From 258b058eecb54e160ac60e72b0354f99f3202bdf Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Sat, 17 Sep 2022 12:26:21 +0200 Subject: [PATCH] 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. --- src/arch/arm/CodeGen.zig | 43 ++++++---------------------------------- src/arch/arm/Emit.zig | 8 ++++---- src/arch/arm/Mir.zig | 4 ++-- 3 files changed, 12 insertions(+), 43 deletions(-) diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index d3ec760607..55cdcf8411 100644 --- a/src/arch/arm/CodeGen.zig +++ b/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), diff --git a/src/arch/arm/Emit.zig b/src/arch/arm/Emit.zig index 188f5a5cfe..91993f00d2 100644 --- a/src/arch/arm/Emit.zig +++ b/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))); diff --git a/src/arch/arm/Mir.zig b/src/arch/arm/Mir.zig index ab64dbf738..3478d8dc58 100644 --- a/src/arch/arm/Mir.zig +++ b/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