authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-27 15:06:37+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-04-01 22:02:51+02:00
loge2e69803dc16efe11a6d42c6c49853e16a41fd0c
tree2c6524123ab0017b556fce6488a00cf0facf036c
parent8b5d5f44e23c86082fba480f01092f2f7ffb3dfe
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: change binOp lowering mechanism to use Mir tags

The Air -> Mir correspondence is not 1:1, so this better represents what Mir insruction we actually want to generate.

1 files changed, 65 insertions(+), 75 deletions(-)

src/arch/arm/CodeGen.zig+65-75
...@@ -1196,7 +1196,7 @@ fn minMax(...@@ -1196,7 +1196,7 @@ fn minMax(
1196 // register.1196 // register.
1197 assert(lhs_reg != rhs_reg); // see note above1197 assert(lhs_reg != rhs_reg); // see note above
11981198
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);
12001200
1201 const cond_choose_lhs: Condition = switch (tag) {1201 const cond_choose_lhs: Condition = switch (tag) {
1202 .max => switch (int_info.signedness) {1202 .max => switch (int_info.signedness) {
...@@ -2067,7 +2067,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2067,7 +2067,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
2067/// Asserts that generating an instruction of that form is possible.2067/// Asserts that generating an instruction of that form is possible.
2068fn binOpRegister(2068fn binOpRegister(
2069 self: *Self,2069 self: *Self,
2070 tag: Air.Inst.Tag,2070 mir_tag: Mir.Inst.Tag,
2071 maybe_inst: ?Air.Inst.Index,2071 maybe_inst: ?Air.Inst.Index,
2072 lhs: MCValue,2072 lhs: MCValue,
2073 rhs: MCValue,2073 rhs: MCValue,
...@@ -2112,8 +2112,8 @@ fn binOpRegister(...@@ -2112,8 +2112,8 @@ fn binOpRegister(
2112 };2112 };
2113 defer self.register_manager.unfreezeRegs(&.{rhs_reg});2113 defer self.register_manager.unfreezeRegs(&.{rhs_reg});
21142114
2115 const dest_reg = switch (tag) {2115 const dest_reg = switch (mir_tag) {
2116 .cmp_eq => .r0, // cmp has no destination regardless2116 .cmp => .r0, // cmp has no destination regardless
2117 else => if (maybe_inst) |inst| blk: {2117 else => if (maybe_inst) |inst| blk: {
2118 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2118 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
21192119
...@@ -2130,41 +2130,21 @@ fn binOpRegister(...@@ -2130,41 +2130,21 @@ fn binOpRegister(
2130 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);2130 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
2131 if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);2131 if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);
21322132
2133 const mir_tag: Mir.Inst.Tag = switch (tag) {2133 const mir_data: Mir.Inst.Data = switch (mir_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) {
2153 .add,2134 .add,
2154 .sub,2135 .sub,
2155 .cmp_eq,2136 .cmp,
2156 .bit_and,2137 .@"and",
2157 .bool_and,2138 .orr,
2158 .bit_or,2139 .eor,
2159 .bool_or,
2160 .xor,
2161 => .{ .rr_op = .{2140 => .{ .rr_op = .{
2162 .rd = dest_reg,2141 .rd = dest_reg,
2163 .rn = lhs_reg,2142 .rn = lhs_reg,
2164 .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),2143 .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
2165 } },2144 } },
2166 .shl_exact,2145 .lsl,
2167 .shr_exact,2146 .asr,
2147 .lsr,
2168 => .{ .rr_shift = .{2148 => .{ .rr_shift = .{
2169 .rd = dest_reg,2149 .rd = dest_reg,
2170 .rm = lhs_reg,2150 .rm = lhs_reg,
...@@ -2200,7 +2180,7 @@ fn binOpRegister(...@@ -2200,7 +2180,7 @@ fn binOpRegister(
2200/// Asserts that generating an instruction of that form is possible.2180/// Asserts that generating an instruction of that form is possible.
2201fn binOpImmediate(2181fn binOpImmediate(
2202 self: *Self,2182 self: *Self,
2203 tag: Air.Inst.Tag,2183 mir_tag: Mir.Inst.Tag,
2204 maybe_inst: ?Air.Inst.Index,2184 maybe_inst: ?Air.Inst.Index,
2205 lhs: MCValue,2185 lhs: MCValue,
2206 rhs: MCValue,2186 rhs: MCValue,
...@@ -2230,8 +2210,8 @@ fn binOpImmediate(...@@ -2230,8 +2210,8 @@ fn binOpImmediate(
2230 };2210 };
2231 defer self.register_manager.unfreezeRegs(&.{lhs_reg});2211 defer self.register_manager.unfreezeRegs(&.{lhs_reg});
22322212
2233 const dest_reg = switch (tag) {2213 const dest_reg = switch (mir_tag) {
2234 .cmp_eq => .r0, // cmp has no destination reg2214 .cmp => .r0, // cmp has no destination reg
2235 else => if (maybe_inst) |inst| blk: {2215 else => if (maybe_inst) |inst| blk: {
2236 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2216 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
22372217
...@@ -2250,40 +2230,21 @@ fn binOpImmediate(...@@ -2250,40 +2230,21 @@ fn binOpImmediate(
22502230
2251 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);2231 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
22522232
2253 const mir_tag: Mir.Inst.Tag = switch (tag) {2233 const mir_data: Mir.Inst.Data = switch (mir_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) {
2272 .add,2234 .add,
2273 .sub,2235 .sub,
2274 .cmp_eq,2236 .cmp,
2275 .bit_and,2237 .@"and",
2276 .bool_and,2238 .orr,
2277 .bit_or,2239 .eor,
2278 .bool_or,
2279 .xor,
2280 => .{ .rr_op = .{2240 => .{ .rr_op = .{
2281 .rd = dest_reg,2241 .rd = dest_reg,
2282 .rn = lhs_reg,2242 .rn = lhs_reg,
2283 .op = Instruction.Operand.fromU32(rhs.immediate).?,2243 .op = Instruction.Operand.fromU32(rhs.immediate).?,
2284 } },2244 } },
2285 .shl_exact,2245 .lsl,
2286 .shr_exact,2246 .asr,
2247 .lsr,
2287 => .{ .rr_shift = .{2248 => .{ .rr_shift = .{
2288 .rd = dest_reg,2249 .rd = dest_reg,
2289 .rm = lhs_reg,2250 .rm = lhs_reg,
...@@ -2352,13 +2313,20 @@ fn binOp(...@@ -2352,13 +2313,20 @@ fn binOp(
2352 else => unreachable,2313 else => unreachable,
2353 };2314 };
23542315
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 if (rhs_immediate_ok) {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 } else if (lhs_immediate_ok) {2325 } else if (lhs_immediate_ok) {
2358 // swap lhs and rhs2326 // 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 } else {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 } else {2331 } else {
2364 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});2332 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
...@@ -2378,7 +2346,7 @@ fn binOp(...@@ -2378,7 +2346,7 @@ fn binOp(
2378 // TODO add optimisations for multiplication2346 // TODO add optimisations for multiplication
2379 // with immediates, for example a * 2 can be2347 // with immediates, for example a * 2 can be
2380 // lowered to a << 12348 // 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 } else {2350 } else {
2383 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});2351 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
2384 }2352 }
...@@ -2432,13 +2400,20 @@ fn binOp(...@@ -2432,13 +2400,20 @@ fn binOp(
2432 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;2400 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;
2433 const rhs_immediate_ok = rhs == .immediate and Instruction.Operand.fromU32(rhs.immediate) != null;2401 const rhs_immediate_ok = rhs == .immediate and Instruction.Operand.fromU32(rhs.immediate) != null;
24342402
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 if (rhs_immediate_ok) {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 } else if (lhs_immediate_ok) {2412 } else if (lhs_immediate_ok) {
2438 // swap lhs and rhs2413 // 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 } else {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 } else {2418 } else {
2444 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});2419 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
...@@ -2457,10 +2432,19 @@ fn binOp(...@@ -2457,10 +2432,19 @@ fn binOp(
2457 if (int_info.bits <= 32) {2432 if (int_info.bits <= 32) {
2458 const rhs_immediate_ok = rhs == .immediate;2433 const rhs_immediate_ok = rhs == .immediate;
24592434
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 if (rhs_immediate_ok) {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 } else {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 } else {2449 } else {
2466 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});2450 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
...@@ -2512,13 +2496,19 @@ fn binOp(...@@ -2512,13 +2496,19 @@ fn binOp(
2512 const lhs_immediate_ok = lhs == .immediate;2496 const lhs_immediate_ok = lhs == .immediate;
2513 const rhs_immediate_ok = rhs == .immediate;2497 const rhs_immediate_ok = rhs == .immediate;
25142498
2499 const mir_tag: Mir.Inst.Tag = switch (tag) {
2500 .bool_and => .@"and",
2501 .bool_or => .orr,
2502 else => unreachable,
2503 };
2504
2515 if (rhs_immediate_ok) {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 } else if (lhs_immediate_ok) {2507 } else if (lhs_immediate_ok) {
2518 // swap lhs and rhs2508 // 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 } else {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 else => unreachable,2514 else => unreachable,
...@@ -2537,7 +2527,7 @@ fn binOp(...@@ -2537,7 +2527,7 @@ fn binOp(
2537 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));2527 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
25382528
2539 if (elem_size == 1) {2529 if (elem_size == 1) {
2540 const base_tag: Air.Inst.Tag = switch (tag) {2530 const base_tag: Mir.Inst.Tag = switch (tag) {
2541 .ptr_add => .add,2531 .ptr_add => .add,
2542 .ptr_sub => .sub,2532 .ptr_sub => .sub,
2543 else => unreachable,2533 else => unreachable,