authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-05 00:44:27-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-05 02:59:02-05:00
logba69ee488baec677d6e206eb0670240b1c2167a6
treef881050133ef5d6f0f73ec41b837caf698c31f74
parent8f6da78fb1bfc9d5e8b3d5affd33cf6a62f5e8c7

CBE: implement vector truncate


2 files changed, 22 insertions(+), 13 deletions(-)

src/codegen/c.zig+22-12
......@@ -3465,34 +3465,40 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
34653465 const operand = try f.resolveInst(ty_op.operand);
34663466 try reap(f, inst, &.{ty_op.operand});
34673467 const inst_ty = f.air.typeOfIndex(inst);
3468 const writer = f.object.writer();
3469 const local = try f.allocLocal(inst, inst_ty);
3468 const inst_scalar_ty = inst_ty.scalarType();
34703469 const target = f.object.dg.module.getTarget();
3471 const dest_int_info = inst_ty.intInfo(target);
3470 const dest_int_info = inst_scalar_ty.intInfo(target);
34723471 const dest_bits = dest_int_info.bits;
34733472 const dest_c_bits = toCIntBits(dest_int_info.bits) orelse
34743473 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
34753474 const operand_ty = f.air.typeOf(ty_op.operand);
3476 const operand_int_info = operand_ty.intInfo(target);
3475 const scalar_ty = operand_ty.scalarType();
3476 const scalar_int_info = scalar_ty.intInfo(target);
3477
3478 const writer = f.object.writer();
3479 const local = try f.allocLocal(inst, inst_ty);
3480 const v = try Vectorizer.start(f, inst, writer, operand_ty);
34773481
34783482 try f.writeCValue(writer, local, .Other);
3483 try v.elem(f, writer);
34793484 try writer.writeAll(" = ");
34803485
34813486 if (dest_c_bits < 64) {
34823487 try writer.writeByte('(');
3483 try f.renderType(writer, inst_ty);
3488 try f.renderType(writer, inst_scalar_ty);
34843489 try writer.writeByte(')');
34853490 }
34863491
3487 const needs_lo = operand_int_info.bits > 64 and dest_bits <= 64;
3492 const needs_lo = scalar_int_info.bits > 64 and dest_bits <= 64;
34883493 if (needs_lo) {
34893494 try writer.writeAll("zig_lo_");
3490 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
3495 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
34913496 try writer.writeByte('(');
34923497 }
34933498
34943499 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {
34953500 try f.writeCValue(writer, operand, .Other);
3501 try v.elem(f, writer);
34963502 } else switch (dest_int_info.signedness) {
34973503 .unsigned => {
34983504 var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);
......@@ -3502,15 +3508,16 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35023508 var stack align(@alignOf(ExpectedContents)) =
35033509 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
35043510
3505 const mask_val = try inst_ty.maxInt(stack.get(), target);
3511 const mask_val = try inst_scalar_ty.maxInt(stack.get(), target);
35063512 try writer.writeAll("zig_and_");
3507 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
3513 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
35083514 try writer.writeByte('(');
35093515 try f.writeCValue(writer, operand, .FunctionArgument);
3510 try writer.print(", {x})", .{try f.fmtIntLiteral(operand_ty, mask_val)});
3516 try v.elem(f, writer);
3517 try writer.print(", {x})", .{try f.fmtIntLiteral(scalar_ty, mask_val)});
35113518 },
35123519 .signed => {
3513 const c_bits = toCIntBits(operand_int_info.bits) orelse
3520 const c_bits = toCIntBits(scalar_int_info.bits) orelse
35143521 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
35153522 var shift_pl = Value.Payload.U64{
35163523 .base = .{ .tag = .int_u64 },
......@@ -3519,7 +3526,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35193526 const shift_val = Value.initPayload(&shift_pl.base);
35203527
35213528 try writer.writeAll("zig_shr_");
3522 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
3529 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
35233530 if (c_bits == 128) {
35243531 try writer.print("(zig_bitcast_i{d}(", .{c_bits});
35253532 } else {
......@@ -3532,6 +3539,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35323539 try writer.print("(uint{d}_t)", .{c_bits});
35333540 }
35343541 try f.writeCValue(writer, operand, .FunctionArgument);
3542 try v.elem(f, writer);
35353543 if (c_bits == 128) try writer.writeByte(')');
35363544 try writer.print(", {})", .{try f.fmtIntLiteral(Type.u8, shift_val)});
35373545 if (c_bits == 128) try writer.writeByte(')');
......@@ -3541,6 +3549,8 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35413549
35423550 if (needs_lo) try writer.writeByte(')');
35433551 try writer.writeAll(";\n");
3552 try v.end(f, inst, writer);
3553
35443554 return local;
35453555}
35463556
test/behavior/truncate.zig-1
......@@ -60,7 +60,6 @@ test "truncate on comptime integer" {
6060}
6161
6262test "truncate on vectors" {
63 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
6463 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
6564 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
6665 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;