| ... | @@ -1016,8 +1016,27 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1016,8 +1016,27 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { |
| 1016 | } | 1016 | } |
| 1017 | | 1017 | |
| 1018 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { | 1018 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1019 | const stack_offset = try self.allocMemPtr(inst); | 1019 | const result: MCValue = switch (self.ret_mcv) { |
| 1020 | return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none }); | 1020 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, |
| | 1021 | .stack_offset => blk: { |
| | 1022 | // self.ret_mcv is an address to where this function |
| | 1023 | // should store its result into |
| | 1024 | const ret_ty = self.fn_type.fnReturnType(); |
| | 1025 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| | 1026 | .base = .{ .tag = .single_mut_pointer }, |
| | 1027 | .data = ret_ty, |
| | 1028 | }; |
| | 1029 | const ptr_ty = Type.initPayload(&ptr_ty_payload.base); |
| | 1030 | |
| | 1031 | // addr_reg will contain the address of where to store the |
| | 1032 | // result into |
| | 1033 | const addr_reg = try self.copyToTmpRegister(ptr_ty, self.ret_mcv); |
| | 1034 | break :blk .{ .register = addr_reg }; |
| | 1035 | }, |
| | 1036 | else => unreachable, // invalid return result |
| | 1037 | }; |
| | 1038 | |
| | 1039 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| 1021 | } | 1040 | } |
| 1022 | | 1041 | |
| 1023 | fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { | 1042 | fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -3631,6 +3650,7 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type | ... | @@ -3631,6 +3650,7 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type |
| 3631 | } | 3650 | } |
| 3632 | | 3651 | |
| 3633 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { | 3652 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| | 3653 | log.debug("store: storing {} to {}", .{ value, ptr }); |
| 3634 | const abi_size = value_ty.abiSize(self.target.*); | 3654 | const abi_size = value_ty.abiSize(self.target.*); |
| 3635 | | 3655 | |
| 3636 | switch (ptr) { | 3656 | switch (ptr) { |
| ... | @@ -3655,6 +3675,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3655,6 +3675,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3655 | .dead => unreachable, | 3675 | .dead => unreachable, |
| 3656 | .undef => unreachable, | 3676 | .undef => unreachable, |
| 3657 | .register => |value_reg| { | 3677 | .register => |value_reg| { |
| | 3678 | log.debug("store: register {} to {}", .{ value_reg, addr_reg }); |
| 3658 | try self.genStrRegister(value_reg, addr_reg, value_ty); | 3679 | try self.genStrRegister(value_reg, addr_reg, value_ty); |
| 3659 | }, | 3680 | }, |
| 3660 | else => { | 3681 | else => { |
| ... | @@ -3673,8 +3694,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3673,8 +3694,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3673 | self.register_manager.unlockReg(reg); | 3694 | self.register_manager.unlockReg(reg); |
| 3674 | }; | 3695 | }; |
| 3675 | | 3696 | |
| 3676 | const src_reg = addr_reg; | 3697 | const src_reg = regs[0]; |
| 3677 | const dst_reg = regs[0]; | 3698 | const dst_reg = addr_reg; |
| 3678 | const len_reg = regs[1]; | 3699 | const len_reg = regs[1]; |
| 3679 | const count_reg = regs[2]; | 3700 | const count_reg = regs[2]; |
| 3680 | const tmp_reg = regs[3]; | 3701 | const tmp_reg = regs[3]; |
| ... | @@ -3684,7 +3705,6 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3684,7 +3705,6 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3684 | // sub src_reg, fp, #off | 3705 | // sub src_reg, fp, #off |
| 3685 | try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); | 3706 | try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); |
| 3686 | }, | 3707 | }, |
| 3687 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }), | | |
| 3688 | .stack_argument_offset => |off| { | 3708 | .stack_argument_offset => |off| { |
| 3689 | _ = try self.addInst(.{ | 3709 | _ = try self.addInst(.{ |
| 3690 | .tag = .ldr_ptr_stack_argument, | 3710 | .tag = .ldr_ptr_stack_argument, |
| ... | @@ -3694,6 +3714,24 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3694,6 +3714,24 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3694 | } }, | 3714 | } }, |
| 3695 | }); | 3715 | }); |
| 3696 | }, | 3716 | }, |
| | 3717 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }), |
| | 3718 | .linker_load => |load_struct| { |
| | 3719 | const tag: Mir.Inst.Tag = switch (load_struct.@"type") { |
| | 3720 | .got => .load_memory_ptr_got, |
| | 3721 | .direct => .load_memory_ptr_direct, |
| | 3722 | }; |
| | 3723 | const mod = self.bin_file.options.module.?; |
| | 3724 | _ = try self.addInst(.{ |
| | 3725 | .tag = tag, |
| | 3726 | .data = .{ |
| | 3727 | .payload = try self.addExtra(Mir.LoadMemoryPie{ |
| | 3728 | .register = @enumToInt(src_reg), |
| | 3729 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| | 3730 | .sym_index = load_struct.sym_index, |
| | 3731 | }), |
| | 3732 | }, |
| | 3733 | }); |
| | 3734 | }, |
| 3697 | else => return self.fail("TODO store {} to register", .{value}), | 3735 | else => return self.fail("TODO store {} to register", .{value}), |
| 3698 | } | 3736 | } |
| 3699 | | 3737 | |
| ... | @@ -4428,7 +4466,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4428,7 +4466,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4428 | if (else_value == .dead) | 4466 | if (else_value == .dead) |
| 4429 | continue; | 4467 | continue; |
| 4430 | // The instruction is only overridden in the else branch. | 4468 | // The instruction is only overridden in the else branch. |
| 4431 | var i: usize = self.branch_stack.items.len - 2; | 4469 | var i: usize = self.branch_stack.items.len - 1; |
| 4432 | while (true) { | 4470 | while (true) { |
| 4433 | i -= 1; // If this overflows, the question is: why wasn't the instruction marked dead? | 4471 | i -= 1; // If this overflows, the question is: why wasn't the instruction marked dead? |
| 4434 | if (self.branch_stack.items[i].inst_table.get(else_key)) |mcv| { | 4472 | if (self.branch_stack.items[i].inst_table.get(else_key)) |mcv| { |
| ... | @@ -4455,7 +4493,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4455,7 +4493,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4455 | if (then_value == .dead) | 4493 | if (then_value == .dead) |
| 4456 | continue; | 4494 | continue; |
| 4457 | const parent_mcv = blk: { | 4495 | const parent_mcv = blk: { |
| 4458 | var i: usize = self.branch_stack.items.len - 2; | 4496 | var i: usize = self.branch_stack.items.len - 1; |
| 4459 | while (true) { | 4497 | while (true) { |
| 4460 | i -= 1; | 4498 | i -= 1; |
| 4461 | if (self.branch_stack.items[i].inst_table.get(then_key)) |mcv| { | 4499 | if (self.branch_stack.items[i].inst_table.get(then_key)) |mcv| { |