Commit 258b058eec

joachimschmidt557 <joachim.schmidt557@outlook.com>
2022-09-17 12:26:21
stage2 ARM: make sub_sp_scratch MIR instruction use r4
r0 is used for argument passing, so this register is not available as a scratch register upon function entry.
1 parent 4521456
Changed files (3)
src/arch/arm/CodeGen.zig
@@ -169,40 +169,6 @@ const MCValue = union(enum) {
     cpsr_flags: Condition,
     /// The value is a function argument passed via the stack.
     stack_argument_offset: u32,
-
-    fn isMemory(mcv: MCValue) bool {
-        return switch (mcv) {
-            .memory, .stack_offset, .stack_argument_offset => true,
-            else => false,
-        };
-    }
-
-    fn isImmediate(mcv: MCValue) bool {
-        return switch (mcv) {
-            .immediate => true,
-            else => false,
-        };
-    }
-
-    fn isMutable(mcv: MCValue) bool {
-        return switch (mcv) {
-            .none => unreachable,
-            .unreach => unreachable,
-            .dead => unreachable,
-
-            .immediate,
-            .memory,
-            .cpsr_flags,
-            .ptr_stack_offset,
-            .undef,
-            .stack_argument_offset,
-            => false,
-
-            .register,
-            .stack_offset,
-            => true,
-        };
-    }
 };
 
 const Branch = struct {
@@ -447,6 +413,11 @@ fn gen(self: *Self) !void {
         // sub sp, sp, #reloc
         const sub_reloc = try self.addNop();
 
+        // The sub_sp_scratch_r4 instruction may use r4, so we mark r4
+        // as allocated by this function.
+        const index = RegisterManager.indexOfRegIntoTracked(.r4).?;
+        self.register_manager.allocated_registers.set(index);
+
         if (self.ret_mcv == .stack_offset) {
             // The address of where to store the return value is in
             // r0. As this register might get overwritten along the
@@ -477,7 +448,6 @@ fn gen(self: *Self) !void {
                 self.saved_regs_stack_space += 4;
             }
         }
-
         self.mir_instructions.set(push_reloc, .{
             .tag = .push,
             .data = .{ .register_list = saved_regs },
@@ -489,7 +459,7 @@ fn gen(self: *Self) !void {
         const stack_size = aligned_total_stack_end - self.saved_regs_stack_space;
         self.max_end_stack = stack_size;
         self.mir_instructions.set(sub_reloc, .{
-            .tag = .sub_sp_scratch_r0,
+            .tag = .sub_sp_scratch_r4,
             .data = .{ .imm32 = stack_size },
         });
 
@@ -4042,7 +4012,6 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, arg_index: u32) error{OutOfM
         => {
             switch (self.debug_output) {
                 .dwarf => |dw| {
-                    // const abi_size = @intCast(u32, ty.abiSize(self.target.*));
                     const adjusted_stack_offset = switch (mcv) {
                         .stack_offset => |offset| -@intCast(i32, offset),
                         .stack_argument_offset => |offset| @intCast(i32, self.saved_regs_stack_space + offset),
src/arch/arm/Emit.zig
@@ -94,7 +94,7 @@ pub fn emitMir(
             .sub => try emit.mirDataProcessing(inst),
             .subs => try emit.mirDataProcessing(inst),
 
-            .sub_sp_scratch_r0 => try emit.mirSubStackPointer(inst),
+            .sub_sp_scratch_r4 => try emit.mirSubStackPointer(inst),
 
             .asr => try emit.mirShift(inst),
             .lsl => try emit.mirShift(inst),
@@ -194,7 +194,7 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize {
         .dbg_prologue_end,
         => return 0,
 
-        .sub_sp_scratch_r0 => {
+        .sub_sp_scratch_r4 => {
             const imm32 = emit.mir.instructions.items(.data)[inst].imm32;
 
             if (imm32 == 0) {
@@ -454,11 +454,11 @@ fn mirSubStackPointer(emit: *Emit, inst: Mir.Inst.Index) !void {
     const imm32 = emit.mir.instructions.items(.data)[inst].imm32;
 
     switch (tag) {
-        .sub_sp_scratch_r0 => {
+        .sub_sp_scratch_r4 => {
             if (imm32 == 0) return;
 
             const operand = Instruction.Operand.fromU32(imm32) orelse blk: {
-                const scratch: Register = .r0;
+                const scratch: Register = .r4;
 
                 if (Target.arm.featureSetHas(emit.target.cpu.features, .has_v7)) {
                     try emit.writeInstruction(Instruction.movw(cond, scratch, @truncate(u16, imm32)));
src/arch/arm/Mir.zig
@@ -113,9 +113,9 @@ pub const Inst = struct {
         sub,
         /// Pseudo-instruction: Subtract 32-bit immediate from stack
         ///
-        /// r0 can be used by Emit as a scratch register for loading
+        /// r4 can be used by Emit as a scratch register for loading
         /// the immediate
-        sub_sp_scratch_r0,
+        sub_sp_scratch_r4,
         /// Subtract, update condition flags
         subs,
         /// Supervisor Call