| ... | ... | @@ -362,6 +362,13 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { |
| 362 | 362 | return result_index; |
| 363 | 363 | } |
| 364 | 364 | |
| 365 | fn addNop(self: *Self) error{OutOfMemory}!Mir.Inst.Index { |
| 366 | return try self.addInst(.{ |
| 367 | .tag = .nop, |
| 368 | .data = .{ .nop = {} }, |
| 369 | }); |
| 370 | } |
| 371 | |
| 365 | 372 | pub fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 { |
| 366 | 373 | const fields = std.meta.fields(@TypeOf(extra)); |
| 367 | 374 | try self.mir_extra.ensureUnusedCapacity(self.gpa, fields.len); |
| ... | ... | @@ -396,10 +403,7 @@ fn gen(self: *Self) !void { |
| 396 | 403 | }); |
| 397 | 404 | |
| 398 | 405 | // <store other registers> |
| 399 | | const backpatch_save_registers = try self.addInst(.{ |
| 400 | | .tag = .nop, |
| 401 | | .data = .{ .nop = {} }, |
| 402 | | }); |
| 406 | const backpatch_save_registers = try self.addNop(); |
| 403 | 407 | |
| 404 | 408 | // mov fp, sp |
| 405 | 409 | _ = try self.addInst(.{ |
| ... | ... | @@ -408,10 +412,7 @@ fn gen(self: *Self) !void { |
| 408 | 412 | }); |
| 409 | 413 | |
| 410 | 414 | // sub sp, sp, #reloc |
| 411 | | const backpatch_reloc = try self.addInst(.{ |
| 412 | | .tag = .nop, |
| 413 | | .data = .{ .nop = {} }, |
| 414 | | }); |
| 415 | const backpatch_reloc = try self.addNop(); |
| 415 | 416 | |
| 416 | 417 | _ = try self.addInst(.{ |
| 417 | 418 | .tag = .dbg_prologue_end, |
| ... | ... | @@ -3261,37 +3262,58 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3261 | 3262 | return bt.finishAir(result); |
| 3262 | 3263 | } |
| 3263 | 3264 | |
| 3264 | | fn ret(self: *Self, mcv: MCValue) !void { |
| 3265 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 3266 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 3267 | const operand = try self.resolveInst(un_op); |
| 3265 | 3268 | const ret_ty = self.fn_type.fnReturnType(); |
| 3269 | |
| 3266 | 3270 | switch (self.ret_mcv) { |
| 3271 | .none => {}, |
| 3267 | 3272 | .immediate => { |
| 3268 | 3273 | assert(ret_ty.isError()); |
| 3269 | 3274 | }, |
| 3270 | | else => { |
| 3271 | | try self.setRegOrMem(ret_ty, self.ret_mcv, mcv); |
| 3275 | .register => |reg| { |
| 3276 | // Return result by value |
| 3277 | try self.genSetReg(ret_ty, reg, operand); |
| 3278 | }, |
| 3279 | .stack_offset => { |
| 3280 | // Return result by reference |
| 3281 | // TODO |
| 3282 | return self.fail("TODO implement airRet for {}", .{self.ret_mcv}); |
| 3272 | 3283 | }, |
| 3284 | else => unreachable, |
| 3273 | 3285 | } |
| 3286 | |
| 3274 | 3287 | // Just add space for an instruction, patch this later |
| 3275 | | const index = try self.addInst(.{ |
| 3276 | | .tag = .nop, |
| 3277 | | .data = .{ .nop = {} }, |
| 3278 | | }); |
| 3279 | | try self.exitlude_jump_relocs.append(self.gpa, index); |
| 3280 | | } |
| 3288 | try self.exitlude_jump_relocs.append(self.gpa, try self.addNop()); |
| 3281 | 3289 | |
| 3282 | | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 3283 | | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 3284 | | const operand = try self.resolveInst(un_op); |
| 3285 | | try self.ret(operand); |
| 3286 | 3290 | return self.finishAir(inst, .dead, .{ un_op, .none, .none }); |
| 3287 | 3291 | } |
| 3288 | 3292 | |
| 3289 | 3293 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3290 | 3294 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 3291 | 3295 | const ptr = try self.resolveInst(un_op); |
| 3292 | | _ = ptr; |
| 3293 | | return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch}); |
| 3294 | | //return self.finishAir(inst, .dead, .{ un_op, .none, .none }); |
| 3296 | const ptr_ty = self.air.typeOf(un_op); |
| 3297 | const ret_ty = self.fn_type.fnReturnType(); |
| 3298 | _ = ret_ty; |
| 3299 | |
| 3300 | switch (self.ret_mcv) { |
| 3301 | .none => {}, |
| 3302 | .register => { |
| 3303 | // Return result by value |
| 3304 | try self.load(self.ret_mcv, ptr, ptr_ty); |
| 3305 | }, |
| 3306 | .stack_offset => { |
| 3307 | // Return result by reference |
| 3308 | // TODO |
| 3309 | return self.fail("TODO implement airRetLoad for {}", .{self.ret_mcv}); |
| 3310 | }, |
| 3311 | else => unreachable, |
| 3312 | } |
| 3313 | |
| 3314 | try self.exitlude_jump_relocs.append(self.gpa, try self.addNop()); |
| 3315 | |
| 3316 | return self.finishAir(inst, .dead, .{ un_op, .none, .none }); |
| 3295 | 3317 | } |
| 3296 | 3318 | |
| 3297 | 3319 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |