zig

fork of https://codeberg.org/ziglang/zig
Log | Tree | Refs | README | LICENSE

commit 258b058eecb54e160ac60e72b0354f99f3202bdf (tree)
parent 4521456f66122c6348ef6980ae1eecdb94f4f110
Author: joachimschmidt557 <joachim.schmidt557@outlook.com>
Date:   Sat, 17 Sep 2022 12:26:21 +0200

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.

Diffstat:
Msrc/arch/arm/CodeGen.zig | 43++++++-------------------------------------
Msrc/arch/arm/Emit.zig | 8++++----
Msrc/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 @@ -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 @@ -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 @@ -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