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.
This commit is contained in:
joachimschmidt557 2022-09-17 12:26:21 +02:00
parent 4521456f66
commit 258b058eec
No known key found for this signature in database
GPG Key ID: E0B575BE2884ACC5
3 changed files with 12 additions and 43 deletions

View File

@ -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),

View File

@ -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)));

View File

@ -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