aboutsummaryrefslogtreecommitdiff
path: root/libpcsxcore/ppc/reguse.c
diff options
context:
space:
mode:
authornotaz2012-12-02 00:36:34 +0200
committernotaz2012-12-02 02:37:11 +0200
commit89f33b734d7d540c7fa26f6556ef9ec49eb3008a (patch)
tree1084e3198b145776dfa594260ef18591321b925b /libpcsxcore/ppc/reguse.c
parent665f33e1e8ce2e40a7939a33075c3bce1c90790c (diff)
downloadpcsx_rearmed-89f33b734d7d540c7fa26f6556ef9ec49eb3008a.tar.gz
pcsx_rearmed-89f33b734d7d540c7fa26f6556ef9ec49eb3008a.tar.bz2
pcsx_rearmed-89f33b734d7d540c7fa26f6556ef9ec49eb3008a.zip
rm x86 and ppc dynarec remains
that code is broken and unmaintained in this fork, which now relies on new_dynarec instead. It's better to merge Ari64's new_dynarec x86 code if x86 support is desired.
Diffstat (limited to 'libpcsxcore/ppc/reguse.c')
-rw-r--r--libpcsxcore/ppc/reguse.c419
1 files changed, 0 insertions, 419 deletions
diff --git a/libpcsxcore/ppc/reguse.c b/libpcsxcore/ppc/reguse.c
deleted file mode 100644
index 47d70a5..0000000
--- a/libpcsxcore/ppc/reguse.c
+++ /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
-}