| ... | @@ -1548,7 +1548,7 @@ fn allocRegs( | ... | @@ -1548,7 +1548,7 @@ fn allocRegs( |
| 1548 | }; | 1548 | }; |
| 1549 | const raw_reg = try self.register_manager.allocReg(track_inst, gp); | 1549 | const raw_reg = try self.register_manager.allocReg(track_inst, gp); |
| 1550 | arg.reg.* = self.registerAlias(raw_reg, arg.ty); | 1550 | arg.reg.* = self.registerAlias(raw_reg, arg.ty); |
| 1551 | read_locks[i] = self.register_manager.lockReg(arg.reg.*); | 1551 | read_locks[i] = self.register_manager.lockRegAssumeUnused(arg.reg.*); |
| 1552 | } | 1552 | } |
| 1553 | } | 1553 | } |
| 1554 | | 1554 | |
| ... | @@ -2920,13 +2920,13 @@ fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: | ... | @@ -2920,13 +2920,13 @@ fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: |
| 2920 | Mir.Inst.Tag.lsr_immediate, | 2920 | Mir.Inst.Tag.lsr_immediate, |
| 2921 | .data = .{ .rr_shift = .{ | 2921 | .data = .{ .rr_shift = .{ |
| 2922 | .rd = dest_reg, | 2922 | .rd = dest_reg, |
| 2923 | .rn = source_reg, | 2923 | .rn = source_reg.toX(), |
| 2924 | .shift = shift, | 2924 | .shift = shift, |
| 2925 | } }, | 2925 | } }, |
| 2926 | }); | 2926 | }); |
| 2927 | } | 2927 | } |
| 2928 | | 2928 | |
| 2929 | return MCValue{ .register = dest_reg }; | 2929 | return MCValue{ .register = self.registerAlias(dest_reg, payload_ty) }; |
| 2930 | }, | 2930 | }, |
| 2931 | .stack_argument_offset => |off| { | 2931 | .stack_argument_offset => |off| { |
| 2932 | return MCValue{ .stack_argument_offset = off + offset }; | 2932 | return MCValue{ .stack_argument_offset = off + offset }; |
| ... | @@ -4215,18 +4215,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -4215,18 +4215,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 4215 | | 4215 | |
| 4216 | const result: MCValue = result: { | 4216 | const result: MCValue = result: { |
| 4217 | switch (info.return_value) { | 4217 | switch (info.return_value) { |
| 4218 | .register => |reg| { | 4218 | .register => { |
| 4219 | if (RegisterManager.indexOfReg(&callee_preserved_regs, reg) == null) { | 4219 | // Save function return value in a callee saved register |
| 4220 | // Save function return value in a callee saved register | 4220 | break :result try self.copyToNewRegister(inst, info.return_value); |
| 4221 | break :result try self.copyToNewRegister(inst, info.return_value); | | |
| 4222 | } | | |
| 4223 | }, | 4221 | }, |
| 4224 | else => {}, | 4222 | else => {}, |
| 4225 | } | 4223 | } |
| 4226 | break :result info.return_value; | 4224 | break :result info.return_value; |
| 4227 | }; | 4225 | }; |
| 4228 | | 4226 | |
| 4229 | if (args.len + 1 <= Liveness.bpi - 1) { | 4227 | if (args.len <= Liveness.bpi - 2) { |
| 4230 | var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1); | 4228 | var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1); |
| 4231 | buf[0] = callee; | 4229 | buf[0] = callee; |
| 4232 | std.mem.copy(Air.Inst.Ref, buf[1..], args); | 4230 | std.mem.copy(Air.Inst.Ref, buf[1..], args); |
| ... | @@ -4642,19 +4640,13 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4642,19 +4640,13 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4642 | } | 4640 | } |
| 4643 | | 4641 | |
| 4644 | fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { | 4642 | fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { |
| 4645 | if (operand_ty.isPtrLikeOptional()) { | 4643 | const sentinel_ty: Type = if (!operand_ty.isPtrLikeOptional()) blk: { |
| 4646 | assert(operand_ty.abiSize(self.target.*) == 8); | | |
| 4647 | | | |
| 4648 | const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } }; | | |
| 4649 | return self.cmp(operand_bind, imm_bind, Type.usize, .eq); | | |
| 4650 | } else { | | |
| 4651 | var buf: Type.Payload.ElemType = undefined; | 4644 | var buf: Type.Payload.ElemType = undefined; |
| 4652 | const payload_ty = operand_ty.optionalChild(&buf); | 4645 | const payload_ty = operand_ty.optionalChild(&buf); |
| 4653 | const sentinel_ty = if (payload_ty.hasRuntimeBitsIgnoreComptime()) Type.bool else operand_ty; | 4646 | break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime()) Type.bool else operand_ty; |
| 4654 | | 4647 | } else operand_ty; |
| 4655 | const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } }; | 4648 | const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } }; |
| 4656 | return self.cmp(operand_bind, imm_bind, sentinel_ty, .eq); | 4649 | return self.cmp(operand_bind, imm_bind, sentinel_ty, .eq); |
| 4657 | } | | |
| 4658 | } | 4650 | } |
| 4659 | | 4651 | |
| 4660 | fn isNonNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { | 4652 | fn isNonNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { |
| ... | @@ -4692,10 +4684,10 @@ fn isNonErr(self: *Self, ty: Type, operand: MCValue) !MCValue { | ... | @@ -4692,10 +4684,10 @@ fn isNonErr(self: *Self, ty: Type, operand: MCValue) !MCValue { |
| 4692 | fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { | 4684 | fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4693 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 4685 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 4694 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4686 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4695 | const operand_bind: ReadArg.Bind = .{ .inst = un_op }; | 4687 | const operand = try self.resolveInst(un_op); |
| 4696 | const operand_ty = self.air.typeOf(un_op); | 4688 | const operand_ty = self.air.typeOf(un_op); |
| 4697 | | 4689 | |
| 4698 | break :result try self.isNull(operand_bind, operand_ty); | 4690 | break :result try self.isNull(.{ .mcv = operand }, operand_ty); |
| 4699 | }; | 4691 | }; |
| 4700 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | 4692 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| 4701 | } | 4693 | } |
| ... | @@ -4718,10 +4710,10 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4718,10 +4710,10 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4718 | fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { | 4710 | fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4719 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 4711 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 4720 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4712 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4721 | const operand_bind: ReadArg.Bind = .{ .inst = un_op }; | 4713 | const operand = try self.resolveInst(un_op); |
| 4722 | const operand_ty = self.air.typeOf(un_op); | 4714 | const operand_ty = self.air.typeOf(un_op); |
| 4723 | | 4715 | |
| 4724 | break :result try self.isNonNull(operand_bind, operand_ty); | 4716 | break :result try self.isNonNull(.{ .mcv = operand }, operand_ty); |
| 4725 | }; | 4717 | }; |
| 4726 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | 4718 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| 4727 | } | 4719 | } |