mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
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:
parent
4521456f66
commit
258b058eec
@ -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),
|
||||
|
||||
@ -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)));
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user