Some cleanup around iCore.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1587 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-07-30 22:41:36 +00:00
parent 3d18ddf16b
commit d1f8bf4d71
6 changed files with 155 additions and 95 deletions

View File

@ -41,7 +41,7 @@ enum gifstate_t
// Should be a gifstate_t rather then int, but I don't feel like possibly interfering with savestates right now.
static int gifstate = GIF_STATE_READY;
static u64 s_gstag = 0; // used for querying the last tag
//static u64 s_gstag = 0; // used for querying the last tag
// This should be a bool, as should the return value of hwDmacSrcChainWithStack.
// Next time I feel like breaking the save state, it will be. --arcum42

View File

@ -667,7 +667,7 @@ void psxHwWrite8(u32 add, u8 value) {
case 0x1f80380c:
{
bool flush = false;
//bool flush = false;
// Terminate lines on CR or full buffers, and ignore \n's if the string contents
// are empty (otherwise terminate on \n too!)

View File

@ -99,7 +99,7 @@ int _getFreeXMMreg()
for (i=0; i<iREGCNT_XMM; i++) {
if (xmmregs[i].needed) continue;
if (xmmregs[i].type == XMMTYPE_GPRREG ) {
if( !(g_pCurInstInfo->regs[xmmregs[i].reg] & (EEINST_LIVE0|EEINST_LIVE1|EEINST_LIVE2)) ) {
if (!(EEINST_ISLIVEXMM(xmmregs[i].reg))) {
_freeXMMreg(i);
return i;
}
@ -144,12 +144,10 @@ int _getFreeXMMreg()
}
int _allocTempXMMreg(XMMSSEType type, int xmmreg) {
if (xmmreg == -1) {
if (xmmreg == -1)
xmmreg = _getFreeXMMreg();
}
else {
else
_freeXMMreg(xmmreg);
}
xmmregs[xmmreg].inuse = 1;
xmmregs[xmmreg].type = XMMTYPE_TEMP;

View File

@ -102,7 +102,11 @@
#define X86TYPE_VU1 0x80
#define X86_ISVI(type) ((type&~X86TYPE_VU1) == X86TYPE_VI)
//#define X86_ISVI(type) ((type&~X86TYPE_VU1) == X86TYPE_VI)
static __forceinline int X86_ISVI(int type)
{
return ((type&~X86TYPE_VU1) == X86TYPE_VI);
}
struct _x86regs {
u8 inuse;
@ -199,25 +203,37 @@ int _signExtendXMMtoM(u32 to, x86SSERegType from, int candestroy); // returns tr
// only valid during writes. If write128, then upper 64bits are in an mmxreg
// (mmreg&0xf). Constant is used from gprreg ((mmreg>>16)&0x1f)
#define MEM_EECONSTTAG 0x0100 // argument is a GPR and comes from g_cpuConstRegs
#define MEM_PSXCONSTTAG 0x0200
#define MEM_MEMORYTAG 0x0400
#define MEM_MMXTAG 0x0800 // mmreg is mmxreg
#define MEM_XMMTAG 0x8000 // mmreg is xmmreg
#define MEM_X86TAG 0x4000 // ignored most of the time
#define MEM_GPRTAG 0x2000 // argument is a GPR reg
#define MEM_CONSTTAG 0x1000 // argument is a const
enum memtag
{
MEM_EECONSTTAG = 0x0100, // argument is a GPR and comes from g_cpuConstRegs
MEM_PSXCONSTTAG = 0x0200,
MEM_MEMORYTAG = 0x0400,
MEM_MMXTAG = 0x0800, // mmreg is mmxreg
MEM_XMMTAG = 0x8000, // mmreg is xmmreg
MEM_X86TAG = 0x4000, // ignored most of the time
MEM_GPRTAG = 0x2000, // argument is a GPR reg
MEM_CONSTTAG = 0x1000 // argument is a const
};
#define IS_EECONSTREG(reg) (reg>=0&&((reg)&MEM_EECONSTTAG))
#define IS_PSXCONSTREG(reg) (reg>=0&&((reg)&MEM_PSXCONSTTAG))
#define IS_MMXREG(reg) (reg>=0&&((reg)&MEM_MMXTAG))
#define IS_XMMREG(reg) (reg>=0&&((reg)&MEM_XMMTAG))
template<memtag tag> static __forceinline bool IS_REG(s32 reg)
{
return ((reg >= 0) && (reg & tag));
}
// fixme - these 4 are only called for u32 registers; should the reg>=0 really be there?
#define IS_X86REG(reg) (reg>=0&&((reg)&MEM_X86TAG))
#define IS_GPRREG(reg) (reg>=0&&((reg)&MEM_GPRTAG))
#define IS_CONSTREG(reg) (reg>=0&&((reg)&MEM_CONSTTAG))
#define IS_MEMORYREG(reg) (reg>=0&&((reg)&MEM_MEMORYTAG))
template<memtag tag> static __forceinline bool IS_REG(u32 reg)
{
return (reg & tag);
}
#define IS_EECONSTREG(reg) IS_REG<MEM_EECONSTTAG>(reg)
#define IS_PSXCONSTREG(reg) IS_REG<MEM_PSXCONSTTAG>(reg)
#define IS_MMXREG(reg) IS_REG<MEM_MMXTAG>(reg)
#define IS_XMMREG(reg) IS_REG<MEM_XMMTAG>(reg)
#define IS_X86REG(reg) IS_REG<MEM_X86TAG>(reg)
#define IS_GPRREG(reg) IS_REG<MEM_GPRTAG>(reg)
#define IS_CONSTREG(reg) IS_REG<MEM_CONSTTAG>(reg)
#define IS_MEMORYREG(reg) IS_REG<MEM_MEMORYTAG>(reg)
//////////////////////
// Instruction Info //
@ -265,13 +281,13 @@ extern u32 _recIsRegWritten(EEINST* pinst, int size, u8 xmmtype, u8 reg);
extern u32 _recIsRegUsed(EEINST* pinst, int size, u8 xmmtype, u8 reg);
extern void _recFillRegister(EEINST& pinst, int type, int reg, int write);
#define EEINST_ISLIVE64(reg) (g_pCurInstInfo->regs[reg] & (EEINST_LIVE0|EEINST_LIVE1))
#define EEINST_ISLIVEXMM(reg) (g_pCurInstInfo->regs[reg] & (EEINST_LIVE0|EEINST_LIVE1|EEINST_LIVE2))
#define EEINST_ISLIVE1(reg) (g_pCurInstInfo->regs[reg] & EEINST_LIVE1)
#define EEINST_ISLIVE2(reg) (g_pCurInstInfo->regs[reg] & EEINST_LIVE2)
static __forceinline bool EEINST_ISLIVE64(u32 reg) { return (g_pCurInstInfo->regs[reg] & (EEINST_LIVE0|EEINST_LIVE1)); }
static __forceinline bool EEINST_ISLIVEXMM(u32 reg) { return (g_pCurInstInfo->regs[reg] & (EEINST_LIVE0|EEINST_LIVE1|EEINST_LIVE2)); }
static __forceinline bool EEINST_ISLIVE1(u32 reg) { return (g_pCurInstInfo->regs[reg] & EEINST_LIVE1); }
static __forceinline bool EEINST_ISLIVE2(u32 reg) { return (g_pCurInstInfo->regs[reg] & EEINST_LIVE2); }
#define FPUINST_ISLIVE(reg) (g_pCurInstInfo->fpuregs[reg] & EEINST_LIVE0)
#define FPUINST_LASTUSE(reg) (g_pCurInstInfo->fpuregs[reg] & EEINST_LASTUSE)
static __forceinline bool FPUINST_ISLIVE(u32 reg) { return (g_pCurInstInfo->fpuregs[reg] & EEINST_LIVE0); }
static __forceinline bool FPUINST_LASTUSE(u32 reg) { return (g_pCurInstInfo->fpuregs[reg] & EEINST_LASTUSE); }
// if set, then the variable at this inst really has its upper 32 bits valid
// The difference between EEINST_LIVE1 is that the latter is used in back propagation
@ -309,8 +325,8 @@ void SetMMXstate();
void SetFPUstate();
// max is 0x7f, when 0x80 is set, need to flush reg
#define MMX_GET_CACHE(ptr, index) ((u8*)ptr)[index]
#define MMX_SET_CACHE(ptr, ind3, ind2, ind1, ind0) ((u32*)ptr)[0] = (ind3<<24)|(ind2<<16)|(ind1<<8)|ind0;
//#define MMX_GET_CACHE(ptr, index) ((u8*)ptr)[index]
//#define MMX_SET_CACHE(ptr, ind3, ind2, ind1, ind0) ((u32*)ptr)[0] = (ind3<<24)|(ind2<<16)|(ind1<<8)|ind0;
#define MMX_GPR 0
#define MMX_HI XMMGPR_HI
#define MMX_LO XMMGPR_LO
@ -319,9 +335,20 @@ void SetFPUstate();
#define MMX_COP0 96
#define MMX_TEMP 0x7f
#define MMX_IS32BITS(x) (((x)>=MMX_FPU&&(x)<MMX_COP0+32)||(x)==MMX_FPUACC)
// If x is unsigned, the first part of this is always true, and it usually is.
#define MMX_ISGPR(x) ((x) >= MMX_GPR && (x) < MMX_GPR+34)
static __forceinline bool MMX_IS32BITS(s32 x)
{
return (((x >= MMX_FPU) && (x < MMX_COP0 + 32)) || (x == MMX_FPUACC));
}
static __forceinline bool MMX_ISGPR(s32 x)
{
return ((x >= MMX_GPR) && (x < MMX_GPR + 34));
}
static __forceinline bool MMX_ISGPR(u32 x)
{
return (x < MMX_GPR + 34);
}
struct _mmxregs {
u8 inuse;

View File

@ -32,12 +32,11 @@ using namespace std;
// landmass of shared code. (air)
extern u32 g_psxConstRegs[32];
u16 x86FpuState;
u16 g_mmxAllocCounter = 0;
static u16 g_mmxAllocCounter = 0;
// X86 caching
int g_x86checknext;
static int g_x86checknext;
// use special x86 register allocation for ia32
@ -49,38 +48,83 @@ void _initX86regs() {
u32 _x86GetAddr(int type, int reg)
{
switch(type&~X86TYPE_VU1) {
case X86TYPE_GPR: return (u32)&cpuRegs.GPR.r[reg];
case X86TYPE_VI: {
//assert( reg < 16 || reg == REG_R );
return (type&X86TYPE_VU1)?(u32)&VU1.VI[reg]:(u32)&VU0.VI[reg];
}
case X86TYPE_MEMOFFSET: return 0;
case X86TYPE_VIMEMOFFSET: return 0;
case X86TYPE_VUQREAD: return (type&X86TYPE_VU1)?(u32)&VU1.VI[REG_Q]:(u32)&VU0.VI[REG_Q];
case X86TYPE_VUPREAD: return (type&X86TYPE_VU1)?(u32)&VU1.VI[REG_P]:(u32)&VU0.VI[REG_P];
case X86TYPE_VUQWRITE: return (type&X86TYPE_VU1)?(u32)&VU1.q:(u32)&VU0.q;
case X86TYPE_VUPWRITE: return (type&X86TYPE_VU1)?(u32)&VU1.p:(u32)&VU0.p;
case X86TYPE_PSX: return (u32)&psxRegs.GPR.r[reg];
u32 ret = 0;
switch(type&~X86TYPE_VU1)
{
case X86TYPE_GPR:
ret = &cpuRegs.GPR.r[reg];
break;
case X86TYPE_VI:
if (type & X86TYPE_VU1)
ret = &VU1.VI[reg];
else
ret = &VU0.VI[reg];
break;
case X86TYPE_MEMOFFSET:
ret = 0;
break;
case X86TYPE_VIMEMOFFSET:
ret = 0;
break;
case X86TYPE_VUQREAD:
if (type & X86TYPE_VU1)
ret = &VU1.VI[REG_Q];
else
ret =&VU0.VI[REG_Q];
break;
case X86TYPE_VUPREAD:
if (type & X86TYPE_VU1)
ret = &VU1.VI[REG_P];
else
ret =&VU0.VI[REG_P];
break;
case X86TYPE_VUQWRITE:
if (type & X86TYPE_VU1)
ret = &VU1.q;
else
ret =&VU0.q;
break;
case X86TYPE_VUPWRITE:
if (type & X86TYPE_VU1)
ret = &VU1.p;
else
ret =&VU0.p;
break;
case X86TYPE_PSX:
ret = (u32)&psxRegs.GPR.r[reg];
break;
case X86TYPE_PCWRITEBACK:
return (u32)&g_recWriteback;
ret = (u32)&g_recWriteback;
break;
case X86TYPE_VUJUMP:
return (u32)&g_recWriteback;
ret = (u32)&g_recWriteback;
break;
jNO_DEFAULT;
}
return 0;
return ret;
}
int _getFreeX86reg(int mode)
{
int i, tempi;
int tempi = -1;
u32 bestcount = 0x10000;
int maxreg = (mode&MODE_8BITREG)?4:iREGCNT_GPR;
for (i=0; i<iREGCNT_GPR; i++) {
for (int i=0; i<iREGCNT_GPR; i++) {
int reg = (g_x86checknext+i)%iREGCNT_GPR;
if( reg == 0 || reg == ESP ) continue;
if( reg >= maxreg ) continue;
@ -92,8 +136,7 @@ int _getFreeX86reg(int mode)
}
}
tempi = -1;
for (i=1; i<maxreg; i++) {
for (int i=1; i<maxreg; i++) {
if( i == ESP ) continue;
if( (mode&MODE_NOFRAME) && i==EBP ) continue;
@ -139,7 +182,6 @@ void _flushConstReg(int reg)
void _flushConstRegs()
{
s32 i, j;
s32 zero_cnt = 0, minusone_cnt = 0;
s32 eaxval = 1; // 0, -1
u32 done[4] = {0, 0, 0, 0};
@ -149,13 +191,12 @@ void _flushConstRegs()
// flush 0 and -1 first
// ignore r0
for (i = 1, j = 0; i < 32; j++ && ++i, j %= 2) {
if (!GPR_IS_CONST1(i) || g_cpuFlushedConstReg & (1<<i))
continue;
if (g_cpuConstRegs[i].SL[j] != 0)
continue;
if (eaxval != 0)
XOR32RtoR(EAX, EAX), eaxval = 0;
for (int i = 1, j = 0; i < 32; j++ && ++i, j %= 2) {
if (!GPR_IS_CONST1(i) || g_cpuFlushedConstReg & (1<<i)) continue;
if (g_cpuConstRegs[i].SL[j] != 0) continue;
if (eaxval != 0) XOR32RtoR(EAX, EAX), eaxval = 0;
MOV32RtoM((uptr)&cpuRegs.GPR.r[i].SL[j], EAX);
done[j] |= 1<<i;
zero_cnt++;
@ -163,11 +204,9 @@ void _flushConstRegs()
rewindPtr = x86Ptr;
for (i = 1, j = 0; i < 32; j++ && ++i, j %= 2) {
if (!GPR_IS_CONST1(i) || g_cpuFlushedConstReg & (1<<i))
continue;
if (g_cpuConstRegs[i].SL[j] != -1)
continue;
for (int i = 1, j = 0; i < 32; j++ && ++i, j %= 2) {
if (!GPR_IS_CONST1(i) || g_cpuFlushedConstReg & (1<<i)) continue;
if (g_cpuConstRegs[i].SL[j] != -1) continue;
if (eaxval > 0) XOR32RtoR(EAX, EAX), eaxval = 0;
if (eaxval == 0) NOT32R(EAX), eaxval = -1;
@ -184,17 +223,17 @@ void _flushConstRegs()
done[1] |= done[3];
}
for (i = 1; i < 32; ++i) {
for (int i = 1; i < 32; ++i) {
if (GPR_IS_CONST1(i)) {
if (!(g_cpuFlushedConstReg&(1<<i))) {
if (!(done[0] & (1<<i)))
MOV32ItoM((uptr)&cpuRegs.GPR.r[i].UL[0], g_cpuConstRegs[i].UL[0]);
if (!(done[1] & (1<<i)))
MOV32ItoM((uptr)&cpuRegs.GPR.r[i].UL[1], g_cpuConstRegs[i].UL[1]);
g_cpuFlushedConstReg |= 1<<i;
}
if (g_cpuHasConstReg == g_cpuFlushedConstReg)
break;
if (g_cpuHasConstReg == g_cpuFlushedConstReg) break;
}
}
}
@ -206,14 +245,13 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
// don't alloc EAX and ESP,EBP if MODE_NOFRAME
int oldmode = mode;
int noframe = mode&MODE_NOFRAME;
int maxreg = (mode&MODE_8BITREG)?4:iREGCNT_GPR;
int noframe = mode & MODE_NOFRAME;
int maxreg = (mode & MODE_8BITREG) ? 4 : iREGCNT_GPR;
mode &= ~(MODE_NOFRAME|MODE_8BITREG);
int readfromreg = -1;
if( type != X86TYPE_TEMP ) {
if( maxreg < iREGCNT_GPR ) {
if ( type != X86TYPE_TEMP ) {
if ( maxreg < iREGCNT_GPR ) {
// make sure reg isn't in the higher regs
for(i = maxreg; i < iREGCNT_GPR; ++i) {
@ -232,8 +270,7 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
}
for (i=1; i<maxreg; i++) {
if( i == ESP ) continue;
if ( i == ESP ) continue;
if (!x86regs[i].inuse || x86regs[i].type != type || x86regs[i].reg != reg) continue;
if( (noframe && i == EBP) || (i >= maxreg) ) {
@ -272,12 +309,10 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
}
}
if (x86reg == -1) {
if (x86reg == -1)
x86reg = _getFreeX86reg(oldmode);
}
else {
else
_freeX86reg(x86reg);
}
x86regs[x86reg].type = type;
x86regs[x86reg].reg = reg;
@ -378,6 +413,7 @@ void _deleteX86reg(int type, int reg, int flush)
case 0:
_freeX86reg(i);
break;
case 1:
if( x86regs[i].mode & MODE_WRITE) {
@ -391,6 +427,7 @@ void _deleteX86reg(int type, int reg, int flush)
x86regs[i].mode |= MODE_READ;
}
return;
case 2:
x86regs[i].inuse = 0;
break;
@ -470,7 +507,7 @@ int _getFreeMMXreg()
// check for dead regs
for (i=0; i<iREGCNT_MMX; i++) {
if (mmxregs[i].needed) continue;
if (mmxregs[i].reg >= MMX_GPR && mmxregs[i].reg < MMX_GPR+34 ) { // mmxregs[i] is unsigned, and MMX_GPR == 0, so the first part is always true.
if (MMX_ISGPR(mmxregs[i].reg)) {
if( !(g_pCurInstInfo->regs[mmxregs[i].reg-MMX_GPR] & (EEINST_LIVE0|EEINST_LIVE1)) ) {
_freeMMXreg(i);
return i;
@ -485,7 +522,7 @@ int _getFreeMMXreg()
// check for future xmm usage
for (i=0; i<iREGCNT_MMX; i++) {
if (mmxregs[i].needed) continue;
if (mmxregs[i].reg >= MMX_GPR && mmxregs[i].reg < MMX_GPR+34 ) {
if (MMX_ISGPR(mmxregs[i].reg)) {
if( !(g_pCurInstInfo->regs[mmxregs[i].reg] & EEINST_MMX) ) {
_freeMMXreg(i);
return i;
@ -612,7 +649,7 @@ int _checkMMXreg(int reg, int mode)
PXORRtoR(i, i);
}
else {
if( MMX_ISGPR(reg) && (mode&(MODE_READHALF|MODE_READ)) ) _flushConstReg(reg-MMX_GPR);
if (MMX_ISGPR(reg) && (mode&(MODE_READHALF|MODE_READ))) _flushConstReg(reg-MMX_GPR);
if( (mode & MODE_READHALF) || (MMX_IS32BITS(reg)&&(mode&MODE_READ)) )
MOVDMtoMMX(i, (u32)_MMXGetAddr(reg));
else
@ -713,7 +750,7 @@ u8 _hasFreeMMXreg()
// check for dead regs
for (i=0; i<iREGCNT_MMX; i++) {
if (mmxregs[i].needed) continue;
if (mmxregs[i].reg >= MMX_GPR && mmxregs[i].reg < MMX_GPR+34 ) {
if (MMX_ISGPR(mmxregs[i].reg)) {
if( !EEINST_ISLIVE64(mmxregs[i].reg-MMX_GPR) ) {
return 1;
}
@ -723,7 +760,7 @@ u8 _hasFreeMMXreg()
// check for dead regs
for (i=0; i<iREGCNT_MMX; i++) {
if (mmxregs[i].needed) continue;
if (mmxregs[i].reg >= MMX_GPR && mmxregs[i].reg < MMX_GPR+34 ) {
if (MMX_ISGPR(mmxregs[i].reg)) {
if( !(g_pCurInstInfo->regs[mmxregs[i].reg-MMX_GPR]&EEINST_USED) ) {
return 1;
}
@ -739,8 +776,8 @@ void _freeMMXreg(int mmxreg)
if (!mmxregs[mmxreg].inuse) return;
if (mmxregs[mmxreg].mode & MODE_WRITE ) {
if( mmxregs[mmxreg].reg >= MMX_GPR && mmxregs[mmxreg].reg < MMX_GPR+32 )
// Not sure if this line is accurate, since if the 32 was 34, it would be MMX_ISGPR.
if ( /*mmxregs[mmxreg].reg >= MMX_GPR &&*/ mmxregs[mmxreg].reg < MMX_GPR+32 ) // Checking if a u32 is >=0 is pointless.
assert( !(g_cpuHasConstReg & (1<<(mmxregs[mmxreg].reg-MMX_GPR))) );
assert( mmxregs[mmxreg].reg != MMX_GPR );

View File

@ -478,8 +478,6 @@ void recResetEE( void )
__asm__("emms");
#endif
#define GET_HWADDR(mem)
for (int i = 0; i < 0x10000; i++)
recLUT_SetPage(recLUT, 0, 0, 0, i, 0);