authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-04-18 13:50:54+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-04-19 22:40:51+02:00
logfa85a739d9a85084fbb6d934c2c8803042fa7d48
tree7db631a9fb4d353eae4f6394629611f33c8573de
parentcbb13c023eb24d08b7f46119fad5e2aa1c7a63bb
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: fix shl, shr, shl_exact, shr_exact

Introduces the necessary truncation after shift

2 files changed, 42 insertions(+), 17 deletions(-)

src/arch/aarch64/CodeGen.zig+42-11
......@@ -1138,6 +1138,8 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
11381138 } },
11391139 });
11401140
1141 try self.truncRegister(dest_reg, dest_reg, int_info.signedness, int_info.bits);
1142
11411143 break :result MCValue{ .register = dest_reg };
11421144 } else {
11431145 return self.fail("TODO AArch64 not on integers > u64/i64", .{});
......@@ -1516,11 +1518,8 @@ fn binOp(
15161518 const int_info = lhs_ty.intInfo(self.target.*);
15171519 if (int_info.bits <= 64) {
15181520 const result_reg = result.register;
1519
1520 if (int_info.bits < 64) {
1521 try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
1522 return result;
1523 } else return result;
1521 try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
1522 return result;
15241523 } else {
15251524 return self.fail("TODO binary operations on integers > u64/i64", .{});
15261525 }
......@@ -1554,8 +1553,8 @@ fn binOp(
15541553 else => unreachable,
15551554 }
15561555 },
1557 .shl,
1558 .shr,
1556 .shl_exact,
1557 .shr_exact,
15591558 => {
15601559 switch (lhs_ty.zigTypeTag()) {
15611560 .Vector => return self.fail("TODO binary operations on vectors", .{}),
......@@ -1565,16 +1564,16 @@ fn binOp(
15651564 const rhs_immediate_ok = rhs == .immediate;
15661565
15671566 const mir_tag_register: Mir.Inst.Tag = switch (tag) {
1568 .shl => .lsl_register,
1569 .shr => switch (lhs_ty.intInfo(self.target.*).signedness) {
1567 .shl_exact => .lsl_register,
1568 .shr_exact => switch (int_info.signedness) {
15701569 .signed => Mir.Inst.Tag.asr_register,
15711570 .unsigned => Mir.Inst.Tag.lsr_register,
15721571 },
15731572 else => unreachable,
15741573 };
15751574 const mir_tag_immediate: Mir.Inst.Tag = switch (tag) {
1576 .shl => .lsl_immediate,
1577 .shr => switch (lhs_ty.intInfo(self.target.*).signedness) {
1575 .shl_exact => .lsl_immediate,
1576 .shr_exact => switch (int_info.signedness) {
15781577 .signed => Mir.Inst.Tag.asr_immediate,
15791578 .unsigned => Mir.Inst.Tag.lsr_immediate,
15801579 },
......@@ -1593,6 +1592,38 @@ fn binOp(
15931592 else => unreachable,
15941593 }
15951594 },
1595 .shl,
1596 .shr,
1597 => {
1598 const base_tag: Air.Inst.Tag = switch (tag) {
1599 .shl => .shl_exact,
1600 .shr => .shr_exact,
1601 else => unreachable,
1602 };
1603
1604 // Generate a shl_exact/shr_exact
1605 const result = try self.binOp(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1606
1607 // Truncate if necessary
1608 switch (tag) {
1609 .shr => return result,
1610 .shl => switch (lhs_ty.zigTypeTag()) {
1611 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1612 .Int => {
1613 const int_info = lhs_ty.intInfo(self.target.*);
1614 if (int_info.bits <= 64) {
1615 const result_reg = result.register;
1616 try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
1617 return result;
1618 } else {
1619 return self.fail("TODO binary operations on integers > u64/i64", .{});
1620 }
1621 },
1622 else => unreachable,
1623 },
1624 else => unreachable,
1625 }
1626 },
15961627 .bool_and,
15971628 .bool_or,
15981629 => {
test/behavior/math.zig-6
......@@ -363,7 +363,6 @@ fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int
363363test "binary not" {
364364 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
365365 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
366 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
367366
368367 try expect(comptime x: {
369368 break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
......@@ -851,8 +850,6 @@ test "quad hex float literal parsing accurate" {
851850}
852851
853852test "truncating shift left" {
854 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
855
856853 try testShlTrunc(maxInt(u16));
857854 comptime try testShlTrunc(maxInt(u16));
858855}
......@@ -863,7 +860,6 @@ fn testShlTrunc(x: u16) !void {
863860
864861test "exact shift left" {
865862 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
866 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
867863
868864 try testShlExact(0b00110101);
869865 comptime try testShlExact(0b00110101);
......@@ -875,7 +871,6 @@ fn testShlExact(x: u8) !void {
875871
876872test "exact shift right" {
877873 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
878 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
879874
880875 try testShrExact(0b10110100);
881876 comptime try testShrExact(0b10110100);
......@@ -887,7 +882,6 @@ fn testShrExact(x: u8) !void {
887882
888883test "shift left/right on u0 operand" {
889884 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
890 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
891885
892886 const S = struct {
893887 fn doTheTest() !void {