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 {...@@ -3465,34 +3465,40 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3465 const operand = try f.resolveInst(ty_op.operand);3465 const operand = try f.resolveInst(ty_op.operand);
3466 try reap(f, inst, &.{ty_op.operand});3466 try reap(f, inst, &.{ty_op.operand});
3467 const inst_ty = f.air.typeOfIndex(inst);3467 const inst_ty = f.air.typeOfIndex(inst);
3468 const writer = f.object.writer();3468 const inst_scalar_ty = inst_ty.scalarType();
3469 const local = try f.allocLocal(inst, inst_ty);
3470 const target = f.object.dg.module.getTarget();3469 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);
3472 const dest_bits = dest_int_info.bits;3471 const dest_bits = dest_int_info.bits;
3473 const dest_c_bits = toCIntBits(dest_int_info.bits) orelse3472 const dest_c_bits = toCIntBits(dest_int_info.bits) orelse
3474 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});3473 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3475 const operand_ty = f.air.typeOf(ty_op.operand);3474 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
3478 try f.writeCValue(writer, local, .Other);3482 try f.writeCValue(writer, local, .Other);
3483 try v.elem(f, writer);
3479 try writer.writeAll(" = ");3484 try writer.writeAll(" = ");
34803485
3481 if (dest_c_bits < 64) {3486 if (dest_c_bits < 64) {
3482 try writer.writeByte('(');3487 try writer.writeByte('(');
3483 try f.renderType(writer, inst_ty);3488 try f.renderType(writer, inst_scalar_ty);
3484 try writer.writeByte(')');3489 try writer.writeByte(')');
3485 }3490 }
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;
3488 if (needs_lo) {3493 if (needs_lo) {
3489 try writer.writeAll("zig_lo_");3494 try writer.writeAll("zig_lo_");
3490 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);3495 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
3491 try writer.writeByte('(');3496 try writer.writeByte('(');
3492 }3497 }
34933498
3494 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {3499 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {
3495 try f.writeCValue(writer, operand, .Other);3500 try f.writeCValue(writer, operand, .Other);
3501 try v.elem(f, writer);
3496 } else switch (dest_int_info.signedness) {3502 } else switch (dest_int_info.signedness) {
3497 .unsigned => {3503 .unsigned => {
3498 var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);3504 var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);
...@@ -3502,15 +3508,16 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3502,15 +3508,16 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3502 var stack align(@alignOf(ExpectedContents)) =3508 var stack align(@alignOf(ExpectedContents)) =
3503 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());3509 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);
3506 try writer.writeAll("zig_and_");3512 try writer.writeAll("zig_and_");
3507 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);3513 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
3508 try writer.writeByte('(');3514 try writer.writeByte('(');
3509 try f.writeCValue(writer, operand, .FunctionArgument);3515 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)});
3511 },3518 },
3512 .signed => {3519 .signed => {
3513 const c_bits = toCIntBits(operand_int_info.bits) orelse3520 const c_bits = toCIntBits(scalar_int_info.bits) orelse
3514 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});3521 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3515 var shift_pl = Value.Payload.U64{3522 var shift_pl = Value.Payload.U64{
3516 .base = .{ .tag = .int_u64 },3523 .base = .{ .tag = .int_u64 },
...@@ -3519,7 +3526,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3519,7 +3526,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3519 const shift_val = Value.initPayload(&shift_pl.base);3526 const shift_val = Value.initPayload(&shift_pl.base);
35203527
3521 try writer.writeAll("zig_shr_");3528 try writer.writeAll("zig_shr_");
3522 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);3529 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
3523 if (c_bits == 128) {3530 if (c_bits == 128) {
3524 try writer.print("(zig_bitcast_i{d}(", .{c_bits});3531 try writer.print("(zig_bitcast_i{d}(", .{c_bits});
3525 } else {3532 } else {
...@@ -3532,6 +3539,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3532,6 +3539,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3532 try writer.print("(uint{d}_t)", .{c_bits});3539 try writer.print("(uint{d}_t)", .{c_bits});
3533 }3540 }
3534 try f.writeCValue(writer, operand, .FunctionArgument);3541 try f.writeCValue(writer, operand, .FunctionArgument);
3542 try v.elem(f, writer);
3535 if (c_bits == 128) try writer.writeByte(')');3543 if (c_bits == 128) try writer.writeByte(')');
3536 try writer.print(", {})", .{try f.fmtIntLiteral(Type.u8, shift_val)});3544 try writer.print(", {})", .{try f.fmtIntLiteral(Type.u8, shift_val)});
3537 if (c_bits == 128) try writer.writeByte(')');3545 if (c_bits == 128) try writer.writeByte(')');
...@@ -3541,6 +3549,8 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3541,6 +3549,8 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35413549
3542 if (needs_lo) try writer.writeByte(')');3550 if (needs_lo) try writer.writeByte(')');
3543 try writer.writeAll(";\n");3551 try writer.writeAll(";\n");
3552 try v.end(f, inst, writer);
3553
3544 return local;3554 return local;
3545}3555}
35463556
test/behavior/truncate.zig-1
...@@ -60,7 +60,6 @@ test "truncate on comptime integer" {...@@ -60,7 +60,6 @@ test "truncate on comptime integer" {
60}60}
6161
62test "truncate on vectors" {62test "truncate on vectors" {
63 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
64 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;63 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
65 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;64 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;65 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;