rm x86 and ppc dynarec remains
[pcsx_rearmed.git] / libpcsxcore / ppc / reguse.c
diff --git a/libpcsxcore/ppc/reguse.c b/libpcsxcore/ppc/reguse.c
deleted file mode 100644 (file)
index 47d70a5..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-
-#include "../psxcommon.h"
-#include "reguse.h"
-
-#include "../r3000a.h"
-
-//#define SAME_CYCLE_MODE
-
-static const int useBSC[64] = {
-       /*recSPECIAL*/ REGUSE_SUB | REGUSE_SPECIAL,
-        /*recREGIMM*/ REGUSE_SUB | REGUSE_REGIMM,
-        /*recJ*/     REGUSE_JUMP, 
-        /*recJAL*/   REGUSE_JUMP | REGUSE_R31_W, 
-        /*recBEQ*/   REGUSE_BRANCH | REGUSE_RS_R | REGUSE_RT_R, 
-        /*recBNE*/   REGUSE_BRANCH | REGUSE_RS_R | REGUSE_RT_R, 
-        /*recBLEZ*/  REGUSE_BRANCH | REGUSE_RS_R, 
-        /*recBGTZ*/  REGUSE_BRANCH | REGUSE_RS_R,
-       /*recADDI*/  REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recADDIU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recSLTI*/  REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recSLTIU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recANDI*/  REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recORI*/   REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recXORI*/  REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recLUI*/   REGUSE_ACC | REGUSE_RT_W,
-       /*recCOP0*/  REGUSE_SUB | REGUSE_COP0, 
-        REGUSE_NONE, 
-        /*recCOP2*/  REGUSE_SUB | REGUSE_COP2, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       /*recLB*/    REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recLH*/    REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recLWL*/   REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT, 
-        /*recLW*/    REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recLBU*/   REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recLHU*/   REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, 
-        /*recLWR*/   REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT, 
-        REGUSE_NONE,
-       /*recSB*/    REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R, 
-        /*recSH*/    REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R, 
-        /*recSWL*/   REGUSE_MEM | REGUSE_RS_R | REGUSE_RT_R, 
-        /*recSW*/    REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R, 
-        REGUSE_NONE, REGUSE_NONE, 
-        /*recSWR*/   REGUSE_MEM | REGUSE_RS_R | REGUSE_RT_R, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        /*recLWC2*/  REGUSE_MEM_R | REGUSE_RS_R | REGUSE_COP2_RT_W, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       REGUSE_NONE, REGUSE_NONE, 
-        /*recSWC2*/  REGUSE_MEM_W | REGUSE_RS_R | REGUSE_COP2_RT_R, 
-        /*recHLE*/   REGUSE_UNKNOWN, // TODO: can this be done in a better way
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE
-};
-
-static const int useSPC[64] = {
-       /*recSLL*/   REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W, 
-        REGUSE_NONE, 
-        /*recSRL*/   REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recSRA*/   REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recSLLV*/  REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        REGUSE_NONE, 
-        /*recSRLV*/  REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recSRAV*/  REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
-       /*recJR*/    REGUSE_JUMPR | REGUSE_RS_R, 
-        /*recJALR*/  REGUSE_JUMPR | REGUSE_RS_R | REGUSE_RD_W, 
-        REGUSE_NONE, REGUSE_NONE, 
-        /*rSYSCALL*/ REGUSE_SYS | REGUSE_PC | REGUSE_COP0_STATUS | REGUSE_EXCEPTION,
-        /*recBREAK*/ REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE,
-       /*recMFHI*/  REGUSE_LOGIC | REGUSE_RD_W | REGUSE_HI_R, 
-        /*recMTHI*/  REGUSE_LOGIC | REGUSE_RS_R | REGUSE_HI_W, 
-        /*recMFLO*/  REGUSE_LOGIC | REGUSE_RD_W | REGUSE_LO_R, 
-        /*recMTLO*/  REGUSE_LOGIC | REGUSE_RS_R | REGUSE_LO_W, 
-        REGUSE_NONE, REGUSE_NONE , REGUSE_NONE, REGUSE_NONE,
-       /*recMULT*/  REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W, 
-        /*recMULTU*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W, 
-        /*recDIV*/   REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W, 
-        /*recDIVU*/  REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       /*recADD*/   REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recADDU*/  REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recSUB*/   REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recSUBU*/  REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recAND*/   REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recOR*/    REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recXOR*/   REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recNOR*/   REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
-       REGUSE_NONE, REGUSE_NONE, 
-        /*recSLT*/   REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        /*recSLTU*/  REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-       REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE
-};
-
-static const int useREGIMM[32] = {
-       /*recBLTZ*/  REGUSE_BRANCH | REGUSE_RS_R, 
-        /*recBGEZ*/  REGUSE_BRANCH | REGUSE_RS_R, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE,
-       /*recBLTZAL*/REGUSE_BRANCH | REGUSE_RS_R | REGUSE_R31_W, 
-        /*recBGEZAL*/REGUSE_BRANCH | REGUSE_RS_R | REGUSE_R31_W, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE
-};
-
-static const int useCP0[32] = {
-       /*recMFC0*/  REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP0_RD_R, 
-        REGUSE_NONE, 
-        /*recCFC0*/  REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP0_RD_R, 
-        REGUSE_NONE, 
-        /*recMTC0*/  REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP0_RD_W, 
-        REGUSE_NONE, 
-        /*recCTC0*/  REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP0_RD_W, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       /*recRFE*/   REGUSE_LOGIC | REGUSE_COP0_STATUS, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE
-};
-
-// TODO: make more explicit
-static const int useCP2[64] = {
-       /*recBASIC*/ REGUSE_SUB | REGUSE_BASIC, 
-        /*recRTPS*/  REGUSE_GTE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        /*recNCLIP*/ REGUSE_GTE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        /*recOP*/    REGUSE_GTE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
-       /*recDPCS*/  REGUSE_GTE, 
-        /*recINTPL*/ REGUSE_GTE, 
-        /*recMVMVA*/ REGUSE_GTE, 
-        /*recNCDS*/  REGUSE_GTE, 
-        /*recCDP*/   REGUSE_GTE, 
-        REGUSE_NONE, 
-        /*recNCDT*/  REGUSE_GTE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        /*recNCCS*/  REGUSE_GTE, 
-        /*recCC*/    REGUSE_GTE, 
-        REGUSE_NONE, 
-        /*recNCS*/   REGUSE_GTE, 
-        REGUSE_NONE,
-       /*recNCT*/   REGUSE_GTE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE,
-       /*recSQR*/   REGUSE_GTE, 
-        /*recDCPL*/  REGUSE_GTE, 
-        /*recDPCT*/  REGUSE_GTE, 
-        REGUSE_NONE, REGUSE_NONE, 
-        /*recAVSZ3*/ REGUSE_GTE, 
-        /*recAVSZ4*/ REGUSE_GTE, 
-        REGUSE_NONE,
-       /*recRTPT*/  REGUSE_GTE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, 
-        /*recGPF*/   REGUSE_GTE, 
-        /*recGPL*/   REGUSE_GTE, 
-        /*recNCCT*/  REGUSE_GTE
-};
-
-static const int useCP2BSC[32] = {
-       /*recMFC2*/  REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP2_RD_R, 
-        REGUSE_NONE, 
-        /*recCFC2*/  REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP2_RD_R, 
-        REGUSE_NONE, 
-        /*recMTC2*/  REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP2_RD_W, 
-        REGUSE_NONE, 
-        /*recCTC2*/  REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP2_RD_W, 
-        REGUSE_NONE,
-       REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE,
-       REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE,
-       REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE, 
-        REGUSE_NONE
-};
-
-static int getRegUse(u32 code) __attribute__ ((__pure__));
-static int getRegUse(u32 code)
-{
-    int use = useBSC[code>>26];
-    
-    switch (use & REGUSE_SUBMASK) {
-                 case REGUSE_NONE:
-                               break;
-        case REGUSE_SPECIAL:
-            use = useSPC[_fFunct_(code)];
-            break;
-        case REGUSE_REGIMM:
-            use = useREGIMM[_fRt_(code)];
-            break;
-        case REGUSE_COP0:
-            use = useCP0[_fRs_(code)];
-            break;
-        case REGUSE_COP2:
-            use = useCP2[_fFunct_(code)];
-            if ((use & REGUSE_SUBMASK) == REGUSE_BASIC)
-                use = useCP2BSC[_fRs_(code)];
-            break;
-                 default:
-                               use = REGUSE_UNKNOWN;
-                               break;
-    }
-    
-    if ((use & REGUSE_COP0_RD_W)) {
-        if (_fRd_(code) == 12 || _fRd_(code) == 13) {
-            use = REGUSE_UNKNOWN;
-        }
-    }
-    
-    return use;
-}
-
-/* returns how psxreg is used in the code instruction */
-int useOfPsxReg(u32 code, int use, int psxreg)
-{
-    int retval = REGUSE_NONE;
-    
-        // get use if it wasn't supplied
-    if (-1 == use) use = getRegUse(code);
-    
-        // if we don't know what the usage is, assume it's read from
-    if (REGUSE_UNKNOWN == use) return REGUSE_READ;
-    
-    if (psxreg < 32) {
-        // check for 3 standard types
-                 if ((use & REGUSE_RT) && _fRt_(code) == (u32)psxreg) {
-            retval |= ((use & REGUSE_RT_R) ? REGUSE_READ:0) | ((use & REGUSE_RT_W) ? REGUSE_WRITE:0);
-        }
-        if ((use & REGUSE_RS) && _fRs_(code) == (u32)psxreg) {
-            retval |= ((use & REGUSE_RS_R) ? REGUSE_READ:0) | ((use & REGUSE_RS_W) ? REGUSE_WRITE:0);
-        }
-        if ((use & REGUSE_RD) && _fRd_(code) == (u32)psxreg) {
-            retval |= ((use & REGUSE_RD_R) ? REGUSE_READ:0) | ((use & REGUSE_RD_W) ? REGUSE_WRITE:0);
-        }
-                 // some instructions explicitly writes to r31
-        if ((use & REGUSE_R31_W) && 31 == psxreg) {
-            retval |= REGUSE_WRITE;
-        }
-    } else if (psxreg == 32) { // Special register LO
-        retval |= ((use & REGUSE_LO_R) ? REGUSE_READ:0) | ((use & REGUSE_LO_W) ? REGUSE_WRITE:0);
-    } else if (psxreg == 33) { // Special register HI
-        retval |= ((use & REGUSE_HI_R) ? REGUSE_READ:0) | ((use & REGUSE_HI_W) ? REGUSE_WRITE:0);
-    }
-    
-    return retval;
-}
-
-//#define NOREGUSE_FOLLOW
-
-static int _nextPsxRegUse(u32 pc, int psxreg, int numInstr) __attribute__ ((__pure__, __unused__));
-static int _nextPsxRegUse(u32 pc, int psxreg, int numInstr)
-{
-    u32 *ptr, code, bPC = 0;
-    int i, use, reguse = 0;
-
-    for (i=0; i<numInstr; ) {
-        // load current instruction
-                 ptr = PSXM(pc);
-                 if (ptr==NULL) {
-                               // going nowhere... might as well assume a write, since we will hopefully never reach here
-                               reguse = REGUSE_WRITE;
-                               break;
-                 }
-                 code = SWAP32(*ptr);
-                 // get usage patterns for instruction
-                 use = getRegUse(code);
-                 // find the use of psxreg in the instruction
-        reguse = useOfPsxReg(code, use, psxreg);
-        
-                 // return if we have found a use
-        if (reguse != REGUSE_NONE)
-                               break;
-        
-                 // goto next instruction
-        pc += 4;
-                 i++;
-                 
-                 // check for code branches/jumps
-                 if (i != numInstr) {
-                         if ((use & REGUSE_TYPEM) == REGUSE_BRANCH) {
-#ifndef NOREGUSE_FOLLOW
-                                       // check delay slot
-                                       reguse = _nextPsxRegUse(pc, psxreg, 1);
-                                       if (reguse != REGUSE_NONE) break;
-                                       
-                                       bPC = _fImm_(code) * 4 + pc;
-                                       reguse = _nextPsxRegUse(pc+4, psxreg, (numInstr-i-1)/2);
-                                       if (reguse != REGUSE_NONE) {
-                                               int reguse2 = _nextPsxRegUse(bPC, psxreg, (numInstr-i-1)/2);
-                                               if (reguse2 != REGUSE_NONE)
-                                                       reguse |= reguse2;
-                                               else
-                                                       reguse = REGUSE_NONE;
-                                       }
-#endif
-                                       break;
-                         } else if ((use & REGUSE_TYPEM) == REGUSE_JUMP) {
-#ifndef NOREGUSE_FOLLOW
-                                       // check delay slot
-                                       reguse = _nextPsxRegUse(pc, psxreg, 1);
-                                       if (reguse != REGUSE_NONE) break;
-                                       
-                                       bPC = _fTarget_(code) * 4 + (pc & 0xf0000000);
-                                       reguse = _nextPsxRegUse(bPC, psxreg, numInstr-i-1);
-#endif
-                                       break;
-                         } else if ((use & REGUSE_TYPEM) == REGUSE_JUMPR) {
-#ifndef NOREGUSE_FOLLOW
-                                       // jump to unknown location - bail after checking delay slot
-                                       reguse = _nextPsxRegUse(pc, psxreg, 1);
-#endif
-                                       break;
-                         } else if ((use & REGUSE_TYPEM) == REGUSE_SYS) {
-                                       break;
-                         }
-                 }
-    }
-    
-    return reguse;
-}
-
-
-int nextPsxRegUse(u32 pc, int psxreg)
-{
-#if 1
-       if (psxreg == 0)
-               return REGUSE_WRITE; // pretend we are writing to it to fool compiler
-
-#ifdef SAME_CYCLE_MODE
-       return REGUSE_READ;
-#else
-       return _nextPsxRegUse(pc, psxreg, 80);
-#endif
-#else
-    u32 code, bPC = 0;
-    int use, reguse = 0, reguse1 = 0, b = 0, i, index = 0;
-
-retry:
-    for (i=index; i<80; i++) {
-        code = PSXMu32(pc);
-       use = getRegUse(code);
-        reguse = useOfPsxReg(code, use, psxreg);
-        
-        if (reguse != REGUSE_NONE) break;
-        
-        pc += 4;
-        if ((use & REGUSE_TYPEM) == REGUSE_BRANCH) {
-            if (b == 0) {
-                bPC = _fImm_(code) * 4 + pc;
-                index = i+1;
-            }
-            b += 1; // TODO: follow branches
-            continue;
-        } else if ((use & REGUSE_TYPEM) == REGUSE_JUMP) {
-            if (b == 0) {
-                bPC = _fTarget_(code) * 4 + (pc & 0xf0000000);
-            }
-            b = 2;
-            continue;       
-        } else if ((use & REGUSE_TYPEM) == REGUSE_JUMPR || 
-                   (use & REGUSE_TYPEM) == REGUSE_SYS) {
-            b = 2;
-            continue;       
-        }
-        
-        if (b == 2 && bPC && index == 0) {
-            pc = bPC; bPC = 0;
-            b = 1;
-        }
-        if (b >= 2) break; // only follow 1 branch
-    }
-    if (reguse == REGUSE_NONE) return reguse;
-    
-    if (bPC) {
-        reguse1 = reguse;
-        pc = bPC; bPC = 0;
-        b = 1;
-        goto retry;
-    }
-    
-    return reguse1 | reguse;
-#endif
-}
-
-int isPsxRegUsed(u32 pc, int psxreg)
-{
-    int use = nextPsxRegUse(pc, psxreg);
-    
-    if (use == REGUSE_NONE)
-        return 2; // unknown use - assume it is used
-    else if (use & REGUSE_READ)
-        return 1; // the next use is a read
-    else
-        return 0; // the next use is a write, i.e. current value is not important
-}