void _deleteEEreg(int reg, int flush) { if( !reg ) return; if( flush && GPR_IS_CONST1(reg) ) { _flushConstReg(reg); } GPR_DEL_CONST(reg); _deleteGPRtoXMMreg(reg, flush ? 0 : 2); _deleteMMXreg(MMX_GPR+reg, flush ? 0 : 2); }
void _flushEEreg(int reg) { if (!reg) return; if (GPR_IS_CONST1(reg)) { _flushConstReg(reg); return; } _deleteGPRtoXMMreg(reg, 1); _deleteMMXreg(MMX_GPR + reg, 1); }
int _allocGPRtoXMMreg(int xmmreg, int gprreg, int mode) { int i; for (i=0; (uint)i<iREGCNT_XMM; i++) { if (xmmregs[i].inuse == 0) continue; if (xmmregs[i].type != XMMTYPE_GPRREG) continue; if (xmmregs[i].reg != gprreg) continue; pxAssert( _checkMMXreg(MMX_GPR|gprreg, mode) == -1 ); g_xmmtypes[i] = XMMT_INT; if (!(xmmregs[i].mode & MODE_READ) && (mode & MODE_READ)) { if (gprreg == 0 ) { SSEX_PXOR_XMM_to_XMM(i, i); } else { //pxAssert( !(g_cpuHasConstReg & (1<<gprreg)) || (g_cpuFlushedConstReg & (1<<gprreg)) ); _flushConstReg(gprreg); SSEX_MOVDQA_M128_to_XMM(i, (uptr)&cpuRegs.GPR.r[gprreg].UL[0]); } xmmregs[i].mode |= MODE_READ; } if ((mode & MODE_WRITE) && (gprreg < 32)) { g_cpuHasConstReg &= ~(1<<gprreg); //pxAssert( !(g_cpuHasConstReg & (1<<gprreg)) ); } xmmregs[i].counter = g_xmmAllocCounter++; // update counter xmmregs[i].needed = 1; xmmregs[i].mode|= mode; return i; } // currently only gpr regs are const // fixme - do we really need to execute this both here and in the loop? if ((mode & MODE_WRITE) && gprreg < 32) { //pxAssert( !(g_cpuHasConstReg & (1<<gprreg)) ); g_cpuHasConstReg &= ~(1<<gprreg); } if (xmmreg == -1) xmmreg = _getFreeXMMreg(); g_xmmtypes[xmmreg] = XMMT_INT; xmmregs[xmmreg].inuse = 1; xmmregs[xmmreg].type = XMMTYPE_GPRREG; xmmregs[xmmreg].reg = gprreg; xmmregs[xmmreg].mode = mode; xmmregs[xmmreg].needed = 1; xmmregs[xmmreg].counter = g_xmmAllocCounter++; if (mode & MODE_READ) { if (gprreg == 0 ) { SSEX_PXOR_XMM_to_XMM(xmmreg, xmmreg); } else { // DOX86 int mmxreg; if (mode & MODE_READ) _flushConstReg(gprreg); mmxreg = _checkMMXreg(MMX_GPR+gprreg, 0); if (mmxreg >= 0 ) { // transfer SetMMXstate(); SSE2_MOVQ2DQ_MM_to_XMM(xmmreg, mmxreg); SSE2_PUNPCKLQDQ_XMM_to_XMM(xmmreg, xmmreg); SSE2_PUNPCKHQDQ_M128_to_XMM(xmmreg, (u32)&cpuRegs.GPR.r[gprreg].UL[0]); if (mmxregs[mmxreg].mode & MODE_WRITE ) { // instead of setting to write, just flush to mem if (!(mode & MODE_WRITE)) { SetMMXstate(); MOVQRtoM((u32)&cpuRegs.GPR.r[gprreg].UL[0], mmxreg); } //xmmregs[xmmreg].mode |= MODE_WRITE; } // don't flush mmxregs[mmxreg].inuse = 0; } else SSEX_MOVDQA_M128_to_XMM(xmmreg, (uptr)&cpuRegs.GPR.r[gprreg].UL[0]); } } else _deleteMMXreg(MMX_GPR+gprreg, 0); return xmmreg; }