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