| ... | @@ -428,6 +428,28 @@ fn gen(self: *Self) !void { | ... | @@ -428,6 +428,28 @@ fn gen(self: *Self) !void { |
| 428 | self.ret_mcv = MCValue{ .stack_offset = stack_offset }; | 428 | self.ret_mcv = MCValue{ .stack_offset = stack_offset }; |
| 429 | } | 429 | } |
| 430 | | 430 | |
| | 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 | |
| 431 | _ = try self.addInst(.{ | 453 | _ = try self.addInst(.{ |
| 432 | .tag = .dbg_prologue_end, | 454 | .tag = .dbg_prologue_end, |
| 433 | .cond = undefined, | 455 | .cond = undefined, |
| ... | @@ -3766,7 +3788,8 @@ fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Typ | ... | @@ -3766,7 +3788,8 @@ fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Typ |
| 3766 | const tag: Mir.Inst.Tag = switch (abi_size) { | 3788 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3767 | 1 => .strb, | 3789 | 1 => .strb, |
| 3768 | 2 => .strh, | 3790 | 2 => .strh, |
| 3769 | 3, 4 => .str, | 3791 | 4 => .str, |
| | 3792 | 3 => return self.fail("TODO: genStrRegister for abi_size={}", .{abi_size}), |
| 3770 | else => unreachable, | 3793 | else => unreachable, |
| 3771 | }; | 3794 | }; |
| 3772 | | 3795 | |
| ... | @@ -3782,7 +3805,7 @@ fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Typ | ... | @@ -3782,7 +3805,7 @@ fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Typ |
| 3782 | } }; | 3805 | } }; |
| 3783 | | 3806 | |
| 3784 | const data: Mir.Inst.Data = switch (abi_size) { | 3807 | const data: Mir.Inst.Data = switch (abi_size) { |
| 3785 | 1, 3, 4 => rr_offset, | 3808 | 1, 4 => rr_offset, |
| 3786 | 2 => rr_extra_offset, | 3809 | 2 => rr_extra_offset, |
| 3787 | else => unreachable, | 3810 | else => unreachable, |
| 3788 | }; | 3811 | }; |
| ... | @@ -4047,38 +4070,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4047,38 +4070,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 4047 | const arg_index = self.arg_index; | 4070 | const arg_index = self.arg_index; |
| 4048 | self.arg_index += 1; | 4071 | self.arg_index += 1; |
| 4049 | | 4072 | |
| 4050 | const ty = self.air.typeOfIndex(inst); | | |
| 4051 | | | |
| 4052 | const result = self.args[arg_index]; | | |
| 4053 | const mcv = switch (result) { | | |
| 4054 | // Copy registers to the stack | | |
| 4055 | .register => |reg| blk: { | | |
| 4056 | const abi_size = @intCast(u32, ty.abiSize(self.target.*)); | | |
| 4057 | const abi_align = ty.abiAlignment(self.target.*); | | |
| 4058 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); | | |
| 4059 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | | |
| 4060 | | | |
| 4061 | break :blk MCValue{ .stack_offset = stack_offset }; | | |
| 4062 | }, | | |
| 4063 | else => result, | | |
| 4064 | }; | | |
| 4065 | | | |
| 4066 | try self.dbg_arg_relocs.append(self.gpa, .{ | 4073 | try self.dbg_arg_relocs.append(self.gpa, .{ |
| 4067 | .inst = inst, | 4074 | .inst = inst, |
| 4068 | .index = arg_index, | 4075 | .index = arg_index, |
| 4069 | }); | 4076 | }); |
| 4070 | | 4077 | |
| 4071 | if (self.liveness.isUnused(inst)) | 4078 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; |
| 4072 | return self.finishAirBookkeeping(); | 4079 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| 4073 | | | |
| 4074 | switch (mcv) { | | |
| 4075 | .register => |reg| { | | |
| 4076 | self.register_manager.getRegAssumeFree(reg, inst); | | |
| 4077 | }, | | |
| 4078 | else => {}, | | |
| 4079 | } | | |
| 4080 | | | |
| 4081 | return self.finishAir(inst, mcv, .{ .none, .none, .none }); | | |
| 4082 | } | 4080 | } |
| 4083 | | 4081 | |
| 4084 | fn airBreakpoint(self: *Self) !void { | 4082 | fn airBreakpoint(self: *Self) !void { |