int s,tl;
int ar;
int offset;
- int c=0;
+ int memtarget=0,c=0;
int jaddr,jaddr2=0,jaddr3,type;
int agr=AGEN1+(i&1);
u_int hr,reglist=0;
} else { // LWC2
ar=tl;
}
+ if(s>=0) c=(i_regs->wasconst>>s)&1;
+ memtarget=c&&(((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE);
if (!offset&&!c&&s>=0) ar=s;
assert(ar>=0);
if (opcode[i]==0x3a) { // SWC2
cop2_get_dreg(copr,tl,HOST_TEMPREG);
+ type=STOREW_STUB;
}
- if(s>=0) c=(i_regs->wasconst>>s)&1;
- if(!c) {
- emit_cmpimm(offset||c||s<0?ar:s,RAM_SIZE);
- jaddr2=(int)out;
- emit_jno(0);
- }
- else if(((signed int)(constmap[i][s]+offset))>=(signed int)0x80000000+RAM_SIZE) {
- jaddr2=(int)out;
- emit_jmp(0); // inline_readstub/inline_writestub? Very rare case
- }
- if (opcode[i]==0x32) { // LWC2
- #ifdef HOST_IMM_ADDR32
- if(c) emit_readword_tlb(constmap[i][s]+offset,-1,tl);
- else
- #endif
- emit_readword_indexed(0,ar,tl);
+ else
type=LOADW_STUB;
+
+ if(c&&!memtarget) {
+ jaddr2=(int)out;
+ emit_jmp(0); // inline_readstub/inline_writestub?
}
- if (opcode[i]==0x3a) { // SWC2
-#ifdef DESTRUCTIVE_SHIFT
- if(!offset&&!c&&s>=0) emit_mov(s,ar);
-#endif
- emit_writeword_indexed(tl,0,ar);
- type=STOREW_STUB;
+ else {
+ if(!c) {
+ emit_cmpimm(offset||c||s<0?ar:s,RAM_SIZE);
+ jaddr2=(int)out;
+ emit_jno(0);
+ }
+ if (opcode[i]==0x32) { // LWC2
+ #ifdef HOST_IMM_ADDR32
+ if(c) emit_readword_tlb(constmap[i][s]+offset,-1,tl);
+ else
+ #endif
+ emit_readword_indexed(0,ar,tl);
+ }
+ if (opcode[i]==0x3a) { // SWC2
+ #ifdef DESTRUCTIVE_SHIFT
+ if(!offset&&!c&&s>=0) emit_mov(s,ar);
+ #endif
+ emit_writeword_indexed(tl,0,ar);
+ }
}
if(jaddr2)
add_stub(type,jaddr2,(int)out,i,ar,(int)i_regs,ccadj[i],reglist);
if(itype[i]==C1LS||itype[i]==C2LS) {
if ((opcode[i]&0x3b)==0x31||(opcode[i]&0x3b)==0x32) // LWC1/LDC1/LWC2/LDC2
ra=get_reg(i_regs->regmap,FTEMP);
- else { // SWC1/SDC1
+ else { // SWC1/SDC1/SWC2/SDC2
ra=get_reg(i_regs->regmap,agr);
if(ra<0) ra=get_reg(i_regs->regmap,-1);
}
#endif
//if(opcode2[i]>=0x10) return; // FIXME (BxxZAL)
- assert(opcode2[i]<0x10||rs1[i]==0); // FIXME (BxxZAL)
+ //assert(opcode2[i]<0x10||rs1[i]==0); // FIXME (BxxZAL)
if(ooo)
if(rs1[i]&&(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1]))
// First test branch condition, then execute delay slot, then branch
ooo=0;
}
- // TODO: Conditional branches w/link must execute in-order so that
- // condition test and write to r31 occur before cycle count test
+ assert(opcode2[i]<0x10||ooo); // FIXME (BxxZALL)
if(ooo) {
s1l=get_reg(branch_regs[i].regmap,rs1[i]);
if(!only32)
{
assert(s1h>=0);
- if(opcode2[i]==0) // BLTZ
+ if((opcode2[i]&0xf)==0) // BLTZ/BLTZAL
{
emit_test(s1h,s1h);
if(invert){
emit_js(0);
}
}
- if(opcode2[i]==1) // BGEZ
+ if((opcode2[i]&0xf)==1) // BGEZ/BLTZAL
{
emit_test(s1h,s1h);
if(invert){
else
{
assert(s1l>=0);
- if(opcode2[i]==0) // BLTZ
+ if((opcode2[i]&0xf)==0) // BLTZ/BLTZAL
{
emit_test(s1l,s1l);
if(invert){
emit_js(0);
}
}
- if(opcode2[i]==1) // BGEZ
+ if((opcode2[i]&0xf)==1) // BGEZ/BLTZAL
{
emit_test(s1l,s1l);
if(invert){
case 0x15: strcpy(insn[i],"BNEL"); type=CJUMP; break;
case 0x16: strcpy(insn[i],"BLEZL"); type=CJUMP; break;
case 0x17: strcpy(insn[i],"BGTZL"); type=CJUMP; break;
+#ifndef FORCE32
case 0x18: strcpy(insn[i],"DADDI"); type=IMM16; break;
case 0x19: strcpy(insn[i],"DADDIU"); type=IMM16; break;
case 0x1A: strcpy(insn[i],"LDL"); type=LOADLR; break;
case 0x1B: strcpy(insn[i],"LDR"); type=LOADLR; break;
+#endif
case 0x20: strcpy(insn[i],"LB"); type=LOAD; break;
case 0x21: strcpy(insn[i],"LH"); type=LOAD; break;
case 0x22: strcpy(insn[i],"LWL"); type=LOADLR; break;
case 0x29: strcpy(insn[i],"SH"); type=STORE; break;
case 0x2A: strcpy(insn[i],"SWL"); type=STORELR; break;
case 0x2B: strcpy(insn[i],"SW"); type=STORE; break;
+#ifndef FORCE32
case 0x2C: strcpy(insn[i],"SDL"); type=STORELR; break;
case 0x2D: strcpy(insn[i],"SDR"); type=STORELR; break;
+#endif
case 0x2E: strcpy(insn[i],"SWR"); type=STORELR; break;
case 0x2F: strcpy(insn[i],"CACHE"); type=NOP; break;
case 0x30: strcpy(insn[i],"LL"); type=NI; break;
case 0x31: strcpy(insn[i],"LWC1"); type=C1LS; break;
+#ifndef FORCE32
case 0x34: strcpy(insn[i],"LLD"); type=NI; break;
case 0x35: strcpy(insn[i],"LDC1"); type=C1LS; break;
case 0x37: strcpy(insn[i],"LD"); type=LOAD; break;
+#endif
case 0x38: strcpy(insn[i],"SC"); type=NI; break;
case 0x39: strcpy(insn[i],"SWC1"); type=C1LS; break;
+#ifndef FORCE32
case 0x3C: strcpy(insn[i],"SCD"); type=NI; break;
case 0x3D: strcpy(insn[i],"SDC1"); type=C1LS; break;
case 0x3F: strcpy(insn[i],"SD"); type=STORE; break;
+#endif
#ifdef PCSX
case 0x12: strcpy(insn[i],"COP2"); type=NI;
op2=(source[i]>>21)&0x1f;
case 0x3B: strcpy(insn[i],"HLECALL"); type=HLECALL; break;
#endif
default: strcpy(insn[i],"???"); type=NI;
- printf("NI %08x @%08x\n", source[i], addr + i*4);
+ printf("NI %08x @%08x (%08x)\n", source[i], addr + i*4, addr);
break;
}
itype[i]=type;
// Don't get too close to the limit
if(i>MAXBLOCK/2) done=1;
}
- if(i>0&&itype[i-1]==SYSCALL&&stop_after_jal) done=1;
- if(itype[i-1]==HLECALL) done=1;
- assert(i<MAXBLOCK-1);
+ if(itype[i]==SYSCALL&&stop_after_jal) done=1;
+ if(itype[i]==HLECALL) done=1;
+ //assert(i<MAXBLOCK-1);
if(start+i*4==pagelimit-4) done=1;
assert(start+i*4<pagelimit);
if (i==MAXBLOCK-1) done=1;