| ... | ... | @@ -1858,6 +1858,7 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void { |
| 1858 | 1858 | } |
| 1859 | 1859 | |
| 1860 | 1860 | fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1861 | const mod = self.bin_file.comp.module.?; |
| 1861 | 1862 | var arg_index = self.arg_index; |
| 1862 | 1863 | |
| 1863 | 1864 | // we skip over args that have no bits |
| ... | ... | @@ -1867,10 +1868,21 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1867 | 1868 | const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: { |
| 1868 | 1869 | const src_mcv = self.args[arg_index]; |
| 1869 | 1870 | |
| 1871 | // we want to move every arg onto the stack. |
| 1872 | // while it might no tbe the best solution right now, it simplifies |
| 1873 | // the spilling of args with multiple arg levels. |
| 1870 | 1874 | const dst_mcv = switch (src_mcv) { |
| 1871 | 1875 | .register => |src_reg| dst: { |
| 1872 | | try self.register_manager.getReg(src_reg, inst); |
| 1873 | | break :dst src_mcv; |
| 1876 | // TODO: get the true type of the arg, and fit the spill to size. |
| 1877 | const arg_size = Type.usize.abiSize(mod); |
| 1878 | const arg_align = Type.usize.abiAlignment(mod); |
| 1879 | const offset = try self.allocMem(inst, @intCast(arg_size), arg_align); |
| 1880 | try self.genSetStack(Type.usize, offset, .{ .register = src_reg }); |
| 1881 | |
| 1882 | // can go on to be reused in next function call |
| 1883 | self.register_manager.freeReg(src_reg); |
| 1884 | |
| 1885 | break :dst .{ .stack_offset = offset }; |
| 1874 | 1886 | }, |
| 1875 | 1887 | else => return self.fail("TODO: airArg {s}", .{@tagName(src_mcv)}), |
| 1876 | 1888 | }; |
| ... | ... | @@ -3258,17 +3270,26 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 3258 | 3270 | return self.fail("TODO: support more than 8 function args", .{}); |
| 3259 | 3271 | } |
| 3260 | 3272 | |
| 3273 | const locks = try self.gpa.alloc(RegisterLock, result.args.len); |
| 3274 | defer self.gpa.free(locks); |
| 3275 | |
| 3261 | 3276 | for (0..result.args.len) |i| { |
| 3262 | 3277 | const arg_reg = try self.register_manager.allocReg(null, fa); |
| 3278 | const lock = self.register_manager.lockRegAssumeUnused(arg_reg); |
| 3279 | locks[i] = lock; |
| 3263 | 3280 | result.args[i] = .{ .register = arg_reg }; |
| 3264 | 3281 | } |
| 3265 | 3282 | |
| 3283 | // we can just free the locks now, as this should be the only place where the fa |
| 3284 | // arg set is used. |
| 3285 | for (locks) |lock| { |
| 3286 | self.register_manager.unlockReg(lock); |
| 3287 | } |
| 3288 | |
| 3266 | 3289 | // stack_offset = num s registers spilled + local var space |
| 3267 | | var stack_offset: u32 = 0; |
| 3268 | | _ = &stack_offset; |
| 3269 | 3290 | // TODO: spill used s registers here |
| 3270 | 3291 | |
| 3271 | | result.stack_byte_count = stack_offset; |
| 3292 | result.stack_byte_count = 0; |
| 3272 | 3293 | result.stack_align = .@"16"; |
| 3273 | 3294 | }, |
| 3274 | 3295 | else => return self.fail("TODO implement function parameters for {} on riscv64", .{cc}), |