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(
11961196 // register.
11971197 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
12011201 const cond_choose_lhs: Condition = switch (tag) {
12021202 .max => switch (int_info.signedness) {
......@@ -2067,7 +2067,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
20672067/// Asserts that generating an instruction of that form is possible.
20682068fn binOpRegister(
20692069 self: *Self,
2070 tag: Air.Inst.Tag,
2070 mir_tag: Mir.Inst.Tag,
20712071 maybe_inst: ?Air.Inst.Index,
20722072 lhs: MCValue,
20732073 rhs: MCValue,
......@@ -2112,8 +2112,8 @@ fn binOpRegister(
21122112 };
21132113 defer self.register_manager.unfreezeRegs(&.{rhs_reg});
21142114
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
21172117 else => if (maybe_inst) |inst| blk: {
21182118 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
21192119
......@@ -2130,41 +2130,21 @@ fn binOpRegister(
21302130 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
21312131 if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);
21322132
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) {
21532134 .add,
21542135 .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,
21612140 => .{ .rr_op = .{
21622141 .rd = dest_reg,
21632142 .rn = lhs_reg,
21642143 .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
21652144 } },
2166 .shl_exact,
2167 .shr_exact,
2145 .lsl,
2146 .asr,
2147 .lsr,
21682148 => .{ .rr_shift = .{
21692149 .rd = dest_reg,
21702150 .rm = lhs_reg,
......@@ -2200,7 +2180,7 @@ fn binOpRegister(
22002180/// Asserts that generating an instruction of that form is possible.
22012181fn binOpImmediate(
22022182 self: *Self,
2203 tag: Air.Inst.Tag,
2183 mir_tag: Mir.Inst.Tag,
22042184 maybe_inst: ?Air.Inst.Index,
22052185 lhs: MCValue,
22062186 rhs: MCValue,
......@@ -2230,8 +2210,8 @@ fn binOpImmediate(
22302210 };
22312211 defer self.register_manager.unfreezeRegs(&.{lhs_reg});
22322212
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
22352215 else => if (maybe_inst) |inst| blk: {
22362216 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
22372217
......@@ -2250,40 +2230,21 @@ fn binOpImmediate(
22502230
22512231 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
22522232
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) {
22722234 .add,
22732235 .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,
22802240 => .{ .rr_op = .{
22812241 .rd = dest_reg,
22822242 .rn = lhs_reg,
22832243 .op = Instruction.Operand.fromU32(rhs.immediate).?,
22842244 } },
2285 .shl_exact,
2286 .shr_exact,
2245 .lsl,
2246 .asr,
2247 .lsr,
22872248 => .{ .rr_shift = .{
22882249 .rd = dest_reg,
22892250 .rm = lhs_reg,
......@@ -2352,13 +2313,20 @@ fn binOp(
23522313 else => unreachable,
23532314 };
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
23552323 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);
23572325 } else if (lhs_immediate_ok) {
23582326 // 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);
23602328 } 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);
23622330 }
23632331 } else {
23642332 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
......@@ -2378,7 +2346,7 @@ fn binOp(
23782346 // TODO add optimisations for multiplication
23792347 // with immediates, for example a * 2 can be
23802348 // 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);
23822350 } else {
23832351 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
23842352 }
......@@ -2432,13 +2400,20 @@ fn binOp(
24322400 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;
24332401 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
24352410 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);
24372412 } else if (lhs_immediate_ok) {
24382413 // 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);
24402415 } 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);
24422417 }
24432418 } else {
24442419 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
......@@ -2457,10 +2432,19 @@ fn binOp(
24572432 if (int_info.bits <= 32) {
24582433 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
24602444 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);
24622446 } 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);
24642448 }
24652449 } else {
24662450 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
......@@ -2512,13 +2496,19 @@ fn binOp(
25122496 const lhs_immediate_ok = lhs == .immediate;
25132497 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
25152505 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);
25172507 } else if (lhs_immediate_ok) {
25182508 // 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);
25202510 } 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);
25222512 }
25232513 },
25242514 else => unreachable,
......@@ -2537,7 +2527,7 @@ fn binOp(
25372527 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
25382528
25392529 if (elem_size == 1) {
2540 const base_tag: Air.Inst.Tag = switch (tag) {
2530 const base_tag: Mir.Inst.Tag = switch (tag) {
25412531 .ptr_add => .add,
25422532 .ptr_sub => .sub,
25432533 else => unreachable,