- // check for link register access in delay slot
- int rt1_=rt1[i-1];
- if(rt1_!=0&&(rs1[i]==rt1_||rs2[i]==rt1_||rt1[i]==rt1_||rt2[i]==rt1_)) {
- printf("link access in delay slot @%08x (%08x)\n", addr + i*4, addr);
+ if(i>0&&(itype[i-1]==RJUMP||itype[i-1]==UJUMP||itype[i-1]==CJUMP||itype[i-1]==SJUMP||itype[i-1]==FJUMP)) {
+ int do_in_intrp=0;
+ // branch in delay slot?
+ if(type==RJUMP||type==UJUMP||type==CJUMP||type==SJUMP||type==FJUMP) {
+ // don't handle first branch and call interpreter if it's hit
+ printf("branch in delay slot @%08x (%08x)\n", addr + i*4, addr);
+ do_in_intrp=1;
+ }
+ // basic load delay detection
+ else if((type==LOAD||type==LOADLR||type==COP0||type==COP2||type==C2LS)&&rt1[i]!=0) {
+ int t=(ba[i-1]-start)/4;
+ if(0 <= t && t < i &&(rt1[i]==rs1[t]||rt1[i]==rs2[t])&&itype[t]!=CJUMP&&itype[t]!=SJUMP) {
+ // jump target wants DS result - potential load delay effect
+ printf("load delay @%08x (%08x)\n", addr + i*4, addr);
+ do_in_intrp=1;
+ bt[t+1]=1; // expected return from interpreter
+ }
+ else if(i>=2&&rt1[i-2]==2&&rt1[i]==2&&rs1[i]!=2&&rs2[i]!=2&&rs1[i-1]!=2&&rs2[i-1]!=2&&
+ !(i>=3&&(itype[i-3]==RJUMP||itype[i-3]==UJUMP||itype[i-3]==CJUMP||itype[i-3]==SJUMP))) {
+ // v0 overwrite like this is a sign of trouble, bail out
+ printf("v0 overwrite @%08x (%08x)\n", addr + i*4, addr);
+ do_in_intrp=1;
+ }
+ }
+ if(do_in_intrp) {
+ rs1[i-1]=CCREG;
+ rs2[i-1]=rt1[i-1]=rt2[i-1]=0;