authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-13 20:54:29+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-16 20:20:07+01:00
log2412ac2c5ffe9ef02fdcfa2806b5f5862d4e42f3
tree5a55cd33546120089f182904580f38982087b47a
parent0eebdfcad38e1348ca5fb8a26e722803664a3ebb
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: fix shl for ints with bits < 32


2 files changed, 50 insertions(+), 26 deletions(-)

src/arch/arm/CodeGen.zig+50-23
......@@ -1983,8 +1983,8 @@ fn binOpRegister(
19831983 if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);
19841984
19851985 const mir_tag: Mir.Inst.Tag = switch (tag) {
1986 .add, .ptr_add => .add,
1987 .sub, .ptr_sub => .sub,
1986 .add => .add,
1987 .sub => .sub,
19881988 .cmp_eq => .cmp,
19891989 .mul => .mul,
19901990 .bit_and,
......@@ -1993,12 +1993,8 @@ fn binOpRegister(
19931993 .bit_or,
19941994 .bool_or,
19951995 => .orr,
1996 .shl,
1997 .shl_exact,
1998 => .lsl,
1999 .shr,
2000 .shr_exact,
2001 => switch (lhs_ty.intInfo(self.target.*).signedness) {
1996 .shl_exact => .lsl,
1997 .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) {
20021998 .signed => Mir.Inst.Tag.asr,
20031999 .unsigned => Mir.Inst.Tag.lsr,
20042000 },
......@@ -2014,16 +2010,12 @@ fn binOpRegister(
20142010 .bit_or,
20152011 .bool_or,
20162012 .xor,
2017 .ptr_add,
2018 .ptr_sub,
20192013 => .{ .rr_op = .{
20202014 .rd = dest_reg,
20212015 .rn = lhs_reg,
20222016 .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
20232017 } },
2024 .shl,
20252018 .shl_exact,
2026 .shr,
20272019 .shr_exact,
20282020 => .{ .rr_shift = .{
20292021 .rd = dest_reg,
......@@ -2120,12 +2112,8 @@ fn binOpImmediate(
21202112 .bit_or,
21212113 .bool_or,
21222114 => .orr,
2123 .shl,
2124 .shl_exact,
2125 => .lsl,
2126 .shr,
2127 .shr_exact,
2128 => switch (lhs_ty.intInfo(self.target.*).signedness) {
2115 .shl_exact => .lsl,
2116 .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) {
21292117 .signed => Mir.Inst.Tag.asr,
21302118 .unsigned => Mir.Inst.Tag.lsr,
21312119 },
......@@ -2146,9 +2134,7 @@ fn binOpImmediate(
21462134 .rn = lhs_reg,
21472135 .op = Instruction.Operand.fromU32(rhs.immediate).?,
21482136 } },
2149 .shl,
21502137 .shl_exact,
2151 .shr,
21522138 .shr_exact,
21532139 => .{ .rr_shift = .{
21542140 .rd = dest_reg,
......@@ -2279,8 +2265,8 @@ fn binOp(
22792265 else => unreachable,
22802266 }
22812267 },
2282 .shl,
2283 .shr,
2268 .shl_exact,
2269 .shr_exact,
22842270 => {
22852271 switch (lhs_ty.zigTypeTag()) {
22862272 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -2301,6 +2287,41 @@ fn binOp(
23012287 else => unreachable,
23022288 }
23032289 },
2290 .shl,
2291 .shr,
2292 => {
2293 const base_tag: Air.Inst.Tag = switch (tag) {
2294 .shl => .shl_exact,
2295 .shr => .shr_exact,
2296 else => unreachable,
2297 };
2298
2299 // Generate a shl_exact/shr_exact
2300 const result = try self.binOp(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
2301
2302 // Truncate if necessary
2303 switch (tag) {
2304 .shr => return result,
2305 .shl => switch (lhs_ty.zigTypeTag()) {
2306 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2307 .Int => {
2308 const int_info = lhs_ty.intInfo(self.target.*);
2309 if (int_info.bits <= 32) {
2310 const result_reg = result.register;
2311
2312 if (int_info.bits < 32) {
2313 try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
2314 return result;
2315 } else return result;
2316 } else {
2317 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
2318 }
2319 },
2320 else => unreachable,
2321 },
2322 else => unreachable,
2323 }
2324 },
23042325 .bool_and,
23052326 .bool_or,
23062327 => {
......@@ -2334,7 +2355,13 @@ fn binOp(
23342355 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
23352356
23362357 if (elem_size == 1) {
2337 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
2358 const base_tag: Air.Inst.Tag = switch (tag) {
2359 .ptr_add => .add,
2360 .ptr_sub => .sub,
2361 else => unreachable,
2362 };
2363
2364 return try self.binOpRegister(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
23382365 } else {
23392366 // convert the offset into a byte offset by
23402367 // multiplying it with elem_size
test/behavior/math.zig-3
......@@ -864,7 +864,6 @@ test "quad hex float literal parsing accurate" {
864864
865865test "truncating shift left" {
866866 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
867 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
868867 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
869868
870869 try testShlTrunc(maxInt(u16));
......@@ -877,7 +876,6 @@ fn testShlTrunc(x: u16) !void {
877876
878877test "exact shift left" {
879878 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
880 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
881879 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
882880
883881 try testShlExact(0b00110101);
......@@ -890,7 +888,6 @@ fn testShlExact(x: u8) !void {
890888
891889test "exact shift right" {
892890 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
893 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
894891 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
895892
896893 try testShrExact(0b10110100);