Commit 28cc363947

joachimschmidt557 <joachim.schmidt557@outlook.com>
2022-08-13 17:42:11
stage2 ARM: improve Mir representation of mov and cmp
1 parent 9e070b6
Changed files (3)
src/arch/arm/CodeGen.zig
@@ -438,9 +438,8 @@ fn gen(self: *Self) !void {
         // mov fp, sp
         _ = try self.addInst(.{
             .tag = .mov,
-            .data = .{ .rr_op = .{
+            .data = .{ .r_op_mov = .{
                 .rd = .fp,
-                .rn = .r0,
                 .op = Instruction.Operand.reg(.sp, Instruction.Operand.Shift.none),
             } },
         });
@@ -531,9 +530,8 @@ fn gen(self: *Self) !void {
         // mov sp, fp
         _ = try self.addInst(.{
             .tag = .mov,
-            .data = .{ .rr_op = .{
+            .data = .{ .r_op_mov = .{
                 .rd = .sp,
-                .rn = .r0,
                 .op = Instruction.Operand.reg(.fp, Instruction.Operand.Shift.none),
             } },
         });
@@ -1240,9 +1238,8 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
 
                             _ = try self.addInst(.{
                                 .tag = .mvn,
-                                .data = .{ .rr_op = .{
+                                .data = .{ .r_op_mov = .{
                                     .rd = dest_reg,
-                                    .rn = undefined,
                                     .op = Instruction.Operand.reg(op_reg, Instruction.Operand.Shift.none),
                                 } },
                             });
@@ -1337,9 +1334,8 @@ fn minMax(
                     _ = try self.addInst(.{
                         .tag = .mov,
                         .cond = cond_choose_lhs,
-                        .data = .{ .rr_op = .{
+                        .data = .{ .r_op_mov = .{
                             .rd = dest_reg,
-                            .rn = .r0,
                             .op = Instruction.Operand.reg(lhs_reg, Instruction.Operand.Shift.none),
                         } },
                     });
@@ -1348,9 +1344,8 @@ fn minMax(
                     _ = try self.addInst(.{
                         .tag = .mov,
                         .cond = cond_choose_rhs,
-                        .data = .{ .rr_op = .{
+                        .data = .{ .r_op_mov = .{
                             .rd = dest_reg,
-                            .rn = .r0,
                             .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
                         } },
                     });
@@ -1682,9 +1677,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
                     // mov rdlo, #0
                     _ = try self.addInst(.{
                         .tag = .mov,
-                        .data = .{ .rr_op = .{
+                        .data = .{ .r_op_mov = .{
                             .rd = rdlo,
-                            .rn = .r0,
                             .op = Instruction.Operand.fromU32(0).?,
                         } },
                     });
@@ -1693,9 +1687,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
                     _ = try self.addInst(.{
                         .tag = .mov,
                         .cond = .ne,
-                        .data = .{ .rr_op = .{
+                        .data = .{ .r_op_mov = .{
                             .rd = rdlo,
-                            .rn = .r0,
                             .op = Instruction.Operand.fromU32(1).?,
                         } },
                     });
@@ -1707,9 +1700,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
                     _ = try self.addInst(.{
                         .tag = .mov,
                         .cond = .ne,
-                        .data = .{ .rr_op = .{
+                        .data = .{ .r_op_mov = .{
                             .rd = rdlo,
-                            .rn = .r0,
                             .op = Instruction.Operand.fromU32(1).?,
                         } },
                     });
@@ -2670,7 +2662,7 @@ fn binOpRegister(
     defer if (new_rhs_lock) |reg| self.register_manager.unlockReg(reg);
 
     const dest_reg = switch (mir_tag) {
-        .cmp => .r0, // cmp has no destination regardless
+        .cmp => undefined, // cmp has no destination regardless
         else => if (metadata) |md| blk: {
             if (lhs_is_register and self.reuseOperand(md.inst, md.lhs, 0, lhs)) {
                 break :blk lhs_reg;
@@ -2690,7 +2682,6 @@ fn binOpRegister(
         .adds,
         .sub,
         .subs,
-        .cmp,
         .@"and",
         .orr,
         .eor,
@@ -2699,6 +2690,10 @@ fn binOpRegister(
             .rn = lhs_reg,
             .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
         } },
+        .cmp => .{ .r_op_cmp = .{
+            .rn = lhs_reg,
+            .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
+        } },
         .lsl,
         .asr,
         .lsr,
@@ -2767,7 +2762,7 @@ fn binOpImmediate(
     defer if (new_lhs_lock) |reg| self.register_manager.unlockReg(reg);
 
     const dest_reg = switch (mir_tag) {
-        .cmp => .r0, // cmp has no destination reg
+        .cmp => undefined, // cmp has no destination reg
         else => if (metadata) |md| blk: {
             if (lhs_is_register and self.reuseOperand(
                 md.inst,
@@ -2789,7 +2784,6 @@ fn binOpImmediate(
         .adds,
         .sub,
         .subs,
-        .cmp,
         .@"and",
         .orr,
         .eor,
@@ -2798,6 +2792,10 @@ fn binOpImmediate(
             .rn = lhs_reg,
             .op = Instruction.Operand.fromU32(rhs.immediate).?,
         } },
+        .cmp => .{ .r_op_cmp = .{
+            .rn = lhs_reg,
+            .op = Instruction.Operand.fromU32(rhs.immediate).?,
+        } },
         .lsl,
         .asr,
         .lsr,
@@ -3312,9 +3310,8 @@ fn genInlineMemcpy(
     // mov count, #0
     _ = try self.addInst(.{
         .tag = .mov,
-        .data = .{ .rr_op = .{
+        .data = .{ .r_op_mov = .{
             .rd = count,
-            .rn = .r0,
             .op = Instruction.Operand.imm(0, 0),
         } },
     });
@@ -3323,8 +3320,7 @@ fn genInlineMemcpy(
     // cmp count, len
     _ = try self.addInst(.{
         .tag = .cmp,
-        .data = .{ .rr_op = .{
-            .rd = .r0,
+        .data = .{ .r_op_cmp = .{
             .rn = count,
             .op = Instruction.Operand.reg(len, Instruction.Operand.Shift.none),
         } },
@@ -3418,9 +3414,8 @@ fn genInlineMemsetCode(
     // mov count, #0
     _ = try self.addInst(.{
         .tag = .mov,
-        .data = .{ .rr_op = .{
+        .data = .{ .r_op_mov = .{
             .rd = count,
-            .rn = .r0,
             .op = Instruction.Operand.imm(0, 0),
         } },
     });
@@ -3429,8 +3424,7 @@ fn genInlineMemsetCode(
     // cmp count, len
     _ = try self.addInst(.{
         .tag = .cmp,
-        .data = .{ .rr_op = .{
-            .rd = .r0,
+        .data = .{ .r_op_cmp = .{
             .rn = count,
             .op = Instruction.Operand.reg(len, Instruction.Operand.Shift.none),
         } },
@@ -4020,9 +4014,7 @@ fn condBr(self: *Self, condition: MCValue) !Mir.Inst.Index {
             // bne ...
             _ = try self.addInst(.{
                 .tag = .cmp,
-                .cond = .al,
-                .data = .{ .rr_op = .{
-                    .rd = .r0,
+                .data = .{ .r_op_cmp = .{
                     .rn = reg,
                     .op = Instruction.Operand.imm(1, 0),
                 } },
@@ -4196,8 +4188,7 @@ fn isNull(self: *Self, ty: Type, operand: MCValue) !MCValue {
 
         _ = try self.addInst(.{
             .tag = .cmp,
-            .data = .{ .rr_op = .{
-                .rd = undefined,
+            .data = .{ .r_op_cmp = .{
                 .rn = reg_mcv.register,
                 .op = Instruction.Operand.fromU32(0).?,
             } },
@@ -4832,9 +4823,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
                     .register_v_flag => .vs,
                     else => unreachable,
                 },
-                .data = .{ .rr_op = .{
+                .data = .{ .r_op_mov = .{
                     .rd = cond_reg,
-                    .rn = .r0,
                     .op = Instruction.Operand.fromU32(1).?,
                 } },
             });
@@ -4935,9 +4925,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
             // mov reg, 0
             _ = try self.addInst(.{
                 .tag = .mov,
-                .data = .{ .rr_op = .{
+                .data = .{ .r_op_mov = .{
                     .rd = reg,
-                    .rn = .r0,
                     .op = zero,
                 } },
             });
@@ -4946,9 +4935,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
             _ = try self.addInst(.{
                 .tag = .mov,
                 .cond = condition,
-                .data = .{ .rr_op = .{
+                .data = .{ .r_op_mov = .{
                     .rd = reg,
-                    .rn = .r0,
                     .op = one,
                 } },
             });
@@ -4957,18 +4945,16 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
             if (Instruction.Operand.fromU32(x)) |op| {
                 _ = try self.addInst(.{
                     .tag = .mov,
-                    .data = .{ .rr_op = .{
+                    .data = .{ .r_op_mov = .{
                         .rd = reg,
-                        .rn = .r0,
                         .op = op,
                     } },
                 });
             } else if (Instruction.Operand.fromU32(~x)) |op| {
                 _ = try self.addInst(.{
                     .tag = .mvn,
-                    .data = .{ .rr_op = .{
+                    .data = .{ .r_op_mov = .{
                         .rd = reg,
-                        .rn = .r0,
                         .op = op,
                     } },
                 });
@@ -4984,9 +4970,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
                 } else {
                     _ = try self.addInst(.{
                         .tag = .mov,
-                        .data = .{ .rr_op = .{
+                        .data = .{ .r_op_mov = .{
                             .rd = reg,
-                            .rn = .r0,
                             .op = Instruction.Operand.imm(@truncate(u8, x), 0),
                         } },
                     });
@@ -5028,9 +5013,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
                     // orr reg, reg, #0xdd, 8
                     _ = try self.addInst(.{
                         .tag = .mov,
-                        .data = .{ .rr_op = .{
+                        .data = .{ .r_op_mov = .{
                             .rd = reg,
-                            .rn = .r0,
                             .op = Instruction.Operand.imm(@truncate(u8, x), 0),
                         } },
                     });
@@ -5069,9 +5053,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
             // mov reg, src_reg
             _ = try self.addInst(.{
                 .tag = .mov,
-                .data = .{ .rr_op = .{
+                .data = .{ .r_op_mov = .{
                     .rd = reg,
-                    .rn = .r0,
                     .op = Instruction.Operand.reg(src_reg, Instruction.Operand.Shift.none),
                 } },
             });
src/arch/arm/Emit.zig
@@ -385,20 +385,44 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
 fn mirDataProcessing(emit: *Emit, inst: Mir.Inst.Index) !void {
     const tag = emit.mir.instructions.items(.tag)[inst];
     const cond = emit.mir.instructions.items(.cond)[inst];
-    const rr_op = emit.mir.instructions.items(.data)[inst].rr_op;
 
     switch (tag) {
-        .add => try emit.writeInstruction(Instruction.add(cond, rr_op.rd, rr_op.rn, rr_op.op)),
-        .adds => try emit.writeInstruction(Instruction.adds(cond, rr_op.rd, rr_op.rn, rr_op.op)),
-        .@"and" => try emit.writeInstruction(Instruction.@"and"(cond, rr_op.rd, rr_op.rn, rr_op.op)),
-        .cmp => try emit.writeInstruction(Instruction.cmp(cond, rr_op.rn, rr_op.op)),
-        .eor => try emit.writeInstruction(Instruction.eor(cond, rr_op.rd, rr_op.rn, rr_op.op)),
-        .mov => try emit.writeInstruction(Instruction.mov(cond, rr_op.rd, rr_op.op)),
-        .mvn => try emit.writeInstruction(Instruction.mvn(cond, rr_op.rd, rr_op.op)),
-        .orr => try emit.writeInstruction(Instruction.orr(cond, rr_op.rd, rr_op.rn, rr_op.op)),
-        .rsb => try emit.writeInstruction(Instruction.rsb(cond, rr_op.rd, rr_op.rn, rr_op.op)),
-        .sub => try emit.writeInstruction(Instruction.sub(cond, rr_op.rd, rr_op.rn, rr_op.op)),
-        .subs => try emit.writeInstruction(Instruction.subs(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+        .add,
+        .adds,
+        .@"and",
+        .eor,
+        .orr,
+        .rsb,
+        .sub,
+        .subs,
+        => {
+            const rr_op = emit.mir.instructions.items(.data)[inst].rr_op;
+            switch (tag) {
+                .add => try emit.writeInstruction(Instruction.add(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+                .adds => try emit.writeInstruction(Instruction.adds(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+                .@"and" => try emit.writeInstruction(Instruction.@"and"(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+                .eor => try emit.writeInstruction(Instruction.eor(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+                .orr => try emit.writeInstruction(Instruction.orr(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+                .rsb => try emit.writeInstruction(Instruction.rsb(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+                .sub => try emit.writeInstruction(Instruction.sub(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+                .subs => try emit.writeInstruction(Instruction.subs(cond, rr_op.rd, rr_op.rn, rr_op.op)),
+                else => unreachable,
+            }
+        },
+        .cmp => {
+            const r_op_cmp = emit.mir.instructions.items(.data)[inst].r_op_cmp;
+            try emit.writeInstruction(Instruction.cmp(cond, r_op_cmp.rn, r_op_cmp.op));
+        },
+        .mov,
+        .mvn,
+        => {
+            const r_op_mov = emit.mir.instructions.items(.data)[inst].r_op_mov;
+            switch (tag) {
+                .mov => try emit.writeInstruction(Instruction.mov(cond, r_op_mov.rd, r_op_mov.op)),
+                .mvn => try emit.writeInstruction(Instruction.mvn(cond, r_op_mov.rd, r_op_mov.op)),
+                else => unreachable,
+            }
+        },
         else => unreachable,
     }
 }
src/arch/arm/Mir.zig
@@ -166,6 +166,20 @@ pub const Inst = struct {
             rd: Register,
             imm16: u16,
         },
+        /// A register and an operand
+        ///
+        /// Used by mov and mvn
+        r_op_mov: struct {
+            rd: Register,
+            op: bits.Instruction.Operand,
+        },
+        /// A register and an operand
+        ///
+        /// Used by cmp
+        r_op_cmp: struct {
+            rn: Register,
+            op: bits.Instruction.Operand,
+        },
         /// Two registers and a shift amount
         ///
         /// Used by e.g. lsl