#define _signExtend16To32(__v) ((uint32)(sint32)(sint16)(__v)) // store #define DSI_EXIT() \ if constexpr(ppcItpCtrl::allowDSI) \ { \ if (hCPU->memoryException) \ { \ hCPU->memoryException = false; \ return; \ } \ } static void PPCInterpreter_STW(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); if (rA != 0) { ppcItpCtrl::ppcMem_writeDataU32(hCPU, hCPU->gpr[rA] + imm, hCPU->gpr[rS]); } else { PPC_ASSERT(true); } PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STWU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); ppcItpCtrl::ppcMem_writeDataU32(hCPU, hCPU->gpr[rA] + imm, hCPU->gpr[rS]); // check for rA != 0 ? hCPU->gpr[rA] += imm; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STWX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->gpr[rS]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STWCX(PPCInterpreter_t* hCPU, uint32 Opcode) { // http://www.ibm.com/developerworks/library/pa-atom/ sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); uint32 ea = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; // check if we hold a reservation for the memory location // todo - this isnt accurate. STWCX can succeed even with a different EA if the reserved value remained untouched if (hCPU->reservedMemAddr == ea) { uint32be reservedValue = hCPU->reservedMemValue; // this is the value we expect in memory (if it does not match, STWCX fails) std::atomic* wordPtr; if constexpr(ppcItpCtrl::allowSupervisorMode) { wordPtr = _rawPtrToAtomic((uint32be*)(memory_base + ppcItpCtrl::ppcMem_translateVirtualDataToPhysicalAddr(hCPU, ea))); DSI_EXIT(); } else { wordPtr = _rawPtrToAtomic((uint32be*)memory_getPointerFromVirtualOffset(ea)); } uint32be newValue = hCPU->gpr[rS]; if (!wordPtr->compare_exchange_strong(reservedValue, newValue)) { // failed ppc_setCRBit(hCPU, CR_BIT_LT, 0); ppc_setCRBit(hCPU, CR_BIT_GT, 0); ppc_setCRBit(hCPU, CR_BIT_EQ, 0); } else { // success, new value has been written ppc_setCRBit(hCPU, CR_BIT_LT, 0); ppc_setCRBit(hCPU, CR_BIT_GT, 0); ppc_setCRBit(hCPU, CR_BIT_EQ, 1); } cemu_assert_debug(hCPU->xer_so <= 1); ppc_setCRBit(hCPU, CR_BIT_SO, hCPU->xer_so); // remove reservation hCPU->reservedMemAddr = 0; hCPU->reservedMemValue = 0; } else { // failed ppc_setCRBit(hCPU, CR_BIT_LT, 0); ppc_setCRBit(hCPU, CR_BIT_GT, 0); ppc_setCRBit(hCPU, CR_BIT_EQ, 0); } PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STWUX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->gpr[rS]); if (rA) hCPU->gpr[rA] += hCPU->gpr[rB]; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STWBRX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], _swapEndianU32(hCPU->gpr[rS])); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STMW(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rS, rA; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); uint32 ea = (rA ? hCPU->gpr[rA] : 0) + imm; while (rS <= 31) { ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea, hCPU->gpr[rS]); rS++; ea += 4; } PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STH(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint16)hCPU->gpr[rS]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STHU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint16)hCPU->gpr[rS]); if (rA) hCPU->gpr[rA] += imm; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STHX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint16)hCPU->gpr[rS]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STHUX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint16)hCPU->gpr[rS]); if (rA) hCPU->gpr[rA] += hCPU->gpr[rB]; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STHBRX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], _swapEndianU16((uint16)hCPU->gpr[rS])); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STB(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint8)hCPU->gpr[rS]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STBU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); ppcItpCtrl::ppcMem_writeDataU8(hCPU, hCPU->gpr[rA] + imm, (uint8)hCPU->gpr[rS]); hCPU->gpr[rA] += imm; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STBX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint8)hCPU->gpr[rS]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STBUX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint8)hCPU->gpr[rS]); if (rA) hCPU->gpr[rA] += hCPU->gpr[rB]; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STSWI(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, nb; PPC_OPC_TEMPL_X(Opcode, rS, rA, nb); if (nb == 0) nb = 32; uint32 ea = rA ? hCPU->gpr[rA] : 0; uint32 r = 0; int i = 0; while (nb > 0) { if (i == 0) { r = rS < 32 ? hCPU->gpr[rS] : 0; // what happens if rS is out of bounds? rS++; rS %= 32; i = 4; } ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea, (r >> 24)); r <<= 8; ea++; i--; nb--; } PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STSWX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); sint32 nb = hCPU->spr.XER&0x7F; if (nb == 0) { PPCInterpreter_nextInstruction(hCPU); return; } uint32 ea = rA ? hCPU->gpr[rA] : 0; ea += hCPU->gpr[rB]; uint32 r = 0; int i = 0; while (nb > 0) { if (i == 0) { r = rS < 32 ? hCPU->gpr[rS] : 0; // what happens if rS is out of bounds? rS++; rS %= 32; i = 4; } ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea, (r >> 24)); r <<= 8; ea++; i--; nb--; } PPCInterpreter_nextInstruction(hCPU); } // load static void PPCInterpreter_LWZ(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); uint32 v = ppcItpCtrl::ppcMem_readDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm); DSI_EXIT(); hCPU->gpr[rD] = v; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LWZU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); hCPU->gpr[rA] += imm; hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU32(hCPU, hCPU->gpr[rA]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LMW(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rD, rA; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); uint32 ea = (rA ? hCPU->gpr[rA] : 0) + imm; while (rD <= 31) { hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU32(hCPU, ea); rD++; ea += 4; } PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LWZX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LWZXU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); uint32 ea = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU32(hCPU, ea); if (rA && rA != rD) hCPU->gpr[rA] = ea; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LWBRX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); hCPU->gpr[rD] = CPU_swapEndianU32(ppcItpCtrl::ppcMem_readDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB])); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LWARX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); uint32 ea = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU32(hCPU, ea); // set reservation hCPU->reservedMemAddr = ea; hCPU->reservedMemValue = hCPU->gpr[rD]; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHZ(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHZU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); // FIXME: rA!=0 hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU16(hCPU, hCPU->gpr[rA] + imm); hCPU->gpr[rA] += imm; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHZX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHZUX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); uint32 ea = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU16(hCPU, ea); if (rA && rA != rD) hCPU->gpr[rA] = ea; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHBRX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); hCPU->gpr[rD] = CPU_swapEndianU16(ppcItpCtrl::ppcMem_readDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB])); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHA(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm); hCPU->gpr[rD] = _signExtend16To32(hCPU->gpr[rD]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHAU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm); if (rA && rA != rD) hCPU->gpr[rA] += imm; hCPU->gpr[rD] = _signExtend16To32(hCPU->gpr[rD]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHAUX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); uint32 ea = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU16(hCPU, ea); if (rA && rA != rD) hCPU->gpr[rA] = ea; hCPU->gpr[rD] = _signExtend16To32(hCPU->gpr[rD]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LHAX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rS, rB; PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); hCPU->gpr[rS] = ppcItpCtrl::ppcMem_readDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]); hCPU->gpr[rS] = _signExtend16To32(hCPU->gpr[rS]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LBZ(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LBZX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LBZXU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); uint32 ea = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; hCPU->gpr[rD] = ppcItpCtrl::ppcMem_readDataU8(hCPU, ea); if (rA && rA != rD) hCPU->gpr[rA] = ea; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LBZU(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, rD, rA, imm); PPC_ASSERT(rA == 0); uint8 r; uint32 ea = hCPU->gpr[rA] + imm; hCPU->gpr[rA] = ea; r = ppcItpCtrl::ppcMem_readDataU8(hCPU, ea); hCPU->gpr[rD] = r; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LSWI(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, nb; PPC_OPC_TEMPL_X(Opcode, rD, rA, nb); if (nb == 0) nb = 32; uint32 ea = rA ? hCPU->gpr[rA] : 0; uint32 r = 0; int i = 4; uint8 v; while (nb>0) { if (i == 0) { i = 4; if(rD < 32) hCPU->gpr[rD] = r; rD++; rD %= 32; r = 0; } v = ppcItpCtrl::ppcMem_readDataU8(hCPU, ea); r <<= 8; r |= v; ea++; i--; nb--; } while (i) { r <<= 8; i--; } if(rD < 32) hCPU->gpr[rD] = r; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LSWX(PPCInterpreter_t* hCPU, uint32 Opcode) { sint32 rA, rD, rB; PPC_OPC_TEMPL_X(Opcode, rD, rA, rB); // byte count comes from XER uint32 nb = (hCPU->spr.XER>>0)&0x7F; if (nb == 0) { PPCInterpreter_nextInstruction(hCPU); return; // no-op } uint32 ea = rA ? hCPU->gpr[rA] : 0; ea += hCPU->gpr[rB]; uint32 r = 0; int i = 4; uint8 v; while (nb>0) { if (i == 0) { i = 4; if(rD < 32) hCPU->gpr[rD] = r; rD++; rD %= 32; r = 0; } v = ppcItpCtrl::ppcMem_readDataU8(hCPU, ea); r <<= 8; r |= v; ea++; i--; nb--; } while (i) { r <<= 8; i--; } if(rD < 32) hCPU->gpr[rD] = r; PPCInterpreter_nextInstruction(hCPU); } // floating point load static void PPCInterpreter_LFS(PPCInterpreter_t* hCPU, uint32 Opcode) //Copied { FPUCheckAvailable(); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, frD, rA, imm); uint64 val; //*(uint32*)&Val = ppcItpCtrl::ppcMem_readDataU32(hCPU, (rA?hCPU->gpr[rA]:0)+imm); val = ppcItpCtrl::ppcMem_readDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm); if (PPC_LSQE) hCPU->fpr[frD].fp0int = hCPU->fpr[frD].fp1int = val; else hCPU->fpr[frD].fp0int = val; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LFSX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frD, rB; PPC_OPC_TEMPL_X(Opcode, frD, rA, rB); uint64 val; val = ppcItpCtrl::ppcMem_readDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]); if (PPC_LSQE) hCPU->fpr[frD].fp0int = hCPU->fpr[frD].fp1int = val; else hCPU->fpr[frD].fp0int = val; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LFSUX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frD, rB; PPC_OPC_TEMPL_X(Opcode, frD, rA, rB); uint64 Val; //*(uint32*)&Val = ppcItpCtrl::ppcMem_readDataU32(hCPU, (rA?hCPU->gpr[rA]:0)+hCPU->gpr[rB]); Val = ppcItpCtrl::ppcMem_readDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]); if (rA) hCPU->gpr[rA] += hCPU->gpr[rB]; if (PPC_LSQE) hCPU->fpr[frD].fp0int = hCPU->fpr[frD].fp1int = Val; else hCPU->fpr[frD].fp0int = Val;//ppcItpCtrl::ppcMem_readDataFloat((rA?hCPU->gpr[rA]:0)+hCPU->gpr[rB]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LFSU(PPCInterpreter_t* hCPU, uint32 Opcode) //Copied { FPUCheckAvailable(); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, frD, rA, imm); uint64 Val; //(uint32*)&Val = ppcItpCtrl::ppcMem_readDataU32(hCPU, (rA?hCPU->gpr[rA]:0)+imm); Val = ppcItpCtrl::ppcMem_readDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm); if (PPC_LSQE) hCPU->fpr[frD].fp0int = hCPU->fpr[frD].fp1int = Val; else hCPU->fpr[frD].fp0int = Val; if (rA) hCPU->gpr[rA] += imm; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LFD(PPCInterpreter_t* hCPU, uint32 Opcode) //Copied { FPUCheckAvailable(); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, frD, rA, imm); hCPU->fpr[frD].fpr = ppcItpCtrl::ppcMem_readDataDouble(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm);//ppcItpCtrl::ppcMem_readDataQUAD((rA?hCPU->gpr[rA]:0)+imm); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LFDU(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, frD, rA, imm); hCPU->fpr[frD].fpr = ppcItpCtrl::ppcMem_readDataDouble(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm);//ppcItpCtrl::ppcMem_readDataQUAD((rA?hCPU->gpr[rA]:0)+imm); if (rA) hCPU->gpr[rA] += imm; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LFDX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frD, rB; PPC_OPC_TEMPL_X(Opcode, frD, rA, rB); hCPU->fpr[frD].fpr = ppcItpCtrl::ppcMem_readDataDouble(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_LFDUX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frD, rB; PPC_OPC_TEMPL_X(Opcode, frD, rA, rB); hCPU->fpr[frD].fpr = ppcItpCtrl::ppcMem_readDataDouble(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]); if (rA) hCPU->gpr[rA] += hCPU->gpr[rB]; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STFS(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, frD, rA, imm); if (PPC_LSQE) ppcItpCtrl::ppcMem_writeDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, hCPU->fpr[frD].fp0int); else ppcItpCtrl::ppcMem_writeDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, hCPU->fpr[frD].fp0int); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STFSU(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, frD, rA, imm); if (PPC_LSQE) ppcItpCtrl::ppcMem_writeDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, hCPU->fpr[frD].fp0int); else ppcItpCtrl::ppcMem_writeDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, hCPU->fpr[frD].fp0int); if (rA) hCPU->gpr[rA] += imm; PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STFSX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frS, rB; PPC_OPC_TEMPL_X(Opcode, frS, rA, rB); if (PPC_LSQE) ppcItpCtrl::ppcMem_writeDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->fpr[frS].fp0int); else ppcItpCtrl::ppcMem_writeDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->fpr[frS].fp0int); PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_STFSUX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); int rA, frS, rB; PPC_OPC_TEMPL_X(Opcode, frS, rA, rB); if (PPC_LSQE) ppcItpCtrl::ppcMem_writeDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->fpr[frS].fp0int); else ppcItpCtrl::ppcMem_writeDataFloatEx(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->fpr[frS].fp0int); if (rA) hCPU->gpr[rA] += hCPU->gpr[rB]; } static void PPCInterpreter_STFD(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); int rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, frD, rA, imm); ppcItpCtrl::ppcMem_writeDataDouble(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, hCPU->fpr[frD].fpr); // debug output #ifdef __DEBUG_OUTPUT_INSTRUCTION debug_printf("STFD f%d, %d(r%d)\n", frD, imm, rA); #endif } static void PPCInterpreter_STFDU(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); int rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(Opcode, frD, rA, imm); if (rA) { hCPU->gpr[rA] += imm; } else { PPC_ASSERT(true); } ppcItpCtrl::ppcMem_writeDataDouble(hCPU, hCPU->gpr[rA], hCPU->fpr[frD].fpr); // debug output #ifdef __DEBUG_OUTPUT_INSTRUCTION debug_printf("STFD f%d, %d(r%d)\n", frD, imm, rA); #endif } static void PPCInterpreter_STFDX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); int rA, frS, rB; PPC_OPC_TEMPL_X(Opcode, frS, rA, rB); ppcItpCtrl::ppcMem_writeDataDouble(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->fpr[frS].fpr); // debug output #ifdef __DEBUG_OUTPUT_INSTRUCTION debug_printf("STFD f%d, r%d+r%d\n", frS, rA, rB); #endif } static void PPCInterpreter_STFDUX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); int rA, frS, rB; PPC_OPC_TEMPL_X(Opcode, frS, rA, rB); if (rA == 0) { ppcItpCtrl::ppcMem_writeDataDouble(hCPU, hCPU->gpr[rB], hCPU->fpr[frS].fpr); } else { hCPU->gpr[rA] += hCPU->gpr[rB]; ppcItpCtrl::ppcMem_writeDataDouble(hCPU, hCPU->gpr[rA], hCPU->fpr[frS].fpr); } } static void PPCInterpreter_STFIWX(PPCInterpreter_t* hCPU, uint32 Opcode) { FPUCheckAvailable(); sint32 rA, frS, rB; PPC_OPC_TEMPL_X(Opcode, frS, rA, rB); uint32 val = (uint32)hCPU->fpr[frS].fp0int; ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], val); // next instruction PPCInterpreter_nextInstruction(hCPU); } // paired single // ST_TYPE: // 4 - uint8 // 5 - uint16 // 6 - sint8 // 7 - sint16 // 0 - float32 #define LD_SCALE(n) ((hCPU->spr.UGQR[0+n] >> 24) & 0x3f) #define LD_TYPE(n) ((hCPU->spr.UGQR[0+n] >> 16) & 7) #define ST_SCALE(n) ((hCPU->spr.UGQR[0+n] >> 8) & 0x3f) #define ST_TYPE(n) ((hCPU->spr.UGQR[0+n] ) & 7) #define PSW (opcode & 0x8000) #define PSI ((opcode >> 12) & 7) #define PSWX (opcode & (1<<(7+3))) #define PSIX ((opcode >> 7) & 7) static void PPCInterpreter_PSQ_ST(PPCInterpreter_t* hCPU, unsigned int opcode) { FPUCheckAvailable(); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm); uint32 ea = _uint32_fastSignExtend(imm, 11); ea += (rA ? hCPU->gpr[rA] : 0); sint32 type = ST_TYPE(PSI); uint8 scale = (uint8)ST_SCALE(PSI); if (opcode & 0x8000) // PSW? { if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); } else { if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea + 1, quantize((float)hCPU->fpr[frD].fp1, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, ea + 2, quantize((float)hCPU->fpr[frD].fp1, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 4, quantize((float)hCPU->fpr[frD].fp1, type, scale)); } PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_PSQ_STU(PPCInterpreter_t* hCPU, unsigned int opcode) { FPUCheckAvailable(); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm); uint32 ea = _uint32_fastSignExtend(imm, 11); if (ea & 0x800) ea |= 0xfffff000; ea += (rA ? hCPU->gpr[rA] : 0); if (rA) hCPU->gpr[rA] = ea; sint32 type = ST_TYPE((opcode >> 12) & 0x7); uint8 scale = (uint8)ST_SCALE(PSI); if (opcode & 0x8000) //PSW? { if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); } else { if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea, quantize((float)hCPU->fpr[frD].fp0, type, scale)); if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea + 1, quantize((float)hCPU->fpr[frD].fp1, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, ea + 2, quantize((float)hCPU->fpr[frD].fp1, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 4, quantize((float)hCPU->fpr[frD].fp1, type, scale)); } PPCInterpreter_nextInstruction(hCPU); } static void PPCInterpreter_PSQ_STX(PPCInterpreter_t* hCPU, unsigned int opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); sint32 frD; uint32 rA, rB; frD = (opcode >> (31 - 10)) & 0x1F; rA = (opcode >> (31 - 15)) & 0x1F; rB = (opcode >> (31 - 20)) & 0x1F; uint32 EA = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; sint32 type = ST_TYPE(PSIX); uint8 scale = (uint8)ST_SCALE(PSIX); if (PSWX) { if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, EA, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, EA, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, EA, quantize((float)hCPU->fpr[frD].fp0, type, scale)); } else { if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, EA, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, EA, quantize((float)hCPU->fpr[frD].fp0, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, EA, quantize((float)hCPU->fpr[frD].fp0, type, scale)); if ((type == 4) || (type == 6)) ppcItpCtrl::ppcMem_writeDataU8(hCPU, EA + 1, quantize((float)hCPU->fpr[frD].fp1, type, scale)); else if ((type == 5) || (type == 7)) ppcItpCtrl::ppcMem_writeDataU16(hCPU, EA + 2, quantize((float)hCPU->fpr[frD].fp1, type, scale)); else ppcItpCtrl::ppcMem_writeDataU32(hCPU, EA + 4, quantize((float)hCPU->fpr[frD].fp1, type, scale)); } } static void PPCInterpreter_PSQ_L(PPCInterpreter_t* hCPU, unsigned int opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); sint32 rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm); uint32 EA, data0 = 0, data1 = 0; sint32 type = LD_TYPE(PSI); uint8 scale = (uint8)LD_SCALE(PSI); EA = _uint32_fastSignExtend(opcode, 11); if (rA) EA += hCPU->gpr[rA]; if (opcode & 0x8000) { if ((type == 4) || (type == 6)) *(uint8*)&data0 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA); else if ((type == 5) || (type == 7)) *(uint16*)&data0 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA); else *(uint32*)&data0 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA); if (type == 6) if (data0 & 0x80) data0 |= 0xffffff00; if (type == 7) if (data0 & 0x8000) data0 |= 0xffff0000; hCPU->fpr[frD].fp0 = (double)dequantize(data0, type, scale); hCPU->fpr[frD].fp1 = 1.0f; } else { if ((type == 4) || (type == 6)) { *(uint8*)&data0 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA); *(uint8*)&data1 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA + 1); } else if ((type == 5) || (type == 7)) { *(uint16*)&data0 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA); *(uint16*)&data1 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA + 2); } else { *(uint32*)&data0 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA); *(uint32*)&data1 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA + 4); } if (type == 6) { if (data0 & 0x80) data0 |= 0xffffff00; if (data1 & 0x80) data1 |= 0xffffff00; } if (type == 7) { if (data0 & 0x8000) data0 |= 0xffff0000; if (data1 & 0x8000) data1 |= 0xffff0000; } hCPU->fpr[frD].fp0 = (double)dequantize(data0, type, scale); hCPU->fpr[frD].fp1 = (double)dequantize(data1, type, scale); } } static void PPCInterpreter_PSQ_LU(PPCInterpreter_t* hCPU, unsigned int opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); int rA, frD; uint32 imm; PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm); uint32 EA = opcode & 0xfff, data0 = 0, data1 = 0; sint32 type = LD_TYPE(PSI); uint8 scale = (uint8)LD_SCALE(PSI); if (EA & 0x800) EA |= 0xfffff000; if (rA) { EA += hCPU->gpr[rA]; hCPU->gpr[rA] = EA; } if (opcode & 0x8000) { if ((type == 4) || (type == 6)) *(uint8*)&data0 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA); else if ((type == 5) || (type == 7)) *(uint16*)&data0 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA); else *(uint32*)&data0 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA); if (type == 6) if (data0 & 0x80) data0 |= 0xffffff00; if (type == 7) if (data0 & 0x8000) data0 |= 0xffff0000; hCPU->fpr[frD].fp0 = (double)dequantize(data0, type, scale); hCPU->fpr[frD].fp1 = 1.0f; } else { if ((type == 4) || (type == 6)) *(uint8*)&data0 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA); else if ((type == 5) || (type == 7)) *(uint16*)&data0 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA); else *(uint32*)&data0 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA); if (type == 6) if (data0 & 0x80) data0 |= 0xffffff00; if (type == 7) if (data0 & 0x8000) data0 |= 0xffff0000; if ((type == 4) || (type == 6)) *(uint8*)&data1 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA + 1); else if ((type == 5) || (type == 7)) *(uint16*)&data1 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA + 2); else *(uint32*)&data1 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA + 4); if (type == 6) if (data1 & 0x80) data1 |= 0xffffff00; if (type == 7) if (data1 & 0x8000) data1 |= 0xffff0000; hCPU->fpr[frD].fp0 = (double)dequantize(data0, type, scale); hCPU->fpr[frD].fp1 = (double)dequantize(data1, type, scale); } } static void PPCInterpreter_PSQ_LX(PPCInterpreter_t* hCPU, unsigned int opcode) { FPUCheckAvailable(); // next instruction PPCInterpreter_nextInstruction(hCPU); sint32 frD; uint32 rA, rB; frD = (opcode >> (32 - 11)) & 0x1F; rA = (opcode >> (32 - 16)) & 0x1F; rB = (opcode >> (32 - 21)) & 0x1F; uint32 EA = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; uint32 data0 = 0, data1 = 0; sint32 type = LD_TYPE(PSIX); uint8 scale = (uint8)LD_SCALE(PSIX); if (PSWX) { if ((type == 4) || (type == 6)) *(uint8*)&data0 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA); else if ((type == 5) || (type == 7)) *(uint16*)&data0 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA); else *(uint32*)&data0 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA); if (type == 6) if (data0 & 0x80) data0 |= 0xffffff00; if (type == 7) if (data0 & 0x8000) data0 |= 0xffff0000; hCPU->fpr[frD].fp0 = (double)dequantize(data0, type, scale); hCPU->fpr[frD].fp1 = 1.0f; } else { if ((type == 4) || (type == 6)) *(uint8*)&data0 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA); else if ((type == 5) || (type == 7)) *(uint16*)&data0 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA); else *(uint32*)&data0 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA); if (type == 6) if (data0 & 0x80) data0 |= 0xffffff00; if (type == 7) if (data0 & 0x8000) data0 |= 0xffff0000; if ((type == 4) || (type == 6)) *(uint8*)&data1 = ppcItpCtrl::ppcMem_readDataU8(hCPU, EA + 1); else if ((type == 5) || (type == 7)) *(uint16*)&data1 = ppcItpCtrl::ppcMem_readDataU16(hCPU, EA + 2); else *(uint32*)&data1 = ppcItpCtrl::ppcMem_readDataU32(hCPU, EA + 4); if (type == 6) if (data1 & 0x80) data1 |= 0xffffff00; if (type == 7) if (data1 & 0x8000) data1 |= 0xffff0000; hCPU->fpr[frD].fp0 = (double)dequantize(data0, type, scale); hCPU->fpr[frD].fp1 = (double)dequantize(data1, type, scale); } } // misc static void PPCInterpreter_DCBZ(PPCInterpreter_t* hCPU, uint32 Opcode) { int rA, rB; rA = (Opcode >> (31 - 15)) & 0x1F; rB = (Opcode >> (31 - 20)) & 0x1F; uint32 ea = (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB]; ea &= ~31; if constexpr(ppcItpCtrl::allowSupervisorMode) { // todo - optimize ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 0, 0); DSI_EXIT(); ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 4, 0); ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 8, 0); ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 12, 0); ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 16, 0); ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 20, 0); ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 24, 0); ppcItpCtrl::ppcMem_writeDataU32(hCPU, ea + 28, 0); } else { memset((void*)memory_getPointerFromVirtualOffset(ea), 0x00, 0x20); } // debug output #ifdef __DEBUG_OUTPUT_INSTRUCTION debug_printf("DCBZ\n"); #endif // next instruction PPCInterpreter_nextInstruction(hCPU); }