| ... | ... | @@ -1196,7 +1196,7 @@ fn minMax( |
| 1196 | 1196 | // register. |
| 1197 | 1197 | assert(lhs_reg != rhs_reg); // see note above |
| 1198 | 1198 | |
| 1199 | | _ = try self.binOpRegister(.cmp_eq, null, .{ .register = lhs_reg }, .{ .register = rhs_reg }, lhs_ty, rhs_ty); |
| 1199 | _ = try self.binOpRegister(.cmp, null, .{ .register = lhs_reg }, .{ .register = rhs_reg }, lhs_ty, rhs_ty); |
| 1200 | 1200 | |
| 1201 | 1201 | const cond_choose_lhs: Condition = switch (tag) { |
| 1202 | 1202 | .max => switch (int_info.signedness) { |
| ... | ... | @@ -2067,7 +2067,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2067 | 2067 | /// Asserts that generating an instruction of that form is possible. |
| 2068 | 2068 | fn binOpRegister( |
| 2069 | 2069 | self: *Self, |
| 2070 | | tag: Air.Inst.Tag, |
| 2070 | mir_tag: Mir.Inst.Tag, |
| 2071 | 2071 | maybe_inst: ?Air.Inst.Index, |
| 2072 | 2072 | lhs: MCValue, |
| 2073 | 2073 | rhs: MCValue, |
| ... | ... | @@ -2112,8 +2112,8 @@ fn binOpRegister( |
| 2112 | 2112 | }; |
| 2113 | 2113 | defer self.register_manager.unfreezeRegs(&.{rhs_reg}); |
| 2114 | 2114 | |
| 2115 | | const dest_reg = switch (tag) { |
| 2116 | | .cmp_eq => .r0, // cmp has no destination regardless |
| 2115 | const dest_reg = switch (mir_tag) { |
| 2116 | .cmp => .r0, // cmp has no destination regardless |
| 2117 | 2117 | else => if (maybe_inst) |inst| blk: { |
| 2118 | 2118 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2119 | 2119 | |
| ... | ... | @@ -2130,41 +2130,21 @@ fn binOpRegister( |
| 2130 | 2130 | if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs); |
| 2131 | 2131 | if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs); |
| 2132 | 2132 | |
| 2133 | | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 2134 | | .add => .add, |
| 2135 | | .sub => .sub, |
| 2136 | | .cmp_eq => .cmp, |
| 2137 | | .mul => .mul, |
| 2138 | | .bit_and, |
| 2139 | | .bool_and, |
| 2140 | | => .@"and", |
| 2141 | | .bit_or, |
| 2142 | | .bool_or, |
| 2143 | | => .orr, |
| 2144 | | .shl_exact => .lsl, |
| 2145 | | .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) { |
| 2146 | | .signed => Mir.Inst.Tag.asr, |
| 2147 | | .unsigned => Mir.Inst.Tag.lsr, |
| 2148 | | }, |
| 2149 | | .xor => .eor, |
| 2150 | | else => unreachable, |
| 2151 | | }; |
| 2152 | | const mir_data: Mir.Inst.Data = switch (tag) { |
| 2133 | const mir_data: Mir.Inst.Data = switch (mir_tag) { |
| 2153 | 2134 | .add, |
| 2154 | 2135 | .sub, |
| 2155 | | .cmp_eq, |
| 2156 | | .bit_and, |
| 2157 | | .bool_and, |
| 2158 | | .bit_or, |
| 2159 | | .bool_or, |
| 2160 | | .xor, |
| 2136 | .cmp, |
| 2137 | .@"and", |
| 2138 | .orr, |
| 2139 | .eor, |
| 2161 | 2140 | => .{ .rr_op = .{ |
| 2162 | 2141 | .rd = dest_reg, |
| 2163 | 2142 | .rn = lhs_reg, |
| 2164 | 2143 | .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none), |
| 2165 | 2144 | } }, |
| 2166 | | .shl_exact, |
| 2167 | | .shr_exact, |
| 2145 | .lsl, |
| 2146 | .asr, |
| 2147 | .lsr, |
| 2168 | 2148 | => .{ .rr_shift = .{ |
| 2169 | 2149 | .rd = dest_reg, |
| 2170 | 2150 | .rm = lhs_reg, |
| ... | ... | @@ -2200,7 +2180,7 @@ fn binOpRegister( |
| 2200 | 2180 | /// Asserts that generating an instruction of that form is possible. |
| 2201 | 2181 | fn binOpImmediate( |
| 2202 | 2182 | self: *Self, |
| 2203 | | tag: Air.Inst.Tag, |
| 2183 | mir_tag: Mir.Inst.Tag, |
| 2204 | 2184 | maybe_inst: ?Air.Inst.Index, |
| 2205 | 2185 | lhs: MCValue, |
| 2206 | 2186 | rhs: MCValue, |
| ... | ... | @@ -2230,8 +2210,8 @@ fn binOpImmediate( |
| 2230 | 2210 | }; |
| 2231 | 2211 | defer self.register_manager.unfreezeRegs(&.{lhs_reg}); |
| 2232 | 2212 | |
| 2233 | | const dest_reg = switch (tag) { |
| 2234 | | .cmp_eq => .r0, // cmp has no destination reg |
| 2213 | const dest_reg = switch (mir_tag) { |
| 2214 | .cmp => .r0, // cmp has no destination reg |
| 2235 | 2215 | else => if (maybe_inst) |inst| blk: { |
| 2236 | 2216 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2237 | 2217 | |
| ... | ... | @@ -2250,40 +2230,21 @@ fn binOpImmediate( |
| 2250 | 2230 | |
| 2251 | 2231 | if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs); |
| 2252 | 2232 | |
| 2253 | | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 2254 | | .add => .add, |
| 2255 | | .sub => .sub, |
| 2256 | | .cmp_eq => .cmp, |
| 2257 | | .bit_and, |
| 2258 | | .bool_and, |
| 2259 | | => .@"and", |
| 2260 | | .bit_or, |
| 2261 | | .bool_or, |
| 2262 | | => .orr, |
| 2263 | | .shl_exact => .lsl, |
| 2264 | | .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) { |
| 2265 | | .signed => Mir.Inst.Tag.asr, |
| 2266 | | .unsigned => Mir.Inst.Tag.lsr, |
| 2267 | | }, |
| 2268 | | .xor => .eor, |
| 2269 | | else => unreachable, |
| 2270 | | }; |
| 2271 | | const mir_data: Mir.Inst.Data = switch (tag) { |
| 2233 | const mir_data: Mir.Inst.Data = switch (mir_tag) { |
| 2272 | 2234 | .add, |
| 2273 | 2235 | .sub, |
| 2274 | | .cmp_eq, |
| 2275 | | .bit_and, |
| 2276 | | .bool_and, |
| 2277 | | .bit_or, |
| 2278 | | .bool_or, |
| 2279 | | .xor, |
| 2236 | .cmp, |
| 2237 | .@"and", |
| 2238 | .orr, |
| 2239 | .eor, |
| 2280 | 2240 | => .{ .rr_op = .{ |
| 2281 | 2241 | .rd = dest_reg, |
| 2282 | 2242 | .rn = lhs_reg, |
| 2283 | 2243 | .op = Instruction.Operand.fromU32(rhs.immediate).?, |
| 2284 | 2244 | } }, |
| 2285 | | .shl_exact, |
| 2286 | | .shr_exact, |
| 2245 | .lsl, |
| 2246 | .asr, |
| 2247 | .lsr, |
| 2287 | 2248 | => .{ .rr_shift = .{ |
| 2288 | 2249 | .rd = dest_reg, |
| 2289 | 2250 | .rm = lhs_reg, |
| ... | ... | @@ -2352,13 +2313,20 @@ fn binOp( |
| 2352 | 2313 | else => unreachable, |
| 2353 | 2314 | }; |
| 2354 | 2315 | |
| 2316 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 2317 | .add => .add, |
| 2318 | .sub => .sub, |
| 2319 | .cmp_eq => .cmp, |
| 2320 | else => unreachable, |
| 2321 | }; |
| 2322 | |
| 2355 | 2323 | if (rhs_immediate_ok) { |
| 2356 | | return try self.binOpImmediate(tag, maybe_inst, lhs, rhs, lhs_ty, false); |
| 2324 | return try self.binOpImmediate(mir_tag, maybe_inst, lhs, rhs, lhs_ty, false); |
| 2357 | 2325 | } else if (lhs_immediate_ok) { |
| 2358 | 2326 | // swap lhs and rhs |
| 2359 | | return try self.binOpImmediate(tag, maybe_inst, rhs, lhs, rhs_ty, true); |
| 2327 | return try self.binOpImmediate(mir_tag, maybe_inst, rhs, lhs, rhs_ty, true); |
| 2360 | 2328 | } else { |
| 2361 | | return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2329 | return try self.binOpRegister(mir_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2362 | 2330 | } |
| 2363 | 2331 | } else { |
| 2364 | 2332 | return self.fail("TODO ARM binary operations on integers > u32/i32", .{}); |
| ... | ... | @@ -2378,7 +2346,7 @@ fn binOp( |
| 2378 | 2346 | // TODO add optimisations for multiplication |
| 2379 | 2347 | // with immediates, for example a * 2 can be |
| 2380 | 2348 | // lowered to a << 1 |
| 2381 | | return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2349 | return try self.binOpRegister(.mul, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2382 | 2350 | } else { |
| 2383 | 2351 | return self.fail("TODO ARM binary operations on integers > u32/i32", .{}); |
| 2384 | 2352 | } |
| ... | ... | @@ -2432,13 +2400,20 @@ fn binOp( |
| 2432 | 2400 | const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null; |
| 2433 | 2401 | const rhs_immediate_ok = rhs == .immediate and Instruction.Operand.fromU32(rhs.immediate) != null; |
| 2434 | 2402 | |
| 2403 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 2404 | .bit_and => .@"and", |
| 2405 | .bit_or => .orr, |
| 2406 | .xor => .eor, |
| 2407 | else => unreachable, |
| 2408 | }; |
| 2409 | |
| 2435 | 2410 | if (rhs_immediate_ok) { |
| 2436 | | return try self.binOpImmediate(tag, maybe_inst, lhs, rhs, lhs_ty, false); |
| 2411 | return try self.binOpImmediate(mir_tag, maybe_inst, lhs, rhs, lhs_ty, false); |
| 2437 | 2412 | } else if (lhs_immediate_ok) { |
| 2438 | 2413 | // swap lhs and rhs |
| 2439 | | return try self.binOpImmediate(tag, maybe_inst, rhs, lhs, rhs_ty, true); |
| 2414 | return try self.binOpImmediate(mir_tag, maybe_inst, rhs, lhs, rhs_ty, true); |
| 2440 | 2415 | } else { |
| 2441 | | return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2416 | return try self.binOpRegister(mir_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2442 | 2417 | } |
| 2443 | 2418 | } else { |
| 2444 | 2419 | return self.fail("TODO ARM binary operations on integers > u32/i32", .{}); |
| ... | ... | @@ -2457,10 +2432,19 @@ fn binOp( |
| 2457 | 2432 | if (int_info.bits <= 32) { |
| 2458 | 2433 | const rhs_immediate_ok = rhs == .immediate; |
| 2459 | 2434 | |
| 2435 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 2436 | .shl_exact => .lsl, |
| 2437 | .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) { |
| 2438 | .signed => Mir.Inst.Tag.asr, |
| 2439 | .unsigned => Mir.Inst.Tag.lsr, |
| 2440 | }, |
| 2441 | else => unreachable, |
| 2442 | }; |
| 2443 | |
| 2460 | 2444 | if (rhs_immediate_ok) { |
| 2461 | | return try self.binOpImmediate(tag, maybe_inst, lhs, rhs, lhs_ty, false); |
| 2445 | return try self.binOpImmediate(mir_tag, maybe_inst, lhs, rhs, lhs_ty, false); |
| 2462 | 2446 | } else { |
| 2463 | | return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2447 | return try self.binOpRegister(mir_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2464 | 2448 | } |
| 2465 | 2449 | } else { |
| 2466 | 2450 | return self.fail("TODO ARM binary operations on integers > u32/i32", .{}); |
| ... | ... | @@ -2512,13 +2496,19 @@ fn binOp( |
| 2512 | 2496 | const lhs_immediate_ok = lhs == .immediate; |
| 2513 | 2497 | const rhs_immediate_ok = rhs == .immediate; |
| 2514 | 2498 | |
| 2499 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 2500 | .bool_and => .@"and", |
| 2501 | .bool_or => .orr, |
| 2502 | else => unreachable, |
| 2503 | }; |
| 2504 | |
| 2515 | 2505 | if (rhs_immediate_ok) { |
| 2516 | | return try self.binOpImmediate(tag, maybe_inst, lhs, rhs, lhs_ty, false); |
| 2506 | return try self.binOpImmediate(mir_tag, maybe_inst, lhs, rhs, lhs_ty, false); |
| 2517 | 2507 | } else if (lhs_immediate_ok) { |
| 2518 | 2508 | // swap lhs and rhs |
| 2519 | | return try self.binOpImmediate(tag, maybe_inst, rhs, lhs, rhs_ty, true); |
| 2509 | return try self.binOpImmediate(mir_tag, maybe_inst, rhs, lhs, rhs_ty, true); |
| 2520 | 2510 | } else { |
| 2521 | | return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2511 | return try self.binOpRegister(mir_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 2522 | 2512 | } |
| 2523 | 2513 | }, |
| 2524 | 2514 | else => unreachable, |
| ... | ... | @@ -2537,7 +2527,7 @@ fn binOp( |
| 2537 | 2527 | const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*)); |
| 2538 | 2528 | |
| 2539 | 2529 | if (elem_size == 1) { |
| 2540 | | const base_tag: Air.Inst.Tag = switch (tag) { |
| 2530 | const base_tag: Mir.Inst.Tag = switch (tag) { |
| 2541 | 2531 | .ptr_add => .add, |
| 2542 | 2532 | .ptr_sub => .sub, |
| 2543 | 2533 | else => unreachable, |