diff --git a/pcsx2/arm64/iCOP2-arm64.cpp b/pcsx2/arm64/iCOP2-arm64.cpp index 3692ddfeba..4d76da6162 100644 --- a/pcsx2/arm64/iCOP2-arm64.cpp +++ b/pcsx2/arm64/iCOP2-arm64.cpp @@ -495,9 +495,10 @@ static void cop2EmitFlagUpdate(int xyzw) armMoveAddressToReg(RSCRATCHADDR, &s_cop2DenormStatusFlag); armAsm->Ldr(RWSCRATCH, a64::MemOperand(RSCRATCHADDR)); - // Clear current (non-sticky) bits 8-15 - armAsm->Mov(a64::w4, 0xFF00); - armAsm->Bic(RWSCRATCH, RWSCRATCH, a64::w4); + // Clear current (non-sticky) bits 8-15. w9 scratch: w4 is an EE-SRA pin + // (rung 3) and this body emits inline into EE blocks. + armAsm->Mov(a64::w9, 0xFF00); + armAsm->Bic(RWSCRATCH, RWSCRATCH, a64::w9); // OR macFlag into sticky bits (0-7) — accumulates over time armAsm->Orr(RWSCRATCH, RWSCRATCH, macFlag); @@ -841,8 +842,8 @@ void recCOP2_CTC2() armAsm->And(a64::w2, a64::w2, 0x1800); armAsm->Orr(RWSCRATCH, RWSCRATCH, a64::w2); armAsm->Lsl(a64::w3, RWARG2, 14); - armAsm->Mov(a64::w4, 0x3cf0000); // not a valid logical-imm; materialize - armAsm->And(a64::w3, a64::w3, a64::w4); + armAsm->Mov(a64::w9, 0x3cf0000); // not a valid logical-imm; materialize (w9: w4 is a rung-3 pin) + armAsm->And(a64::w3, a64::w3, a64::w9); armAsm->Orr(RWSCRATCH, RWSCRATCH, a64::w3); // Broadcast the denormalized value into all 4 lanes of micro_statusflags. @@ -1950,9 +1951,10 @@ void recCOP2_VCLIP() armAsm->Cmp(a64::w2, 0); armAsm->Csel(a64::w1, a64::w1, a64::w3, a64::ne); // w1 = clip value - // Shift clipflag left by 6 - armAsm->Ldr(a64::w4, armVU0Mem(&VU0.clipflag)); - armAsm->Lsl(a64::w4, a64::w4, 6); + // Shift clipflag left by 6. Accumulates in w9 across the NEON stretch + // below (w4 is a rung-3 EE-SRA pin; this body emits inline into EE blocks). + armAsm->Ldr(a64::w9, armVU0Mem(&VU0.clipflag)); + armAsm->Lsl(a64::w9, a64::w9, 6); // Load fs = [x,y,z,w] as integers for the lane comparisons. armAsm->Ldr(RQSCRATCH, armVU0Mem(&VU0.VF[_Fs_cop2])); // q30 = [x,y,z,w] @@ -1985,19 +1987,19 @@ void recCOP2_VCLIP() armAsm->Umov(a64::w2, posMask.V4S(), 0); // 6-bit clip field // Merge into clipflag and mask to 24 bits - armAsm->Orr(a64::w4, a64::w4, a64::w2); - armAsm->And(a64::w4, a64::w4, 0xFFFFFF); + armAsm->Orr(a64::w9, a64::w9, a64::w2); + armAsm->And(a64::w9, a64::w9, 0xFFFFFF); // Store clipflag and sync to VI[REG_CLIP_FLAG] - armAsm->Str(a64::w4, armVU0Mem(&VU0.clipflag)); - armAsm->Str(a64::w4, armVU0Mem(&VU0.VI[REG_CLIP_FLAG])); + armAsm->Str(a64::w9, armVU0Mem(&VU0.clipflag)); + armAsm->Str(a64::w9, armVU0Mem(&VU0.VI[REG_CLIP_FLAG])); // Broadcast the new clipflag into all 4 lanes of micro_clipflags. A // subsequent VU0 microprogram loads its clip-flag instances directly from // the VURegs::micro_clipflags field in the mVU Execute prologue — without // this they would be stale (pre-VCLIP). RQSCRATCH is free here (its earlier // fs load is consumed). - armAsm->Dup(RQSCRATCH.V4S(), a64::w4); + armAsm->Dup(RQSCRATCH.V4S(), a64::w9); armAsm->Str(RQSCRATCH, armVU0Mem(&VU0.micro_clipflags)); } diff --git a/pcsx2/arm64/iR5900-arm64.cpp b/pcsx2/arm64/iR5900-arm64.cpp index 633a689e12..8ac54e982d 100644 --- a/pcsx2/arm64/iR5900-arm64.cpp +++ b/pcsx2/arm64/iR5900-arm64.cpp @@ -2063,35 +2063,36 @@ static bool recSkipTimeoutLoop(s32 reg, bool is_timeout_loop) armAsm->Cmp(RECCYCLE, 0); armEmitCondBranch(a64::ge, DispatcherEvent); - // w4 = reg value (the decrementing counter) - armAsm->Ldr(a64::w4, armCpuRegMem(&cpuRegs.GPR.r[reg].UL[0])); + // w9 = reg value (the decrementing counter). Scratches are w9/x10/w8: + // w4-w7 are rung-3 EE-SRA pins and this emits inline into EE blocks. + armAsm->Ldr(a64::w9, armCpuRegMem(&cpuRegs.GPR.r[reg].UL[0])); - // x5 = reg * 8 + delta (estimated end delta, s64) - armAsm->Add(a64::x5, RECCYCLE, a64::Operand(a64::x4, a64::LSL, 3)); + // x10 = reg * 8 + delta (estimated end delta, s64) + armAsm->Add(a64::x10, RECCYCLE, a64::Operand(a64::x9, a64::LSL, 3)); - // x5 = min(x5, 0) — can't run past the next event - armAsm->Cmp(a64::x5, 0); - armAsm->Csel(a64::x5, a64::xzr, a64::x5, a64::gt); // if x5 > 0, clamp to 0 + // x10 = min(x10, 0) — can't run past the next event + armAsm->Cmp(a64::x10, 0); + armAsm->Csel(a64::x10, a64::xzr, a64::x10, a64::gt); // if x10 > 0, clamp to 0 - // w6 = (new_delta - old_delta) >> 3 = iterations consumed (deltas share + // w8 = (new_delta - old_delta) >> 3 = iterations consumed (deltas share // the same nextEventCycle base, so their difference equals the absolute // cycle difference). - armAsm->Sub(a64::w6, a64::w5, RECCYCLE.W()); - armAsm->Lsr(a64::w6, a64::w6, 3); + armAsm->Sub(RWSCRATCH, a64::w10, RECCYCLE.W()); + armAsm->Lsr(RWSCRATCH, RWSCRATCH, 3); // Commit the new delta into RECCYCLE (no memory store — DispatcherEvent // converts and flushes it if we exit there; otherwise the next block-tail // event check uses RECCYCLE directly). - armAsm->Mov(RECCYCLE, a64::x5); + armAsm->Mov(RECCYCLE, a64::x10); // reg -= iterations consumed; sign-extend into the 64-bit guest reg // (the full UD[0] store covers the UL[0] half). - armAsm->Sub(a64::w4, a64::w4, a64::w6); - armAsm->Sxtw(a64::x4, a64::w4); - armStoreEERegPtr(a64::x4, &cpuRegs.GPR.r[reg].UD[0]); + armAsm->Sub(a64::w9, a64::w9, RWSCRATCH); + armAsm->Sxtw(a64::x9, a64::w9); + armStoreEERegPtr(a64::x9, &cpuRegs.GPR.r[reg].UD[0]); // if reg != 0, event interrupted the loop — go to dispatcher - armEmitCbnz(a64::w4, DispatcherEvent); + armEmitCbnz(a64::w9, DispatcherEvent); // Loop finished — set PC to end of block and dispatch armAsm->Mov(RWSCRATCH, s_nEndBlock); diff --git a/pcsx2/arm64/iR5900MultDiv-arm64.cpp b/pcsx2/arm64/iR5900MultDiv-arm64.cpp index 68925c083d..e192ff91ac 100644 --- a/pcsx2/arm64/iR5900MultDiv-arm64.cpp +++ b/pcsx2/arm64/iR5900MultDiv-arm64.cpp @@ -476,8 +476,8 @@ void recMADD() // Load existing HI:LO into x1 armLoadEERegPtr(a64::w3, &cpuRegs.LO.UL[0]); - armLoadEERegPtr(a64::w4, &cpuRegs.HI.UL[0]); - armAsm->Orr(a64::x3, a64::x3, a64::Operand(a64::x4, a64::LSL, 32)); + armLoadEERegPtr(RWSCRATCH, &cpuRegs.HI.UL[0]); // w8: w4 is a rung-3 EE-SRA pin + armAsm->Orr(a64::x3, a64::x3, a64::Operand(RXSCRATCH, a64::LSL, 32)); // Add armAsm->Add(a64::x0, a64::x0, a64::x3); @@ -512,8 +512,8 @@ void recMADDU() armAsm->Umull(a64::x0, a64::w1, a64::w2); armLoadEERegPtr(a64::w3, &cpuRegs.LO.UL[0]); - armLoadEERegPtr(a64::w4, &cpuRegs.HI.UL[0]); - armAsm->Orr(a64::x3, a64::x3, a64::Operand(a64::x4, a64::LSL, 32)); + armLoadEERegPtr(RWSCRATCH, &cpuRegs.HI.UL[0]); // w8: w4 is a rung-3 EE-SRA pin + armAsm->Orr(a64::x3, a64::x3, a64::Operand(RXSCRATCH, a64::LSL, 32)); armAsm->Add(a64::x0, a64::x0, a64::x3); @@ -547,8 +547,8 @@ void recMADD1() armAsm->Smull(a64::x0, a64::w1, a64::w2); armLoadEERegPtr(a64::w3, &cpuRegs.LO.UL[2]); // LO1 = LO.UL[2] (upper 64 bits) - armLoadEERegPtr(a64::w4, &cpuRegs.HI.UL[2]); // HI1 = HI.UL[2] - armAsm->Orr(a64::x3, a64::x3, a64::Operand(a64::x4, a64::LSL, 32)); + armLoadEERegPtr(RWSCRATCH, &cpuRegs.HI.UL[2]); // HI1 = HI.UL[2] (w8: w4 is a rung-3 pin) + armAsm->Orr(a64::x3, a64::x3, a64::Operand(RXSCRATCH, a64::LSL, 32)); armAsm->Add(a64::x0, a64::x0, a64::x3); @@ -582,8 +582,8 @@ void recMADDU1() armAsm->Umull(a64::x0, a64::w1, a64::w2); armLoadEERegPtr(a64::w3, &cpuRegs.LO.UL[2]); - armLoadEERegPtr(a64::w4, &cpuRegs.HI.UL[2]); - armAsm->Orr(a64::x3, a64::x3, a64::Operand(a64::x4, a64::LSL, 32)); + armLoadEERegPtr(RWSCRATCH, &cpuRegs.HI.UL[2]); // w8: w4 is a rung-3 pin + armAsm->Orr(a64::x3, a64::x3, a64::Operand(RXSCRATCH, a64::LSL, 32)); armAsm->Add(a64::x0, a64::x0, a64::x3);