authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-05 02:06:53-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-05 02:59:02-05:00
log0b0298aff27a31a7f45828d96d95adfdde61a085
tree919b129fe64f54c9aa89a060793ec9c57bb6b643
parentaac47079026d0daf4d5acac08b7d0ad1150002d0

CBE: implement select and shuffle


4 files changed, 75 insertions(+), 10 deletions(-)

src/codegen/c.zig+75-4
......@@ -6584,15 +6584,86 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
65846584}
65856585
65866586fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
6587 if (f.liveness.isUnused(inst)) return .none;
6587 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
6588 const extra = f.air.extraData(Air.Bin, pl_op.payload).data;
6589
6590 if (f.liveness.isUnused(inst)) {
6591 try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs });
6592 return .none;
6593 }
6594
6595 const pred = try f.resolveInst(pl_op.operand);
6596 const lhs = try f.resolveInst(extra.lhs);
6597 const rhs = try f.resolveInst(extra.rhs);
6598 try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs });
6599
6600 const inst_ty = f.air.typeOfIndex(inst);
6601
6602 const writer = f.object.writer();
6603 const local = try f.allocLocal(inst, inst_ty);
6604 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6605 try f.writeCValue(writer, local, .Other);
6606 try v.elem(f, writer);
6607 try writer.writeAll(" = ");
6608 try f.writeCValue(writer, pred, .Other);
6609 try v.elem(f, writer);
6610 try writer.writeAll(" ? ");
6611 try f.writeCValue(writer, lhs, .Other);
6612 try v.elem(f, writer);
6613 try writer.writeAll(" : ");
6614 try f.writeCValue(writer, rhs, .Other);
6615 try v.elem(f, writer);
6616 try writer.writeAll(";\n");
6617 try v.end(f, inst, writer);
65886618
6589 return f.fail("TODO: C backend: implement airSelect", .{});
6619 return local;
65906620}
65916621
65926622fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6593 if (f.liveness.isUnused(inst)) return .none;
6623 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6624 const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data;
6625
6626 if (f.liveness.isUnused(inst)) {
6627 try reap(f, inst, &.{ extra.a, extra.b });
6628 return .none;
6629 }
6630
6631 const mask = f.air.values[extra.mask];
6632 const lhs = try f.resolveInst(extra.a);
6633 const rhs = try f.resolveInst(extra.b);
65946634
6595 return f.fail("TODO: C backend: implement airShuffle", .{});
6635 const module = f.object.dg.module;
6636 const target = module.getTarget();
6637 const inst_ty = f.air.typeOfIndex(inst);
6638
6639 const writer = f.object.writer();
6640 const local = try f.allocLocal(inst, inst_ty);
6641 try reap(f, inst, &.{ extra.a, extra.b }); // local cannot alias operands
6642 for (0..extra.mask_len) |index| {
6643 var dst_pl = Value.Payload.U64{
6644 .base = .{ .tag = .int_u64 },
6645 .data = @intCast(u64, index),
6646 };
6647
6648 try f.writeCValue(writer, local, .Other);
6649 try writer.writeByte('[');
6650 try f.object.dg.renderValue(writer, Type.usize, Value.initPayload(&dst_pl.base), .Other);
6651 try writer.writeAll("] = ");
6652
6653 var buf: Value.ElemValueBuffer = undefined;
6654 const mask_elem = mask.elemValueBuffer(module, index, &buf).toSignedInt(target);
6655 var src_pl = Value.Payload.U64{
6656 .base = .{ .tag = .int_u64 },
6657 .data = @intCast(u64, mask_elem ^ mask_elem >> 63),
6658 };
6659
6660 try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other);
6661 try writer.writeByte('[');
6662 try f.object.dg.renderValue(writer, Type.usize, Value.initPayload(&src_pl.base), .Other);
6663 try writer.writeAll("];\n");
6664 }
6665
6666 return local;
65966667}
65976668
65986669fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
test/behavior/select.zig-2
......@@ -4,7 +4,6 @@ const mem = std.mem;
44const expect = std.testing.expect;
55
66test "@select vectors" {
7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
87 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
......@@ -33,7 +32,6 @@ fn selectVectors() !void {
3332}
3433
3534test "@select arrays" {
36 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
3735 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
3836 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
3937 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/shuffle.zig-2
......@@ -8,7 +8,6 @@ test "@shuffle int" {
88 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1211 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1312
1413 const S = struct {
......@@ -50,7 +49,6 @@ test "@shuffle bool 1" {
5049 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
5150 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5251 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
53 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
5452 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5553
5654 const S = struct {
test/behavior/vector.zig-2
......@@ -804,7 +804,6 @@ test "vector @reduce comptime" {
804804
805805test "mask parameter of @shuffle is comptime scope" {
806806 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
807 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
808807 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
809808 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
810809 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
......@@ -1212,7 +1211,6 @@ test "modRem with zero divisor" {
12121211
12131212test "array operands to shuffle are coerced to vectors" {
12141213 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1215 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
12161214 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12171215 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12181216 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO