authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-05 01:23:21-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-05 02:59:02-05:00
logaac47079026d0daf4d5acac08b7d0ad1150002d0
treef76f96f8e431d958d1416e7a04eb325bd9685380
parentba69ee488baec677d6e206eb0670240b1c2167a6

CBE: implement splat


2 files changed, 28 insertions(+), 6 deletions(-)

src/codegen/c.zig+28-5
...@@ -438,6 +438,10 @@ pub const Function = struct {...@@ -438,6 +438,10 @@ pub const Function = struct {
438 return f.object.dg.renderType(w, t);438 return f.object.dg.renderType(w, t);
439 }439 }
440440
441 fn renderCType(f: *Function, w: anytype, t: CType.Index) !void {
442 return f.object.dg.renderCType(w, t);
443 }
444
441 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorizer, src_ty: Type, location: ValueRenderLocation) !void {445 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorizer, src_ty: Type, location: ValueRenderLocation) !void {
442 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);446 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
443 }447 }
...@@ -1576,9 +1580,12 @@ pub const DeclGen = struct {...@@ -1576,9 +1580,12 @@ pub const DeclGen = struct {
1576 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |1580 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |
1577 ///1581 ///
1578 fn renderType(dg: *DeclGen, w: anytype, t: Type) error{ OutOfMemory, AnalysisFail }!void {1582 fn renderType(dg: *DeclGen, w: anytype, t: Type) error{ OutOfMemory, AnalysisFail }!void {
1583 try dg.renderCType(w, try dg.typeToIndex(t, .complete));
1584 }
1585
1586 fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {
1579 const store = &dg.ctypes.set;1587 const store = &dg.ctypes.set;
1580 const module = dg.module;1588 const module = dg.module;
1581 const idx = try dg.typeToIndex(t, .complete);
1582 _ = try renderTypePrefix(dg.decl_index, store.*, module, w, idx, .suffix, .{});1589 _ = try renderTypePrefix(dg.decl_index, store.*, module, w, idx, .suffix, .{});
1583 try renderTypeSuffix(dg.decl_index, store.*, module, w, idx, .suffix, .{});1590 try renderTypeSuffix(dg.decl_index, store.*, module, w, idx, .suffix, .{});
1584 }1591 }
...@@ -6543,21 +6550,37 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6543,21 +6550,37 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
65436550
6544fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {6551fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
6545 const ty_op = f.air.instructions.items(.data)[inst].ty_op;6552 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
6553
6546 if (f.liveness.isUnused(inst)) {6554 if (f.liveness.isUnused(inst)) {
6547 try reap(f, inst, &.{ty_op.operand});6555 try reap(f, inst, &.{ty_op.operand});
6548 return .none;6556 return .none;
6549 }6557 }
65506558
6551 const inst_ty = f.air.typeOfIndex(inst);
6552 const operand = try f.resolveInst(ty_op.operand);6559 const operand = try f.resolveInst(ty_op.operand);
6553 try reap(f, inst, &.{ty_op.operand});6560 try reap(f, inst, &.{ty_op.operand});
6561
6562 const inst_ty = f.air.typeOfIndex(inst);
6563 const inst_scalar_ty = inst_ty.scalarType();
6564 const inst_scalar_cty = try f.typeToIndex(inst_scalar_ty, .complete);
6565 const need_memcpy = f.indexToCType(inst_scalar_cty).tag() == .array;
6566
6554 const writer = f.object.writer();6567 const writer = f.object.writer();
6555 const local = try f.allocLocal(inst, inst_ty);6568 const local = try f.allocLocal(inst, inst_ty);
6569 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6570 if (need_memcpy) try writer.writeAll("memcpy(&");
6556 try f.writeCValue(writer, local, .Other);6571 try f.writeCValue(writer, local, .Other);
6557 try writer.writeAll(" = ");6572 try v.elem(f, writer);
6573 try writer.writeAll(if (need_memcpy) ", &" else " = ");
6574 try f.writeCValue(writer, operand, .Other);
6575 if (need_memcpy) {
6576 try writer.writeAll(", sizeof(");
6577 try f.renderCType(writer, inst_scalar_cty);
6578 try writer.writeAll("))");
6579 }
6580 try writer.writeAll(";\n");
6581 try v.end(f, inst, writer);
65586582
6559 _ = operand;6583 return local;
6560 return f.fail("TODO: C backend: implement airSplat", .{});
6561}6584}
65626585
6563fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {6586fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
test/behavior/vector.zig-1
...@@ -234,7 +234,6 @@ test "vector casts of sizes not divisible by 8" {...@@ -234,7 +234,6 @@ test "vector casts of sizes not divisible by 8" {
234}234}
235235
236test "vector @splat" {236test "vector @splat" {
237 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
238 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO237 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
239 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO238 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
240 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO239 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO