| ... | @@ -362,6 +362,13 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { | ... | @@ -362,6 +362,13 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { |
| 362 | return result_index; | 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 | pub fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 { | 372 | pub fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 { |
| 366 | const fields = std.meta.fields(@TypeOf(extra)); | 373 | const fields = std.meta.fields(@TypeOf(extra)); |
| 367 | try self.mir_extra.ensureUnusedCapacity(self.gpa, fields.len); | 374 | try self.mir_extra.ensureUnusedCapacity(self.gpa, fields.len); |
| ... | @@ -396,10 +403,7 @@ fn gen(self: *Self) !void { | ... | @@ -396,10 +403,7 @@ fn gen(self: *Self) !void { |
| 396 | }); | 403 | }); |
| 397 | | 404 | |
| 398 | // <store other registers> | 405 | // <store other registers> |
| 399 | const backpatch_save_registers = try self.addInst(.{ | 406 | const backpatch_save_registers = try self.addNop(); |
| 400 | .tag = .nop, | | |
| 401 | .data = .{ .nop = {} }, | | |
| 402 | }); | | |
| 403 | | 407 | |
| 404 | // mov fp, sp | 408 | // mov fp, sp |
| 405 | _ = try self.addInst(.{ | 409 | _ = try self.addInst(.{ |
| ... | @@ -408,10 +412,7 @@ fn gen(self: *Self) !void { | ... | @@ -408,10 +412,7 @@ fn gen(self: *Self) !void { |
| 408 | }); | 412 | }); |
| 409 | | 413 | |
| 410 | // sub sp, sp, #reloc | 414 | // sub sp, sp, #reloc |
| 411 | const backpatch_reloc = try self.addInst(.{ | 415 | const backpatch_reloc = try self.addNop(); |
| 412 | .tag = .nop, | | |
| 413 | .data = .{ .nop = {} }, | | |
| 414 | }); | | |
| 415 | | 416 | |
| 416 | _ = try self.addInst(.{ | 417 | _ = try self.addInst(.{ |
| 417 | .tag = .dbg_prologue_end, | 418 | .tag = .dbg_prologue_end, |
| ... | @@ -3261,37 +3262,58 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3261,37 +3262,58 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3261 | return bt.finishAir(result); | 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 | const ret_ty = self.fn_type.fnReturnType(); | 3268 | const ret_ty = self.fn_type.fnReturnType(); |
| | 3269 | |
| 3266 | switch (self.ret_mcv) { | 3270 | switch (self.ret_mcv) { |
| | 3271 | .none => {}, |
| 3267 | .immediate => { | 3272 | .immediate => { |
| 3268 | assert(ret_ty.isError()); | 3273 | assert(ret_ty.isError()); |
| 3269 | }, | 3274 | }, |
| 3270 | else => { | 3275 | .register => |reg| { |
| 3271 | try self.setRegOrMem(ret_ty, self.ret_mcv, mcv); | 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 | // Just add space for an instruction, patch this later | 3287 | // Just add space for an instruction, patch this later |
| 3275 | const index = try self.addInst(.{ | 3288 | try self.exitlude_jump_relocs.append(self.gpa, try self.addNop()); |
| 3276 | .tag = .nop, | | |
| 3277 | .data = .{ .nop = {} }, | | |
| 3278 | }); | | |
| 3279 | try self.exitlude_jump_relocs.append(self.gpa, index); | | |
| 3280 | } | | |
| 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 | return self.finishAir(inst, .dead, .{ un_op, .none, .none }); | 3290 | return self.finishAir(inst, .dead, .{ un_op, .none, .none }); |
| 3287 | } | 3291 | } |
| 3288 | | 3292 | |
| 3289 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | 3293 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3290 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 3294 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 3291 | const ptr = try self.resolveInst(un_op); | 3295 | const ptr = try self.resolveInst(un_op); |
| 3292 | _ = ptr; | 3296 | const ptr_ty = self.air.typeOf(un_op); |
| 3293 | return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch}); | 3297 | const ret_ty = self.fn_type.fnReturnType(); |
| 3294 | //return self.finishAir(inst, .dead, .{ un_op, .none, .none }); | 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 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | 3319 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |