| ... | @@ -1983,8 +1983,8 @@ fn binOpRegister( | ... | @@ -1983,8 +1983,8 @@ fn binOpRegister( |
| 1983 | if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs); | 1983 | if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs); |
| 1984 | | 1984 | |
| 1985 | const mir_tag: Mir.Inst.Tag = switch (tag) { | 1985 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 1986 | .add, .ptr_add => .add, | 1986 | .add => .add, |
| 1987 | .sub, .ptr_sub => .sub, | 1987 | .sub => .sub, |
| 1988 | .cmp_eq => .cmp, | 1988 | .cmp_eq => .cmp, |
| 1989 | .mul => .mul, | 1989 | .mul => .mul, |
| 1990 | .bit_and, | 1990 | .bit_and, |
| ... | @@ -1993,12 +1993,8 @@ fn binOpRegister( | ... | @@ -1993,12 +1993,8 @@ fn binOpRegister( |
| 1993 | .bit_or, | 1993 | .bit_or, |
| 1994 | .bool_or, | 1994 | .bool_or, |
| 1995 | => .orr, | 1995 | => .orr, |
| 1996 | .shl, | 1996 | .shl_exact => .lsl, |
| 1997 | .shl_exact, | 1997 | .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) { |
| 1998 | => .lsl, | | |
| 1999 | .shr, | | |
| 2000 | .shr_exact, | | |
| 2001 | => switch (lhs_ty.intInfo(self.target.*).signedness) { | | |
| 2002 | .signed => Mir.Inst.Tag.asr, | 1998 | .signed => Mir.Inst.Tag.asr, |
| 2003 | .unsigned => Mir.Inst.Tag.lsr, | 1999 | .unsigned => Mir.Inst.Tag.lsr, |
| 2004 | }, | 2000 | }, |
| ... | @@ -2014,16 +2010,12 @@ fn binOpRegister( | ... | @@ -2014,16 +2010,12 @@ fn binOpRegister( |
| 2014 | .bit_or, | 2010 | .bit_or, |
| 2015 | .bool_or, | 2011 | .bool_or, |
| 2016 | .xor, | 2012 | .xor, |
| 2017 | .ptr_add, | | |
| 2018 | .ptr_sub, | | |
| 2019 | => .{ .rr_op = .{ | 2013 | => .{ .rr_op = .{ |
| 2020 | .rd = dest_reg, | 2014 | .rd = dest_reg, |
| 2021 | .rn = lhs_reg, | 2015 | .rn = lhs_reg, |
| 2022 | .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none), | 2016 | .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none), |
| 2023 | } }, | 2017 | } }, |
| 2024 | .shl, | | |
| 2025 | .shl_exact, | 2018 | .shl_exact, |
| 2026 | .shr, | | |
| 2027 | .shr_exact, | 2019 | .shr_exact, |
| 2028 | => .{ .rr_shift = .{ | 2020 | => .{ .rr_shift = .{ |
| 2029 | .rd = dest_reg, | 2021 | .rd = dest_reg, |
| ... | @@ -2120,12 +2112,8 @@ fn binOpImmediate( | ... | @@ -2120,12 +2112,8 @@ fn binOpImmediate( |
| 2120 | .bit_or, | 2112 | .bit_or, |
| 2121 | .bool_or, | 2113 | .bool_or, |
| 2122 | => .orr, | 2114 | => .orr, |
| 2123 | .shl, | 2115 | .shl_exact => .lsl, |
| 2124 | .shl_exact, | 2116 | .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) { |
| 2125 | => .lsl, | | |
| 2126 | .shr, | | |
| 2127 | .shr_exact, | | |
| 2128 | => switch (lhs_ty.intInfo(self.target.*).signedness) { | | |
| 2129 | .signed => Mir.Inst.Tag.asr, | 2117 | .signed => Mir.Inst.Tag.asr, |
| 2130 | .unsigned => Mir.Inst.Tag.lsr, | 2118 | .unsigned => Mir.Inst.Tag.lsr, |
| 2131 | }, | 2119 | }, |
| ... | @@ -2146,9 +2134,7 @@ fn binOpImmediate( | ... | @@ -2146,9 +2134,7 @@ fn binOpImmediate( |
| 2146 | .rn = lhs_reg, | 2134 | .rn = lhs_reg, |
| 2147 | .op = Instruction.Operand.fromU32(rhs.immediate).?, | 2135 | .op = Instruction.Operand.fromU32(rhs.immediate).?, |
| 2148 | } }, | 2136 | } }, |
| 2149 | .shl, | | |
| 2150 | .shl_exact, | 2137 | .shl_exact, |
| 2151 | .shr, | | |
| 2152 | .shr_exact, | 2138 | .shr_exact, |
| 2153 | => .{ .rr_shift = .{ | 2139 | => .{ .rr_shift = .{ |
| 2154 | .rd = dest_reg, | 2140 | .rd = dest_reg, |
| ... | @@ -2279,8 +2265,8 @@ fn binOp( | ... | @@ -2279,8 +2265,8 @@ fn binOp( |
| 2279 | else => unreachable, | 2265 | else => unreachable, |
| 2280 | } | 2266 | } |
| 2281 | }, | 2267 | }, |
| 2282 | .shl, | 2268 | .shl_exact, |
| 2283 | .shr, | 2269 | .shr_exact, |
| 2284 | => { | 2270 | => { |
| 2285 | switch (lhs_ty.zigTypeTag()) { | 2271 | switch (lhs_ty.zigTypeTag()) { |
| 2286 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 2272 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -2301,6 +2287,41 @@ fn binOp( | ... | @@ -2301,6 +2287,41 @@ fn binOp( |
| 2301 | else => unreachable, | 2287 | else => unreachable, |
| 2302 | } | 2288 | } |
| 2303 | }, | 2289 | }, |
| | 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 | }, |
| 2304 | .bool_and, | 2325 | .bool_and, |
| 2305 | .bool_or, | 2326 | .bool_or, |
| 2306 | => { | 2327 | => { |
| ... | @@ -2334,7 +2355,13 @@ fn binOp( | ... | @@ -2334,7 +2355,13 @@ fn binOp( |
| 2334 | const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*)); | 2355 | const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*)); |
| 2335 | | 2356 | |
| 2336 | if (elem_size == 1) { | 2357 | 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); |
| 2338 | } else { | 2365 | } else { |
| 2339 | // convert the offset into a byte offset by | 2366 | // convert the offset into a byte offset by |
| 2340 | // multiplying it with elem_size | 2367 | // multiplying it with elem_size |