| ... | ... | @@ -3919,7 +3919,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 3919 | 3919 | const rest_ty = try mod.intType(.unsigned, int_info.bits - hi_bits); |
| 3920 | 3920 | |
| 3921 | 3921 | const temp_regs = |
| 3922 | | try self.register_manager.allocRegs(3, .{ null, null, null }, abi.RegisterClass.gp); |
| 3922 | try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp); |
| 3923 | 3923 | const temp_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs); |
| 3924 | 3924 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); |
| 3925 | 3925 | |
| ... | ... | @@ -4000,11 +4000,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4000 | 4000 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 4001 | 4001 | const rhs_mcv = try self.resolveInst(bin_op.rhs); |
| 4002 | 4002 | |
| 4003 | | const temp_regs = try self.register_manager.allocRegs( |
| 4004 | | 4, |
| 4005 | | .{ null, null, null, null }, |
| 4006 | | abi.RegisterClass.gp, |
| 4007 | | ); |
| 4003 | const temp_regs = |
| 4004 | try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); |
| 4008 | 4005 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); |
| 4009 | 4006 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); |
| 4010 | 4007 | |
| ... | ... | @@ -6582,6 +6579,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 6582 | 6579 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { |
| 6583 | 6580 | else => null, |
| 6584 | 6581 | .Int => switch (ty.abiSize(mod)) { |
| 6582 | 0 => unreachable, |
| 6585 | 6583 | 1...8 => { |
| 6586 | 6584 | try self.spillEflagsIfOccupied(); |
| 6587 | 6585 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | ... | @@ -6647,7 +6645,64 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 6647 | 6645 | |
| 6648 | 6646 | break :result dst_mcv; |
| 6649 | 6647 | }, |
| 6650 | | else => return self.fail("TODO implement abs for {}", .{ty.fmt(mod)}), |
| 6648 | else => { |
| 6649 | const abi_size: u31 = @intCast(ty.abiSize(mod)); |
| 6650 | const limb_len = std.math.divCeil(u31, abi_size, 8) catch unreachable; |
| 6651 | |
| 6652 | const tmp_regs = |
| 6653 | try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp); |
| 6654 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(3, tmp_regs); |
| 6655 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); |
| 6656 | |
| 6657 | try self.spillEflagsIfOccupied(); |
| 6658 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 6659 | const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 6660 | src_mcv |
| 6661 | else |
| 6662 | try self.allocRegOrMem(inst, false); |
| 6663 | |
| 6664 | try self.asmMemoryImmediate( |
| 6665 | .{ ._, .cmp }, |
| 6666 | try dst_mcv.address().offset((limb_len - 1) * 8).deref().mem(self, .qword), |
| 6667 | Immediate.u(0), |
| 6668 | ); |
| 6669 | const positive = try self.asmJccReloc(.ns, undefined); |
| 6670 | |
| 6671 | try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[0].to32(), tmp_regs[0].to32()); |
| 6672 | try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[1].to8(), tmp_regs[1].to8()); |
| 6673 | |
| 6674 | const neg_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); |
| 6675 | try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[2].to32(), tmp_regs[2].to32()); |
| 6676 | try self.asmRegisterImmediate(.{ ._r, .sh }, tmp_regs[1].to8(), Immediate.u(1)); |
| 6677 | try self.asmRegisterMemory(.{ ._, .sbb }, tmp_regs[2].to64(), .{ |
| 6678 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 6679 | .mod = .{ .rm = .{ |
| 6680 | .size = .qword, |
| 6681 | .index = tmp_regs[0].to64(), |
| 6682 | .scale = .@"8", |
| 6683 | } }, |
| 6684 | }); |
| 6685 | try self.asmSetccRegister(.c, tmp_regs[1].to8()); |
| 6686 | try self.asmMemoryRegister(.{ ._, .mov }, .{ |
| 6687 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 6688 | .mod = .{ .rm = .{ |
| 6689 | .size = .qword, |
| 6690 | .index = tmp_regs[0].to64(), |
| 6691 | .scale = .@"8", |
| 6692 | } }, |
| 6693 | }, tmp_regs[2].to64()); |
| 6694 | |
| 6695 | if (self.hasFeature(.slow_incdec)) { |
| 6696 | try self.asmRegisterImmediate(.{ ._, .add }, tmp_regs[0].to32(), Immediate.u(1)); |
| 6697 | } else { |
| 6698 | try self.asmRegister(.{ ._, .inc }, tmp_regs[0].to32()); |
| 6699 | } |
| 6700 | try self.asmRegisterImmediate(.{ ._, .cmp }, tmp_regs[0].to32(), Immediate.u(limb_len)); |
| 6701 | _ = try self.asmJccReloc(.b, neg_loop); |
| 6702 | |
| 6703 | try self.performReloc(positive); |
| 6704 | break :result dst_mcv; |
| 6705 | }, |
| 6651 | 6706 | }, |
| 6652 | 6707 | .Float => return self.floatSign(inst, ty_op.operand, ty), |
| 6653 | 6708 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { |
| ... | ... | @@ -7435,7 +7490,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7435 | 7490 | const dst_regs: [2]Register = if (field_rc.supersetOf(container_rc) and |
| 7436 | 7491 | self.reuseOperand(inst, operand, 0, src_mcv)) src_regs else dst: { |
| 7437 | 7492 | const dst_regs = |
| 7438 | | try self.register_manager.allocRegs(2, .{ null, null }, field_rc); |
| 7493 | try self.register_manager.allocRegs(2, .{null} ** 2, field_rc); |
| 7439 | 7494 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); |
| 7440 | 7495 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); |
| 7441 | 7496 | |
| ... | ... | @@ -8343,11 +8398,8 @@ fn genMulDivBinOp( |
| 8343 | 8398 | .{}, |
| 8344 | 8399 | ); |
| 8345 | 8400 | |
| 8346 | | const temp_regs = try self.register_manager.allocRegs( |
| 8347 | | 4, |
| 8348 | | .{ null, null, null, null }, |
| 8349 | | abi.RegisterClass.gp, |
| 8350 | | ); |
| 8401 | const temp_regs = |
| 8402 | try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); |
| 8351 | 8403 | const temp_locks = self.register_manager.lockRegs(4, temp_regs); |
| 8352 | 8404 | defer for (temp_locks) |temp_lock| if (temp_lock) |lock| |
| 8353 | 8405 | self.register_manager.unlockReg(lock); |
| ... | ... | @@ -8909,14 +8961,14 @@ fn genBinOp( |
| 8909 | 8961 | const locks = self.register_manager.lockRegsAssumeUnused(2, lhs_regs); |
| 8910 | 8962 | break :locks .{ locks[0], locks[1] }; |
| 8911 | 8963 | }, |
| 8912 | | else => .{ null, null }, |
| 8964 | else => .{null} ** 2, |
| 8913 | 8965 | }; |
| 8914 | 8966 | defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 8915 | 8967 | |
| 8916 | 8968 | const rhs_locks: [2]?RegisterLock = switch (rhs_mcv) { |
| 8917 | 8969 | .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null }, |
| 8918 | 8970 | .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs), |
| 8919 | | else => .{ null, null }, |
| 8971 | else => .{null} ** 2, |
| 8920 | 8972 | }; |
| 8921 | 8973 | defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 8922 | 8974 | |
| ... | ... | @@ -8949,7 +9001,7 @@ fn genBinOp( |
| 8949 | 9001 | const dst_locks: [2]?RegisterLock = switch (dst_mcv) { |
| 8950 | 9002 | .register => |dst_reg| .{ self.register_manager.lockReg(dst_reg), null }, |
| 8951 | 9003 | .register_pair => |dst_regs| self.register_manager.lockRegs(2, dst_regs), |
| 8952 | | else => .{ null, null }, |
| 9004 | else => .{null} ** 2, |
| 8953 | 9005 | }; |
| 8954 | 9006 | defer for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 8955 | 9007 | |
| ... | ... | @@ -8965,7 +9017,7 @@ fn genBinOp( |
| 8965 | 9017 | const src_locks: [2]?RegisterLock = switch (src_mcv) { |
| 8966 | 9018 | .register => |src_reg| .{ self.register_manager.lockReg(src_reg), null }, |
| 8967 | 9019 | .register_pair => |src_regs| self.register_manager.lockRegs(2, src_regs), |
| 8968 | | else => .{ null, null }, |
| 9020 | else => .{null} ** 2, |
| 8969 | 9021 | }; |
| 8970 | 9022 | defer for (src_locks) |src_lock| if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 8971 | 9023 | |
| ... | ... | @@ -9025,7 +9077,7 @@ fn genBinOp( |
| 9025 | 9077 | else => dst: { |
| 9026 | 9078 | const dst_regs = try self.register_manager.allocRegs( |
| 9027 | 9079 | 2, |
| 9028 | | .{ null, null }, |
| 9080 | .{null} ** 2, |
| 9029 | 9081 | abi.RegisterClass.gp, |
| 9030 | 9082 | ); |
| 9031 | 9083 | const dst_regs_locks = self.register_manager.lockRegs(2, dst_regs); |
| ... | ... | @@ -11631,7 +11683,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 11631 | 11683 | |
| 11632 | 11684 | const regs = try self.register_manager.allocRegs( |
| 11633 | 11685 | 2, |
| 11634 | | .{ null, null }, |
| 11686 | .{null} ** 2, |
| 11635 | 11687 | abi.RegisterClass.gp, |
| 11636 | 11688 | ); |
| 11637 | 11689 | const acc_reg = regs[0].to64(); |
| ... | ... | @@ -16298,7 +16350,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 16298 | 16350 | try self.spillEflagsIfOccupied(); |
| 16299 | 16351 | |
| 16300 | 16352 | const tmp_regs = |
| 16301 | | try self.register_manager.allocRegs(2, .{ null, null }, abi.RegisterClass.gp); |
| 16353 | try self.register_manager.allocRegs(2, .{null} ** 2, abi.RegisterClass.gp); |
| 16302 | 16354 | const offset_reg = tmp_regs[0].to32(); |
| 16303 | 16355 | const addr_reg = tmp_regs[1].to64(); |
| 16304 | 16356 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); |