mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
stage2 AArch64: fix shl, shr, shl_exact, shr_exact
Introduces the necessary truncation after shift
This commit is contained in:
parent
cbb13c023e
commit
fa85a739d9
@ -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,
|
||||
=> {
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user