diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 8e046264aa..7ca56946d0 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1390,7 +1390,14 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { return local; }, .signed => { - return f.fail("TODO: C backend: implement trunc for signed integers", .{}); + const operand_ty = f.air.typeOf(ty_op.operand); + const c_bits = toCIntBits(operand_ty.intInfo(target).bits) orelse + return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); + const shift_rhs = c_bits - dest_bits; + try writer.print("(int{d}_t)((uint{d}_t)", .{ c_bits, c_bits }); + try f.writeCValue(writer, operand); + try writer.print(" << {d}) >> {d};\n", .{ shift_rhs, shift_rhs }); + return local; }, } } diff --git a/test/behavior.zig b/test/behavior.zig index 3b84e6f5e6..4b19e81199 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -5,6 +5,7 @@ test { _ = @import("behavior/basic.zig"); _ = @import("behavior/bool.zig"); _ = @import("behavior/if.zig"); + _ = @import("behavior/truncate.zig"); if (builtin.object_format != .c) { // Tests that pass for stage1 and stage2 but not the C backend. @@ -60,7 +61,6 @@ test { _ = @import("behavior/switch.zig"); _ = @import("behavior/this.zig"); _ = @import("behavior/translate_c_macros.zig"); - _ = @import("behavior/truncate.zig"); _ = @import("behavior/underscore.zig"); _ = @import("behavior/union.zig"); _ = @import("behavior/usingnamespace.zig"); diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 72babc8118..93a1e676fe 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -27,8 +27,11 @@ test "truncate to non-power-of-two integers" { try testTrunc(u32, u1, 0b10110, 0b0); try testTrunc(u32, u2, 0b10101, 0b01); try testTrunc(u32, u2, 0b10110, 0b10); - // TODO add test coverage for this! - // try testTrunc(i32, i3, -4, -4); + try testTrunc(i32, i5, -4, -4); + try testTrunc(i32, i5, 4, 4); + try testTrunc(i32, i5, -28, 4); + try testTrunc(i32, i5, 28, -4); + try testTrunc(i32, i5, std.math.maxInt(i32), -1); } fn testTrunc(comptime Big: type, comptime Little: type, big: Big, little: Little) !void {