| author | |
| committer | |
| log | 969bcb6a59eadb2ef46a9784286728a25d275c24 |
| tree | 8fff245884c9df30a82024e1ff30baf3bf5444ed |
| parent | 1de6f9a267bf9247b62b385fc793586e60f78376 |
3 files changed, 14 insertions(+), 4 deletions(-)
src/codegen/c.zig+8-1| ... | @@ -1390,7 +1390,14 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -1390,7 +1390,14 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 1390 | return local; | 1390 | return local; |
| 1391 | }, | 1391 | }, |
| 1392 | .signed => { | 1392 | .signed => { |
| 1393 | return f.fail("TODO: C backend: implement trunc for signed integers", .{}); | 1393 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 1394 | const c_bits = toCIntBits(operand_ty.intInfo(target).bits) orelse | ||
| 1395 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | ||
| 1396 | const shift_rhs = c_bits - dest_bits; | ||
| 1397 | try writer.print("(int{d}_t)((uint{d}_t)", .{ c_bits, c_bits }); | ||
| 1398 | try f.writeCValue(writer, operand); | ||
| 1399 | try writer.print(" << {d}) >> {d};\n", .{ shift_rhs, shift_rhs }); | ||
| 1400 | return local; | ||
| 1394 | }, | 1401 | }, |
| 1395 | } | 1402 | } |
| 1396 | } | 1403 | } |
test/behavior.zig+1-1| ... | @@ -5,6 +5,7 @@ test { | ... | @@ -5,6 +5,7 @@ test { |
| 5 | _ = @import("behavior/basic.zig"); | 5 | _ = @import("behavior/basic.zig"); |
| 6 | _ = @import("behavior/bool.zig"); | 6 | _ = @import("behavior/bool.zig"); |
| 7 | _ = @import("behavior/if.zig"); | 7 | _ = @import("behavior/if.zig"); |
| 8 | _ = @import("behavior/truncate.zig"); | ||
| 8 | 9 | ||
| 9 | if (builtin.object_format != .c) { | 10 | if (builtin.object_format != .c) { |
| 10 | // Tests that pass for stage1 and stage2 but not the C backend. | 11 | // Tests that pass for stage1 and stage2 but not the C backend. |
| ... | @@ -60,7 +61,6 @@ test { | ... | @@ -60,7 +61,6 @@ test { |
| 60 | _ = @import("behavior/switch.zig"); | 61 | _ = @import("behavior/switch.zig"); |
| 61 | _ = @import("behavior/this.zig"); | 62 | _ = @import("behavior/this.zig"); |
| 62 | _ = @import("behavior/translate_c_macros.zig"); | 63 | _ = @import("behavior/translate_c_macros.zig"); |
| 63 | _ = @import("behavior/truncate.zig"); | ||
| 64 | _ = @import("behavior/underscore.zig"); | 64 | _ = @import("behavior/underscore.zig"); |
| 65 | _ = @import("behavior/union.zig"); | 65 | _ = @import("behavior/union.zig"); |
| 66 | _ = @import("behavior/usingnamespace.zig"); | 66 | _ = @import("behavior/usingnamespace.zig"); |
test/behavior/basic.zig+5-2| ... | @@ -27,8 +27,11 @@ test "truncate to non-power-of-two integers" { | ... | @@ -27,8 +27,11 @@ test "truncate to non-power-of-two integers" { |
| 27 | try testTrunc(u32, u1, 0b10110, 0b0); | 27 | try testTrunc(u32, u1, 0b10110, 0b0); |
| 28 | try testTrunc(u32, u2, 0b10101, 0b01); | 28 | try testTrunc(u32, u2, 0b10101, 0b01); |
| 29 | try testTrunc(u32, u2, 0b10110, 0b10); | 29 | try testTrunc(u32, u2, 0b10110, 0b10); |
| 30 | // TODO add test coverage for this! | 30 | try testTrunc(i32, i5, -4, -4); |
| 31 | // try testTrunc(i32, i3, -4, -4); | 31 | try testTrunc(i32, i5, 4, 4); |
| 32 | try testTrunc(i32, i5, -28, 4); | ||
| 33 | try testTrunc(i32, i5, 28, -4); | ||
| 34 | try testTrunc(i32, i5, std.math.maxInt(i32), -1); | ||
| 32 | } | 35 | } |
| 33 | 36 | ||
| 34 | fn testTrunc(comptime Big: type, comptime Little: type, big: Big, little: Little) !void { | 37 | fn testTrunc(comptime Big: type, comptime Little: type, big: Big, little: Little) !void { |