authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-09-20 21:51:02+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-09-20 21:51:02+02:00
log1f50810733e087faf884c5641617369c1c8e258f
treef70b1453ad6e2748374cbad4695601763e844679
parent4521456f66122c6348ef6980ae1eecdb94f4f110
parentf014de6456f0cd56d692c2a93c441d83b01796a2
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12912 from joachimschmidt557/stage2-arm

stage2 ARM: minor fixes

3 files changed, 39 insertions(+), 72 deletions(-)

src/arch/arm/CodeGen.zig+33-66
......@@ -169,40 +169,6 @@ const MCValue = union(enum) {
169169 cpsr_flags: Condition,
170170 /// The value is a function argument passed via the stack.
171171 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 }
206172};
207173
208174const Branch = struct {
......@@ -447,6 +413,11 @@ fn gen(self: *Self) !void {
447413 // sub sp, sp, #reloc
448414 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
450421 if (self.ret_mcv == .stack_offset) {
451422 // The address of where to store the return value is in
452423 // r0. As this register might get overwritten along the
......@@ -457,6 +428,28 @@ fn gen(self: *Self) !void {
457428 self.ret_mcv = MCValue{ .stack_offset = stack_offset };
458429 }
459430
431 for (self.args) |*arg, arg_index| {
432 // Copy register arguments to the stack
433 switch (arg.*) {
434 .register => |reg| {
435 // The first AIR instructions of the main body are guaranteed
436 // to be the functions arguments
437 const inst = self.air.getMainBody()[arg_index];
438 assert(self.air.instructions.items(.tag)[inst] == .arg);
439
440 const ty = self.air.typeOfIndex(inst);
441
442 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
443 const abi_align = ty.abiAlignment(self.target.*);
444 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
445 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
446
447 arg.* = MCValue{ .stack_offset = stack_offset };
448 },
449 else => {},
450 }
451 }
452
460453 _ = try self.addInst(.{
461454 .tag = .dbg_prologue_end,
462455 .cond = undefined,
......@@ -477,7 +470,6 @@ fn gen(self: *Self) !void {
477470 self.saved_regs_stack_space += 4;
478471 }
479472 }
480
481473 self.mir_instructions.set(push_reloc, .{
482474 .tag = .push,
483475 .data = .{ .register_list = saved_regs },
......@@ -489,7 +481,7 @@ fn gen(self: *Self) !void {
489481 const stack_size = aligned_total_stack_end - self.saved_regs_stack_space;
490482 self.max_end_stack = stack_size;
491483 self.mir_instructions.set(sub_reloc, .{
492 .tag = .sub_sp_scratch_r0,
484 .tag = .sub_sp_scratch_r4,
493485 .data = .{ .imm32 = stack_size },
494486 });
495487
......@@ -3796,7 +3788,8 @@ fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Typ
37963788 const tag: Mir.Inst.Tag = switch (abi_size) {
37973789 1 => .strb,
37983790 2 => .strh,
3799 3, 4 => .str,
3791 4 => .str,
3792 3 => return self.fail("TODO: genStrRegister for abi_size={}", .{abi_size}),
38003793 else => unreachable,
38013794 };
38023795
......@@ -3812,7 +3805,7 @@ fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Typ
38123805 } };
38133806
38143807 const data: Mir.Inst.Data = switch (abi_size) {
3815 1, 3, 4 => rr_offset,
3808 1, 4 => rr_offset,
38163809 2 => rr_extra_offset,
38173810 else => unreachable,
38183811 };
......@@ -4042,7 +4035,6 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, arg_index: u32) error{OutOfM
40424035 => {
40434036 switch (self.debug_output) {
40444037 .dwarf => |dw| {
4045 // const abi_size = @intCast(u32, ty.abiSize(self.target.*));
40464038 const adjusted_stack_offset = switch (mcv) {
40474039 .stack_offset => |offset| -@intCast(i32, offset),
40484040 .stack_argument_offset => |offset| @intCast(i32, self.saved_regs_stack_space + offset),
......@@ -4078,38 +4070,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
40784070 const arg_index = self.arg_index;
40794071 self.arg_index += 1;
40804072
4081 const ty = self.air.typeOfIndex(inst);
4082
4083 const result = self.args[arg_index];
4084 const mcv = switch (result) {
4085 // Copy registers to the stack
4086 .register => |reg| blk: {
4087 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
4088 const abi_align = ty.abiAlignment(self.target.*);
4089 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
4090 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
4091
4092 break :blk MCValue{ .stack_offset = stack_offset };
4093 },
4094 else => result,
4095 };
4096
40974073 try self.dbg_arg_relocs.append(self.gpa, .{
40984074 .inst = inst,
40994075 .index = arg_index,
41004076 });
41014077
4102 if (self.liveness.isUnused(inst))
4103 return self.finishAirBookkeeping();
4104
4105 switch (mcv) {
4106 .register => |reg| {
4107 self.register_manager.getRegAssumeFree(reg, inst);
4108 },
4109 else => {},
4110 }
4111
4112 return self.finishAir(inst, mcv, .{ .none, .none, .none });
4078 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4079 return self.finishAir(inst, result, .{ .none, .none, .none });
41134080}
41144081
41154082fn airBreakpoint(self: *Self) !void {
src/arch/arm/Emit.zig+4-4
......@@ -94,7 +94,7 @@ pub fn emitMir(
9494 .sub => try emit.mirDataProcessing(inst),
9595 .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
9999 .asr => try emit.mirShift(inst),
100100 .lsl => try emit.mirShift(inst),
......@@ -194,7 +194,7 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize {
194194 .dbg_prologue_end,
195195 => return 0,
196196
197 .sub_sp_scratch_r0 => {
197 .sub_sp_scratch_r4 => {
198198 const imm32 = emit.mir.instructions.items(.data)[inst].imm32;
199199
200200 if (imm32 == 0) {
......@@ -454,11 +454,11 @@ fn mirSubStackPointer(emit: *Emit, inst: Mir.Inst.Index) !void {
454454 const imm32 = emit.mir.instructions.items(.data)[inst].imm32;
455455
456456 switch (tag) {
457 .sub_sp_scratch_r0 => {
457 .sub_sp_scratch_r4 => {
458458 if (imm32 == 0) return;
459459
460460 const operand = Instruction.Operand.fromU32(imm32) orelse blk: {
461 const scratch: Register = .r0;
461 const scratch: Register = .r4;
462462
463463 if (Target.arm.featureSetHas(emit.target.cpu.features, .has_v7)) {
464464 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 {
113113 sub,
114114 /// Pseudo-instruction: Subtract 32-bit immediate from stack
115115 ///
116 /// r0 can be used by Emit as a scratch register for loading
116 /// r4 can be used by Emit as a scratch register for loading
117117 /// the immediate
118 sub_sp_scratch_r0,
118 sub_sp_scratch_r4,
119119 /// Subtract, update condition flags
120120 subs,
121121 /// Supervisor Call