mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2 ARM: fix shl for ints with bits < 32
This commit is contained in:
parent
0eebdfcad3
commit
2412ac2c5f
@ -1983,8 +1983,8 @@ fn binOpRegister(
|
||||
if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);
|
||||
|
||||
const mir_tag: Mir.Inst.Tag = switch (tag) {
|
||||
.add, .ptr_add => .add,
|
||||
.sub, .ptr_sub => .sub,
|
||||
.add => .add,
|
||||
.sub => .sub,
|
||||
.cmp_eq => .cmp,
|
||||
.mul => .mul,
|
||||
.bit_and,
|
||||
@ -1993,12 +1993,8 @@ fn binOpRegister(
|
||||
.bit_or,
|
||||
.bool_or,
|
||||
=> .orr,
|
||||
.shl,
|
||||
.shl_exact,
|
||||
=> .lsl,
|
||||
.shr,
|
||||
.shr_exact,
|
||||
=> switch (lhs_ty.intInfo(self.target.*).signedness) {
|
||||
.shl_exact => .lsl,
|
||||
.shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) {
|
||||
.signed => Mir.Inst.Tag.asr,
|
||||
.unsigned => Mir.Inst.Tag.lsr,
|
||||
},
|
||||
@ -2014,16 +2010,12 @@ fn binOpRegister(
|
||||
.bit_or,
|
||||
.bool_or,
|
||||
.xor,
|
||||
.ptr_add,
|
||||
.ptr_sub,
|
||||
=> .{ .rr_op = .{
|
||||
.rd = dest_reg,
|
||||
.rn = lhs_reg,
|
||||
.op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
|
||||
} },
|
||||
.shl,
|
||||
.shl_exact,
|
||||
.shr,
|
||||
.shr_exact,
|
||||
=> .{ .rr_shift = .{
|
||||
.rd = dest_reg,
|
||||
@ -2120,12 +2112,8 @@ fn binOpImmediate(
|
||||
.bit_or,
|
||||
.bool_or,
|
||||
=> .orr,
|
||||
.shl,
|
||||
.shl_exact,
|
||||
=> .lsl,
|
||||
.shr,
|
||||
.shr_exact,
|
||||
=> switch (lhs_ty.intInfo(self.target.*).signedness) {
|
||||
.shl_exact => .lsl,
|
||||
.shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) {
|
||||
.signed => Mir.Inst.Tag.asr,
|
||||
.unsigned => Mir.Inst.Tag.lsr,
|
||||
},
|
||||
@ -2146,9 +2134,7 @@ fn binOpImmediate(
|
||||
.rn = lhs_reg,
|
||||
.op = Instruction.Operand.fromU32(rhs.immediate).?,
|
||||
} },
|
||||
.shl,
|
||||
.shl_exact,
|
||||
.shr,
|
||||
.shr_exact,
|
||||
=> .{ .rr_shift = .{
|
||||
.rd = dest_reg,
|
||||
@ -2279,8 +2265,8 @@ fn binOp(
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.shl,
|
||||
.shr,
|
||||
.shl_exact,
|
||||
.shr_exact,
|
||||
=> {
|
||||
switch (lhs_ty.zigTypeTag()) {
|
||||
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
|
||||
@ -2301,6 +2287,41 @@ 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 ARM binary operations on vectors", .{}),
|
||||
.Int => {
|
||||
const int_info = lhs_ty.intInfo(self.target.*);
|
||||
if (int_info.bits <= 32) {
|
||||
const result_reg = result.register;
|
||||
|
||||
if (int_info.bits < 32) {
|
||||
try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
|
||||
return result;
|
||||
} else return result;
|
||||
} else {
|
||||
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.bool_and,
|
||||
.bool_or,
|
||||
=> {
|
||||
@ -2334,7 +2355,13 @@ fn binOp(
|
||||
const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
|
||||
|
||||
if (elem_size == 1) {
|
||||
return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
|
||||
const base_tag: Air.Inst.Tag = switch (tag) {
|
||||
.ptr_add => .add,
|
||||
.ptr_sub => .sub,
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
return try self.binOpRegister(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
|
||||
} else {
|
||||
// convert the offset into a byte offset by
|
||||
// multiplying it with elem_size
|
||||
|
||||
@ -864,7 +864,6 @@ test "quad hex float literal parsing accurate" {
|
||||
|
||||
test "truncating shift left" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testShlTrunc(maxInt(u16));
|
||||
@ -877,7 +876,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_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testShlExact(0b00110101);
|
||||
@ -890,7 +888,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_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testShrExact(0b10110100);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user