authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-09-17 12:26:21+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-09-20 17:14:27+02:00
log258b058eecb54e160ac60e72b0354f99f3202bdf
treeaee5b0c2b12871e9047d0983c1926afe29d6ac5a
parent4521456f66122c6348ef6980ae1eecdb94f4f110
signaturelock-open Commit is signed but in an unrecognized format.

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.

3 files changed, 12 insertions(+), 43 deletions(-)

src/arch/arm/CodeGen.zig+6-37
...@@ -169,40 +169,6 @@ const MCValue = union(enum) {...@@ -169,40 +169,6 @@ const MCValue = union(enum) {
169 cpsr_flags: Condition,169 cpsr_flags: Condition,
170 /// The value is a function argument passed via the stack.170 /// The value is a function argument passed via the stack.
171 stack_argument_offset: u32,171 stack_argument_offset: u32,
172
173 fn isMemory(mcv: MCValue) bool {
174 return switch (mcv) {
175 .memory, .stack_offset, .stack_argument_offset => true,
176 else => false,
177 };
178 }
179
180 fn isImmediate(mcv: MCValue) bool {
181 return switch (mcv) {
182 .immediate => true,
183 else => false,
184 };
185 }
186
187 fn isMutable(mcv: MCValue) bool {
188 return switch (mcv) {
189 .none => unreachable,
190 .unreach => unreachable,
191 .dead => unreachable,
192
193 .immediate,
194 .memory,
195 .cpsr_flags,
196 .ptr_stack_offset,
197 .undef,
198 .stack_argument_offset,
199 => false,
200
201 .register,
202 .stack_offset,
203 => true,
204 };
205 }
206};172};
207173
208const Branch = struct {174const Branch = struct {
...@@ -447,6 +413,11 @@ fn gen(self: *Self) !void {...@@ -447,6 +413,11 @@ fn gen(self: *Self) !void {
447 // sub sp, sp, #reloc413 // sub sp, sp, #reloc
448 const sub_reloc = try self.addNop();414 const sub_reloc = try self.addNop();
449415
416 // The sub_sp_scratch_r4 instruction may use r4, so we mark r4
417 // as allocated by this function.
418 const index = RegisterManager.indexOfRegIntoTracked(.r4).?;
419 self.register_manager.allocated_registers.set(index);
420
450 if (self.ret_mcv == .stack_offset) {421 if (self.ret_mcv == .stack_offset) {
451 // The address of where to store the return value is in422 // The address of where to store the return value is in
452 // r0. As this register might get overwritten along the423 // r0. As this register might get overwritten along the
...@@ -477,7 +448,6 @@ fn gen(self: *Self) !void {...@@ -477,7 +448,6 @@ fn gen(self: *Self) !void {
477 self.saved_regs_stack_space += 4;448 self.saved_regs_stack_space += 4;
478 }449 }
479 }450 }
480
481 self.mir_instructions.set(push_reloc, .{451 self.mir_instructions.set(push_reloc, .{
482 .tag = .push,452 .tag = .push,
483 .data = .{ .register_list = saved_regs },453 .data = .{ .register_list = saved_regs },
...@@ -489,7 +459,7 @@ fn gen(self: *Self) !void {...@@ -489,7 +459,7 @@ fn gen(self: *Self) !void {
489 const stack_size = aligned_total_stack_end - self.saved_regs_stack_space;459 const stack_size = aligned_total_stack_end - self.saved_regs_stack_space;
490 self.max_end_stack = stack_size;460 self.max_end_stack = stack_size;
491 self.mir_instructions.set(sub_reloc, .{461 self.mir_instructions.set(sub_reloc, .{
492 .tag = .sub_sp_scratch_r0,462 .tag = .sub_sp_scratch_r4,
493 .data = .{ .imm32 = stack_size },463 .data = .{ .imm32 = stack_size },
494 });464 });
495465
...@@ -4042,7 +4012,6 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, arg_index: u32) error{OutOfM...@@ -4042,7 +4012,6 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, arg_index: u32) error{OutOfM
4042 => {4012 => {
4043 switch (self.debug_output) {4013 switch (self.debug_output) {
4044 .dwarf => |dw| {4014 .dwarf => |dw| {
4045 // const abi_size = @intCast(u32, ty.abiSize(self.target.*));
4046 const adjusted_stack_offset = switch (mcv) {4015 const adjusted_stack_offset = switch (mcv) {
4047 .stack_offset => |offset| -@intCast(i32, offset),4016 .stack_offset => |offset| -@intCast(i32, offset),
4048 .stack_argument_offset => |offset| @intCast(i32, self.saved_regs_stack_space + offset),4017 .stack_argument_offset => |offset| @intCast(i32, self.saved_regs_stack_space + offset),
src/arch/arm/Emit.zig+4-4
...@@ -94,7 +94,7 @@ pub fn emitMir(...@@ -94,7 +94,7 @@ pub fn emitMir(
94 .sub => try emit.mirDataProcessing(inst),94 .sub => try emit.mirDataProcessing(inst),
95 .subs => try emit.mirDataProcessing(inst),95 .subs => try emit.mirDataProcessing(inst),
9696
97 .sub_sp_scratch_r0 => try emit.mirSubStackPointer(inst),97 .sub_sp_scratch_r4 => try emit.mirSubStackPointer(inst),
9898
99 .asr => try emit.mirShift(inst),99 .asr => try emit.mirShift(inst),
100 .lsl => try emit.mirShift(inst),100 .lsl => try emit.mirShift(inst),
...@@ -194,7 +194,7 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize {...@@ -194,7 +194,7 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize {
194 .dbg_prologue_end,194 .dbg_prologue_end,
195 => return 0,195 => return 0,
196196
197 .sub_sp_scratch_r0 => {197 .sub_sp_scratch_r4 => {
198 const imm32 = emit.mir.instructions.items(.data)[inst].imm32;198 const imm32 = emit.mir.instructions.items(.data)[inst].imm32;
199199
200 if (imm32 == 0) {200 if (imm32 == 0) {
...@@ -454,11 +454,11 @@ fn mirSubStackPointer(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -454,11 +454,11 @@ fn mirSubStackPointer(emit: *Emit, inst: Mir.Inst.Index) !void {
454 const imm32 = emit.mir.instructions.items(.data)[inst].imm32;454 const imm32 = emit.mir.instructions.items(.data)[inst].imm32;
455455
456 switch (tag) {456 switch (tag) {
457 .sub_sp_scratch_r0 => {457 .sub_sp_scratch_r4 => {
458 if (imm32 == 0) return;458 if (imm32 == 0) return;
459459
460 const operand = Instruction.Operand.fromU32(imm32) orelse blk: {460 const operand = Instruction.Operand.fromU32(imm32) orelse blk: {
461 const scratch: Register = .r0;461 const scratch: Register = .r4;
462462
463 if (Target.arm.featureSetHas(emit.target.cpu.features, .has_v7)) {463 if (Target.arm.featureSetHas(emit.target.cpu.features, .has_v7)) {
464 try emit.writeInstruction(Instruction.movw(cond, scratch, @truncate(u16, imm32)));464 try emit.writeInstruction(Instruction.movw(cond, scratch, @truncate(u16, imm32)));
src/arch/arm/Mir.zig+2-2
...@@ -113,9 +113,9 @@ pub const Inst = struct {...@@ -113,9 +113,9 @@ pub const Inst = struct {
113 sub,113 sub,
114 /// Pseudo-instruction: Subtract 32-bit immediate from stack114 /// Pseudo-instruction: Subtract 32-bit immediate from stack
115 ///115 ///
116 /// r0 can be used by Emit as a scratch register for loading116 /// r4 can be used by Emit as a scratch register for loading
117 /// the immediate117 /// the immediate
118 sub_sp_scratch_r0,118 sub_sp_scratch_r4,
119 /// Subtract, update condition flags119 /// Subtract, update condition flags
120 subs,120 subs,
121 /// Supervisor Call121 /// Supervisor Call