diff --git a/app/src/main/cpp/common/Pcsx2Defs.h b/app/src/main/cpp/common/Pcsx2Defs.h index be997ec..86f1261 100644 --- a/app/src/main/cpp/common/Pcsx2Defs.h +++ b/app/src/main/cpp/common/Pcsx2Defs.h @@ -28,7 +28,7 @@ static constexpr bool IsDebugBuild = false; static constexpr unsigned int __pagesize = OVERRIDE_HOST_PAGE_SIZE; static constexpr unsigned int __pagemask = __pagesize - 1; static constexpr unsigned int __pageshift = std::bit_width(__pagemask); -#elif defined(_M_ARM64) +#elif defined(_M_ARM64) && !defined(ANDROID) // Apple Silicon uses 16KB pages and 128 byte cache lines. static constexpr unsigned int __pagesize = 0x4000; static constexpr unsigned int __pageshift = 14; @@ -41,7 +41,7 @@ static constexpr bool IsDebugBuild = false; #endif #if defined(OVERRIDE_HOST_CACHE_LINE_SIZE) static constexpr unsigned int __cachelinesize = OVERRIDE_HOST_CACHE_LINE_SIZE; -#elif defined(_M_ARM64) +#elif defined(_M_ARM64) && !defined(ANDROID) static constexpr unsigned int __cachelinesize = 128; #else static constexpr unsigned int __cachelinesize = 64; diff --git a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp index 30a90c8..525d12a 100644 --- a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp +++ b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp @@ -359,7 +359,7 @@ void recMTC0() // xADD(ecx, scaleblockcycles_clear()); // xMOV(ptr32[&cpuRegs.cycle], ecx); // update cycles armAdd(ECX, PTR_CPU(cpuRegs.cycle), scaleblockcycles_clear()); - _eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[9], _Rt_); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.CP0.r[9]), _Rt_); // xMOV(ptr[&cpuRegs.lastCOP0Cycle], ecx); armStore(PTR_CPU(cpuRegs.lastCOP0Cycle), ECX); break; @@ -376,7 +376,7 @@ void recMTC0() armAdd(PTR_CPU(cpuRegs.cycle), scaleblockcycles_clear()); // xFastCall((void*)COP0_UpdatePCCR); armEmitCall(reinterpret_cast(COP0_UpdatePCCR)); - _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.PERF.n.pccr), _Rt_); // xFastCall((void*)COP0_DiagnosticPCCR); armEmitCall(reinterpret_cast(COP0_DiagnosticPCCR)); } @@ -386,7 +386,7 @@ void recMTC0() // xADD(ecx, scaleblockcycles_clear()); // xMOV(ptr32[&cpuRegs.cycle], ecx); // update cycles armAdd(ECX, PTR_CPU(cpuRegs.cycle), scaleblockcycles_clear()); - _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr0, _Rt_); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.PERF.n.pcr0), _Rt_); // xMOV(ptr[&cpuRegs.lastPERFCycle[0]], ecx); armStore(PTR_CPU(cpuRegs.lastPERFCycle[0]), ECX); } @@ -396,7 +396,7 @@ void recMTC0() // xADD(ecx, scaleblockcycles_clear()); // xMOV(ptr32[&cpuRegs.cycle], ecx); // update cycles armAdd(ECX, PTR_CPU(cpuRegs.cycle), scaleblockcycles_clear()); - _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr1, _Rt_); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.PERF.n.pcr1), _Rt_); // xMOV(ptr[&cpuRegs.lastPERFCycle[1]], ecx); armStore(PTR_CPU(cpuRegs.lastPERFCycle[1]), ECX); } @@ -407,7 +407,7 @@ void recMTC0() break; default: - _eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[_Rd_], _Rt_); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.CP0.r[_Rd_]), _Rt_); break; } } diff --git a/app/src/main/cpp/pcsx2/x86/iR5900.h b/app/src/main/cpp/pcsx2/x86/iR5900.h index 3e9c585..c4735b8 100644 --- a/app/src/main/cpp/pcsx2/x86/iR5900.h +++ b/app/src/main/cpp/pcsx2/x86/iR5900.h @@ -108,7 +108,7 @@ extern u32 g_cpuHasConstReg, g_cpuFlushedConstReg; // finds where the GPR is stored and moves lower 32 bits to EAX void _eeMoveGPRtoR(const a64::Register& to, int fromgpr, bool allow_preload = true); -void _eeMoveGPRtoM(uptr to, int fromgpr); // 32-bit only +void _eeMoveGPRtoM(const a64::MemOperand& to, int fromgpr); // 32-bit only void _eeFlushAllDirty(); void _eeOnWriteReg(int reg, int signext); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp index e5830c5..29278af 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp @@ -298,11 +298,11 @@ void _eeMoveGPRtoR(const a64::Register& to, int fromgpr, bool allow_preload) } } -void _eeMoveGPRtoM(uptr to, int fromgpr) +void _eeMoveGPRtoM(const a64::MemOperand& to, int fromgpr) { if (GPR_IS_CONST1(fromgpr)) { // xMOV(ptr32[(u32 *) (to)], g_cpuConstRegs[fromgpr].UL[0]); - armStorePtr(g_cpuConstRegs[fromgpr].UL[0], (u32 *) (to)); + armStorePtr(g_cpuConstRegs[fromgpr].UL[0], to); } else { @@ -320,19 +320,19 @@ void _eeMoveGPRtoM(uptr to, int fromgpr) if (x86reg >= 0) { // xMOV(ptr32[(void*)(to)], xRegister32(x86reg)); - armAsm->Str(a64::WRegister(x86reg), armMemOperandPtr((void*)(to))); + armAsm->Str( a64::WRegister(x86reg), to); } else if (xmmreg >= 0) { // xMOVSS(ptr32[(void*)(to)], xRegisterSSE(xmmreg)); - armAsm->Str(a64::QRegister(xmmreg).S(), armMemOperandPtr((void*)(to))); + armAsm->Str(a64::QRegister(xmmreg).S(), to); } else { // xMOV(eax, ptr32[&cpuRegs.GPR.r[fromgpr].UL[0]]); armLoad(EAX, PTR_CPU(cpuRegs.GPR.r[fromgpr].UL[0])); // xMOV(ptr32[(void*)(to)], eax); - armAsm->Str(EAX, armMemOperandPtr((void*)(to))); + armAsm->Str(EAX, to); } } } @@ -932,7 +932,7 @@ void SetBranchReg(u32 reg) } else { - _eeMoveGPRtoM((uptr)&cpuRegs.pc, reg); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.pc), reg); } } } diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp index 94a6c72..96c94a8 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp @@ -168,7 +168,7 @@ void recJALR() } else { - _eeMoveGPRtoM((uptr)&cpuRegs.pc, _Rs_); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.pc), _Rs_); } } diff --git a/app/src/main/cpp/pcsx2/x86/microVU.h b/app/src/main/cpp/pcsx2/x86/microVU.h index 4441cf8..38f7084 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU.h +++ b/app/src/main/cpp/pcsx2/x86/microVU.h @@ -211,6 +211,8 @@ public: } return thisBlock; } + + typedef u32 (*mVUCall)(u32, void*, void*); __ri microBlock* search(microVU& mVU, microRegInfo* pState) { if (pState->needExactMatch) // Needs Detailed Search (Exact Match of Pipeline State) @@ -218,7 +220,8 @@ public: microBlockLink* prevI = nullptr; for (microBlockLink* linkI = fBlockList; linkI != nullptr; prevI = linkI, linkI = linkI->next) { - if (mVU.compareState(pState, &linkI->block.pState) == 0) +// if (mVU.compareState(pState, &linkI->block.pState) == 0) + if (((mVUCall(mVU.compareStateF)(0, pState, &linkI->block.pState)) == 0)) { if (linkI != fBlockList) { diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl index f52a2de..64a57ae 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl @@ -310,62 +310,58 @@ static void mVUGenerateCopyPipelineState(mV) static void mVUGenerateCompareState(mV) { mVU.compareStateF = armStartBlock(); - { // xMOVAPS (xmm0, ptr32[arg1reg]); - armAsm->Ldr(xmm0, a64::MemOperand(RAX)); + armAsm->Ldr(xmm0, a64::MemOperand(RCX)); // xPCMP.EQD(xmm0, ptr32[arg2reg]); - armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RCX).V4S()); + armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RDX).V4S()); // xMOVAPS (xmm1, ptr32[arg1reg + 0x10]); - armAsm->Ldr(xmm1, a64::MemOperand(RAX, 0x10)); + armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x10)); // xPCMP.EQD(xmm1, ptr32[arg2reg + 0x10]); - armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RCX, 0x10).V4S()); + armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x10).V4S()); // xPAND (xmm0, xmm1); armAsm->And(xmm0.V16B(), xmm0.V16B(), xmm1.V16B()); // xMOVMSKPS(eax, xmm0); - armMOVMSKPS(EDX, xmm0); + armMOVMSKPS(EAX, xmm0); // xXOR (eax, 0xf); - armAsm->Eor(EDX, EDX, 0xf); + armAsm->Eor(EAX, EAX, 0xf); // xForwardJNZ8 exitPoint; a64::Label exitPoint; - armAsm->Cbnz(EDX, &exitPoint); + armAsm->Cbnz(EAX, &exitPoint); // xMOVAPS (xmm0, ptr32[arg1reg + 0x20]); - armAsm->Ldr(xmm0, a64::MemOperand(RAX, 0x20)); + armAsm->Ldr(xmm0, a64::MemOperand(RCX, 0x20)); // xPCMP.EQD(xmm0, ptr32[arg2reg + 0x20]); - armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RCX, 0x20).V4S()); + armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RDX, 0x20).V4S()); // xMOVAPS (xmm1, ptr32[arg1reg + 0x30]); - armAsm->Ldr(xmm1, a64::MemOperand(RAX, 0x30)); + armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x30)); // xPCMP.EQD(xmm1, ptr32[arg2reg + 0x30]); - armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RCX, 0x30).V4S()); + armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x30).V4S()); // xPAND (xmm0, xmm1); armAsm->And(xmm0.V16B(), xmm0.V16B(), xmm1.V16B()); // xMOVAPS (xmm1, ptr32[arg1reg + 0x40]); - armAsm->Ldr(xmm1, a64::MemOperand(RAX, 0x40)); + armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x40)); // xPCMP.EQD(xmm1, ptr32[arg2reg + 0x40]); - armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RCX, 0x40).V4S()); + armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x40).V4S()); // xMOVAPS (xmm2, ptr32[arg1reg + 0x50]); - armAsm->Ldr(xmm2, a64::MemOperand(RAX, 0x50)); + armAsm->Ldr(xmm2, a64::MemOperand(RCX, 0x50)); // xPCMP.EQD(xmm2, ptr32[arg2reg + 0x50]); - armAsm->Cmeq(xmm2.V4S(), xmm2.V4S(), armLoadPtrM(RCX, 0x50).V4S()); + armAsm->Cmeq(xmm2.V4S(), xmm2.V4S(), armLoadPtrM(RDX, 0x50).V4S()); // xPAND (xmm1, xmm2); armAsm->And(xmm1.V16B(), xmm1.V16B(), xmm2.V16B()); // xPAND (xmm0, xmm1); armAsm->And(xmm0.V16B(), xmm0.V16B(), xmm1.V16B()); // xMOVMSKPS(eax, xmm0); - armMOVMSKPS(EDX, xmm0); + armMOVMSKPS(EAX, xmm0); // xXOR(eax, 0xf); - armAsm->Eor(EDX, EDX, 0xf); + armAsm->Eor(EAX, EAX, 0xf); // exitPoint.SetTarget(); armBind(&exitPoint); - - // Result - armAsm->Mov(EAX, EDX); } // xRET(); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Macro.inl b/app/src/main/cpp/pcsx2/x86/microVU_Macro.inl index 377e244..5295944 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Macro.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Macro.inl @@ -5,7 +5,7 @@ extern void _vu0WaitMicro(); extern void _vu0FinishMicro(); -static VURegs& vu0Regs = g_cpuRegistersPack.vuRegs[0]; +//static VURegs& vu0Regs = g_cpuRegistersPack.vuRegs[0]; //------------------------------------------------------------------ // Macro VU - Helper Macros / Functions @@ -72,7 +72,7 @@ void setupMacroOp(int mode, const char* opName) // load denormalized status flag // ideally we'd keep this in a register, but 32-bit... // xMOV(gprF0, ptr32[&vuRegs->VI[REG_STATUS_FLAG].UL]); - armAsm->Ldr(gprF0, armMemOperandPtr(&g_cpuRegistersPack.vuRegs->VI[REG_STATUS_FLAG].UL)); + armAsm->Ldr(gprF0, PTR_CPU(vuRegs[g_cpuRegistersPack.vuRegs->idx].VI[REG_STATUS_FLAG].UL)); } } } @@ -101,7 +101,7 @@ void endMacroOp(int mode) // backup denormalized flags for the next instruction // this is fine, because we'll normalize them again before this reg is accessed // xMOV(ptr32[&vuRegs->VI[REG_STATUS_FLAG].UL], gprF0); - armAsm->Str(gprF0, armMemOperandPtr(&g_cpuRegistersPack.vuRegs->VI[REG_STATUS_FLAG].UL)); + armAsm->Str(gprF0, PTR_CPU(vuRegs[g_cpuRegistersPack.vuRegs->idx].VI[REG_STATUS_FLAG].UL)); } } @@ -489,13 +489,13 @@ static void recCFC2() } const int regt = _allocX86reg(X86TYPE_GPR, _Rt_, MODE_WRITE); + auto regT = a64::XRegister(regt); pxAssert(!GPR_IS_CONST1(_Rt_)); if (_Rd_ == 0) // why would you read vi00? { // xXOR(xRegister32(regt), xRegister32(regt)); - a64::Register reg32 = a64::WRegister(regt); - armAsm->Eor(reg32, reg32, reg32); + armAsm->Eor(regT.W(), regT.W(), regT.W()); } else if (_Rd_ == REG_I) { @@ -503,38 +503,38 @@ static void recCFC2() if (xmmreg >= 0) { // xMOVD(xRegister32(regt), xRegisterSSE(xmmreg)); - armAsm->Fmov(a64::WRegister(regt), a64::QRegister(xmmreg).S()); + armAsm->Fmov(regT.W(), a64::QRegister(xmmreg).S()); // xMOVSX(xRegister64(regt), xRegister32(regt)); - armAsm->Sxtw(a64::XRegister(regt), a64::WRegister(regt)); + armAsm->Sxtw(regT.X(), regT.W()); } else { // xMOVSX(xRegister64(regt), ptr32[&vu0Regs.VI[_Rd_].UL]); - armAsm->Ldrsw(a64::XRegister(regt), PTR_CPU(vuRegs[0].VI[_Rd_].UL)); + armAsm->Ldrsw(regT.X(), PTR_CPU(vuRegs[0].VI[_Rd_].UL)); } } else if (_Rd_ == REG_R) { // xMOVSX(xRegister64(regt), ptr32[&vu0Regs.VI[REG_R].UL]); - armAsm->Ldrsw(a64::XRegister(regt), PTR_CPU(vuRegs[0].VI[REG_R].UL)); + armAsm->Ldrsw(regT.X(), PTR_CPU(vuRegs[0].VI[REG_R].UL)); // xAND(xRegister64(regt), 0x7FFFFF); - armAsm->And(a64::XRegister(regt), a64::XRegister(regt), 0x7FFFFF); + armAsm->And(regT.X(), regT.X(), 0x7FFFFF); } else if (_Rd_ >= REG_STATUS_FLAG) // FixMe: Should R-Reg have upper 9 bits 0? { // xMOVSX(xRegister64(regt), ptr32[&vu0Regs.VI[_Rd_].UL]); - armAsm->Ldrsw(a64::XRegister(regt), PTR_CPU(vuRegs[0].VI[_Rd_].UL)); + armAsm->Ldrsw(regT.X(), PTR_CPU(vuRegs[0].VI[_Rd_].UL)); } else { const int vireg = _allocIfUsedVItoX86(_Rd_, MODE_READ); if (vireg >= 0) { // xMOVZX(xRegister32(regt), xRegister16(vireg)); - armAsm->Uxth(a64::WRegister(regt), a64::WRegister(vireg)); + armAsm->Uxth(regT.W(), a64::WRegister(vireg)); } else { // xMOVZX(xRegister32(regt), ptr16[&vu0Regs.VI[_Rd_].UL]); - armAsm->Ldrh(a64::WRegister(regt), PTR_CPU(vuRegs[0].VI[_Rd_].UL)); + armAsm->Ldrh(regT.W(), PTR_CPU(vuRegs[0].VI[_Rd_].UL)); } } } @@ -589,17 +589,18 @@ static void recCTC2() } const int xmmtemp = _allocTempXMMreg(XMMT_INT); + auto regQ = a64::QRegister(xmmtemp); //Need to update the sticky flags for microVU // mVUallocSFLAGd(&vu0Regs.VI[REG_STATUS_FLAG].UL); mVUallocSFLAGd(PTR_CPU(vuRegs[0].VI[REG_STATUS_FLAG].UL)); // xMOVDZX(xRegisterSSE(xmmtemp), eax); // TODO(Stenzek): This can be a broadcast. - armAsm->Fmov(a64::QRegister(xmmtemp).S(), EAX); + armAsm->Fmov(regQ.S(), EAX); // xSHUF.PS(xRegisterSSE(xmmtemp), xRegisterSSE(xmmtemp), 0); - armSHUFPS(a64::QRegister(xmmtemp), a64::QRegister(xmmtemp), 0); + armSHUFPS(regQ, regQ, 0); // Make sure the values are everywhere the need to be // xMOVAPS(ptr128[&vu0Regs.micro_statusflags], xRegisterSSE(xmmtemp)); - armAsm->Str(a64::QRegister(xmmtemp).Q(), PTR_CPU(vuRegs[0].micro_statusflags)); + armAsm->Str(regQ.Q(), PTR_CPU(vuRegs[0].micro_statusflags)); _freeXMMreg(xmmtemp); break; } @@ -624,16 +625,17 @@ static void recCTC2() } const int flagreg = _allocX86reg(X86TYPE_TEMP, 0, MODE_CALLEESAVED); - _eeMoveGPRtoR(a64::WRegister(flagreg), _Rt_); + auto regFlag = a64::WRegister(flagreg); + _eeMoveGPRtoR(regFlag, _Rt_); iFlushCall(FLUSH_FREE_VU0); TEST_FBRST_RESET(flagreg, vu0ResetRegs, 0); TEST_FBRST_RESET(flagreg, vu1ResetRegs, 1); // xAND(xRegister32(flagreg), 0x0C0C); - armAsm->And(a64::WRegister(flagreg), a64::WRegister(flagreg), 0x0C0C); + armAsm->And(regFlag, regFlag, 0x0C0C); // xMOV(ptr32[&vu0Regs.VI[REG_FBRST].UL], xRegister32(flagreg)); - armAsm->Str(a64::WRegister(flagreg), PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)); + armAsm->Str(regFlag, PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)); _freeX86reg(flagreg); } break; @@ -754,7 +756,7 @@ static void recCTC2() } else { - _eeMoveGPRtoM((uptr)&vu0Regs.VI[_Rd_].UL, _Rt_); + _eeMoveGPRtoM(PTR_CPU(vuRegs[0].VI[_Rd_].UL), _Rt_); } } break; diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl index f8ab5a5..2f15850 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl @@ -62,7 +62,7 @@ void mVUloadReg(const xmm& reg, const a64::MemOperand& ptr, int xyzw) void mVUloadIreg(const xmm& reg, int xyzw, VURegs* vuRegs) { // xMOVSSZX(reg, ptr32[&vuRegs->VI[REG_I].UL]); - armAsm->Ldr(reg, armMemOperandPtr(&vuRegs->VI[REG_I].UL)); + armAsm->Ldr(reg, PTR_CPU(vuRegs[g_cpuRegistersPack.vuRegs->idx].VI[REG_I].UL)); if (!_XYZWss(xyzw)) { // xSHUF.PS(reg, reg, 0); armSHUFPS(reg, reg, 0); @@ -402,6 +402,17 @@ __fi void mVUaddrFix(mV, const a64::Register& gprReg) // xAND(xRegister32(gprReg.Id), 0x3f); // ToDo: theres a potential problem if VU0 overrides VU1's VF0/VI0 regs! armAsm->And(reg32, reg32, 0x3f); // xADD(gprReg, (u128*)VU1.VF - (u128*)VU0.Mem); + +// armAsm->Ldr(RAX, PTR_CPU(vuRegs[0].Mem)); +// armAsm->Add(gprReg, gprReg, EEX); + +// armAsm->Ldr(RCX, PTR_CPU(vuRegs[1].VF)); +// armAsm->Sub(gprReg, gprReg, EEX); +// PTR_CPU(vuRegs[0].Mem); + +// armAsm->Sub(REX, RCX, RAX); +// armAsm->Add(gprReg, gprReg, REX); + armAsm->Add(gprReg, gprReg, (u128*)VU1.VF - (u128*)VU0.Mem); // jmpB.SetTarget(); armBind(&jmpB);