Commit fa85a739d9
Changed files (2)
src
arch
aarch64
test
behavior
src/arch/aarch64/CodeGen.zig
@@ -1138,6 +1138,8 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
} },
});
+ try self.truncRegister(dest_reg, dest_reg, int_info.signedness, int_info.bits);
+
break :result MCValue{ .register = dest_reg };
} else {
return self.fail("TODO AArch64 not on integers > u64/i64", .{});
@@ -1516,11 +1518,8 @@ fn binOp(
const int_info = lhs_ty.intInfo(self.target.*);
if (int_info.bits <= 64) {
const result_reg = result.register;
-
- if (int_info.bits < 64) {
- try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
- return result;
- } else return result;
+ try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
+ return result;
} else {
return self.fail("TODO binary operations on integers > u64/i64", .{});
}
@@ -1554,8 +1553,8 @@ fn binOp(
else => unreachable,
}
},
- .shl,
- .shr,
+ .shl_exact,
+ .shr_exact,
=> {
switch (lhs_ty.zigTypeTag()) {
.Vector => return self.fail("TODO binary operations on vectors", .{}),
@@ -1565,16 +1564,16 @@ fn binOp(
const rhs_immediate_ok = rhs == .immediate;
const mir_tag_register: Mir.Inst.Tag = switch (tag) {
- .shl => .lsl_register,
- .shr => switch (lhs_ty.intInfo(self.target.*).signedness) {
+ .shl_exact => .lsl_register,
+ .shr_exact => switch (int_info.signedness) {
.signed => Mir.Inst.Tag.asr_register,
.unsigned => Mir.Inst.Tag.lsr_register,
},
else => unreachable,
};
const mir_tag_immediate: Mir.Inst.Tag = switch (tag) {
- .shl => .lsl_immediate,
- .shr => switch (lhs_ty.intInfo(self.target.*).signedness) {
+ .shl_exact => .lsl_immediate,
+ .shr_exact => switch (int_info.signedness) {
.signed => Mir.Inst.Tag.asr_immediate,
.unsigned => Mir.Inst.Tag.lsr_immediate,
},
@@ -1593,6 +1592,38 @@ fn binOp(
else => unreachable,
}
},
+ .shl,
+ .shr,
+ => {
+ const base_tag: Air.Inst.Tag = switch (tag) {
+ .shl => .shl_exact,
+ .shr => .shr_exact,
+ else => unreachable,
+ };
+
+ // Generate a shl_exact/shr_exact
+ const result = try self.binOp(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
+
+ // Truncate if necessary
+ switch (tag) {
+ .shr => return result,
+ .shl => switch (lhs_ty.zigTypeTag()) {
+ .Vector => return self.fail("TODO binary operations on vectors", .{}),
+ .Int => {
+ const int_info = lhs_ty.intInfo(self.target.*);
+ if (int_info.bits <= 64) {
+ const result_reg = result.register;
+ try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
+ return result;
+ } else {
+ return self.fail("TODO binary operations on integers > u64/i64", .{});
+ }
+ },
+ else => unreachable,
+ },
+ else => unreachable,
+ }
+ },
.bool_and,
.bool_or,
=> {
test/behavior/math.zig
@@ -363,7 +363,6 @@ fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int
test "binary not" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
try expect(comptime x: {
break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
@@ -851,8 +850,6 @@ test "quad hex float literal parsing accurate" {
}
test "truncating shift left" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
-
try testShlTrunc(maxInt(u16));
comptime try testShlTrunc(maxInt(u16));
}
@@ -863,7 +860,6 @@ fn testShlTrunc(x: u16) !void {
test "exact shift left" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
try testShlExact(0b00110101);
comptime try testShlExact(0b00110101);
@@ -875,7 +871,6 @@ fn testShlExact(x: u8) !void {
test "exact shift right" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
try testShrExact(0b10110100);
comptime try testShrExact(0b10110100);
@@ -887,7 +882,6 @@ fn testShrExact(x: u8) !void {
test "shift left/right on u0 operand" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
const S = struct {
fn doTheTest() !void {