-
- for (i=iend;i>=istart;i--)
- {
- //printf("unneeded registers i=%d (%d,%d) r=%d\n",i,istart,iend,r);
- if(dops[i].is_jump)
- {
- // If subroutine call, flag return address as a possible branch target
- if(dops[i].rt1==31 && i<slen-2) dops[i+2].bt=1;
-
- if(ba[i]<start || ba[i]>=(start+slen*4))
- {
- // Branch out of this block, flush all regs
- u=1;
- gte_u=gte_u_unknown;
- branch_unneeded_reg[i]=u;
- // Merge in delay slot
- u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
- u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
- u|=1;
- gte_u|=gte_rt[i+1];
- gte_u&=~gte_rs[i+1];
- }
- else
- {
- // Internal branch, flag target
- dops[(ba[i]-start)>>2].bt=1;
- if(ba[i]<=start+i*4) {
- // Backward branch
- if(dops[i].is_ujump)
- {
- // Unconditional branch
- temp_u=1;
- temp_gte_u=0;
- } else {
- // Conditional branch (not taken case)
- temp_u=unneeded_reg[i+2];
- temp_gte_u&=gte_unneeded[i+2];
- }
- // Merge in delay slot
- temp_u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
- temp_u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
- temp_u|=1;
- temp_gte_u|=gte_rt[i+1];
- temp_gte_u&=~gte_rs[i+1];
- temp_u|=(1LL<<dops[i].rt1)|(1LL<<dops[i].rt2);
- temp_u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
- temp_u|=1;
- temp_gte_u|=gte_rt[i];
- temp_gte_u&=~gte_rs[i];
- unneeded_reg[i]=temp_u;
- gte_unneeded[i]=temp_gte_u;
- // Only go three levels deep. This recursion can take an
- // excessive amount of time if there are a lot of nested loops.
- if(r<2) {
- unneeded_registers((ba[i]-start)>>2,i-1,r+1);
- }else{
- unneeded_reg[(ba[i]-start)>>2]=1;
- gte_unneeded[(ba[i]-start)>>2]=gte_u_unknown;
- }
- } /*else*/ if(1) {
- if (dops[i].is_ujump)
- {
- // Unconditional branch
- u=unneeded_reg[(ba[i]-start)>>2];
- gte_u=gte_unneeded[(ba[i]-start)>>2];
- branch_unneeded_reg[i]=u;
- // Merge in delay slot
- u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
- u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
- u|=1;
- gte_u|=gte_rt[i+1];
- gte_u&=~gte_rs[i+1];
- } else {
- // Conditional branch
- b=unneeded_reg[(ba[i]-start)>>2];
- gte_b=gte_unneeded[(ba[i]-start)>>2];
- branch_unneeded_reg[i]=b;
- // Branch delay slot
- b|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
- b&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
- b|=1;
- gte_b|=gte_rt[i+1];
- gte_b&=~gte_rs[i+1];
- u&=b;
- gte_u&=gte_b;
- if(i<slen-1) {
- branch_unneeded_reg[i]&=unneeded_reg[i+2];
- } else {
- branch_unneeded_reg[i]=1;
- }
- }
- }
- }
- }
- else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
- {
- // SYSCALL instruction (software interrupt)
- u=1;
- }
- else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
- {
- // ERET instruction (return from interrupt)
- u=1;
- }
- //u=1; // DEBUG
- // Written registers are unneeded
- u|=1LL<<dops[i].rt1;
- u|=1LL<<dops[i].rt2;
- gte_u|=gte_rt[i];
- // Accessed registers are needed
- u&=~(1LL<<dops[i].rs1);
- u&=~(1LL<<dops[i].rs2);
- gte_u&=~gte_rs[i];
- if(gte_rs[i]&&dops[i].rt1&&(unneeded_reg[i+1]&(1ll<<dops[i].rt1)))
- gte_u|=gte_rs[i]>e_unneeded[i+1]; // MFC2/CFC2 to dead register, unneeded
- // Source-target dependencies
- // R0 is always unneeded
- u|=1;
- // Save it
- unneeded_reg[i]=u;
- gte_unneeded[i]=gte_u;
- /*
- printf("ur (%d,%d) %x: ",istart,iend,start+i*4);
- printf("U:");
- int r;
- for(r=1;r<=CCREG;r++) {
- if((unneeded_reg[i]>>r)&1) {
- if(r==HIREG) printf(" HI");
- else if(r==LOREG) printf(" LO");
- else printf(" r%d",r);
- }
- }
- printf("\n");
- */
- }
-}
-
-// Write back dirty registers as soon as we will no longer modify them,
-// so that we don't end up with lots of writes at the branches.
-void clean_registers(int istart,int iend,int wr)
-{
- int i;
- int r;
- u_int will_dirty_i,will_dirty_next,temp_will_dirty;
- u_int wont_dirty_i,wont_dirty_next,temp_wont_dirty;
- if(iend==slen-1) {
- will_dirty_i=will_dirty_next=0;
- wont_dirty_i=wont_dirty_next=0;
- }else{
- will_dirty_i=will_dirty_next=will_dirty[iend+1];
- wont_dirty_i=wont_dirty_next=wont_dirty[iend+1];
- }
- for (i=iend;i>=istart;i--)
- {
- __builtin_prefetch(regs[i-1].regmap);
- if(dops[i].is_jump)
- {
- if(ba[i]<start || ba[i]>=(start+slen*4))
- {
- // Branch out of this block, flush all regs
- if (dops[i].is_ujump)
- {
- // Unconditional branch
- will_dirty_i=0;
- wont_dirty_i=0;
- // Merge in delay slot (will dirty)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(branch_regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
- if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- }
- }
- }
- else
- {
- // Conditional branch
- will_dirty_i=0;
- wont_dirty_i=wont_dirty_next;
- // Merge in delay slot (will dirty)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if (1) { // !dops[i].likely)
- // Might not dirty if likely branch is not taken
- if(branch_regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(branch_regs[i].regmap[r]==0) will_dirty_i&=~(1<<r);
- if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- //if(regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- //if(regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- }
- }
- }
- }
- // Merge in delay slot (wont dirty)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(regs[i].regmap[r]==dops[i].rt1) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt2) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt1) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
- }
- }
- if(wr) {
- #ifndef DESTRUCTIVE_WRITEBACK
- branch_regs[i].dirty&=wont_dirty_i;
- #endif
- branch_regs[i].dirty|=will_dirty_i;
- }
- }
- else
- {
- // Internal branch
- if(ba[i]<=start+i*4) {
- // Backward branch
- if (dops[i].is_ujump)
- {
- // Unconditional branch
- temp_will_dirty=0;
- temp_wont_dirty=0;
- // Merge in delay slot (will dirty)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(branch_regs[i].regmap[r]==dops[i].rt1) temp_will_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) temp_will_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) temp_will_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) temp_will_dirty|=1<<r;
- if(branch_regs[i].regmap[r]>33) temp_will_dirty&=~(1<<r);
- if(branch_regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
- if(branch_regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt1) temp_will_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt2) temp_will_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) temp_will_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) temp_will_dirty|=1<<r;
- if(regs[i].regmap[r]>33) temp_will_dirty&=~(1<<r);
- if(regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
- if(regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
- }
- }
- } else {
- // Conditional branch (not taken case)
- temp_will_dirty=will_dirty_next;
- temp_wont_dirty=wont_dirty_next;
- // Merge in delay slot (will dirty)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if (1) { // !dops[i].likely)
- // Will not dirty if likely branch is not taken
- if(branch_regs[i].regmap[r]==dops[i].rt1) temp_will_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) temp_will_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) temp_will_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) temp_will_dirty|=1<<r;
- if(branch_regs[i].regmap[r]>33) temp_will_dirty&=~(1<<r);
- if(branch_regs[i].regmap[r]==0) temp_will_dirty&=~(1<<r);
- if(branch_regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
- //if(regs[i].regmap[r]==dops[i].rt1) temp_will_dirty|=1<<r;
- //if(regs[i].regmap[r]==dops[i].rt2) temp_will_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) temp_will_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) temp_will_dirty|=1<<r;
- if(regs[i].regmap[r]>33) temp_will_dirty&=~(1<<r);
- if(regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
- if(regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
- }
- }
- }
- }
- // Merge in delay slot (wont dirty)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(regs[i].regmap[r]==dops[i].rt1) temp_wont_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt2) temp_wont_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) temp_wont_dirty|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) temp_wont_dirty|=1<<r;
- if(regs[i].regmap[r]==CCREG) temp_wont_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt1) temp_wont_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) temp_wont_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) temp_wont_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) temp_wont_dirty|=1<<r;
- if(branch_regs[i].regmap[r]==CCREG) temp_wont_dirty|=1<<r;
- }
- }
- // Deal with changed mappings
- if(i<iend) {
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(regs[i].regmap[r]!=regmap_pre[i][r]) {
- temp_will_dirty&=~(1<<r);
- temp_wont_dirty&=~(1<<r);
- if(regmap_pre[i][r]>0 && regmap_pre[i][r]<34) {
- temp_will_dirty|=((unneeded_reg[i]>>regmap_pre[i][r])&1)<<r;
- temp_wont_dirty|=((unneeded_reg[i]>>regmap_pre[i][r])&1)<<r;
- } else {
- temp_will_dirty|=1<<r;
- temp_wont_dirty|=1<<r;
- }
- }
- }
- }
- }
- if(wr) {
- will_dirty[i]=temp_will_dirty;
- wont_dirty[i]=temp_wont_dirty;
- clean_registers((ba[i]-start)>>2,i-1,0);
- }else{
- // Limit recursion. It can take an excessive amount
- // of time if there are a lot of nested loops.
- will_dirty[(ba[i]-start)>>2]=0;
- wont_dirty[(ba[i]-start)>>2]=-1;
- }
- }
- /*else*/ if(1)
- {
- if (dops[i].is_ujump)
- {
- // Unconditional branch
- will_dirty_i=0;
- wont_dirty_i=0;
- //if(ba[i]>start+i*4) { // Disable recursion (for debugging)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(branch_regs[i].regmap[r]==regs[(ba[i]-start)>>2].regmap_entry[r]) {
- will_dirty_i|=will_dirty[(ba[i]-start)>>2]&(1<<r);
- wont_dirty_i|=wont_dirty[(ba[i]-start)>>2]&(1<<r);
- }
- if(branch_regs[i].regmap[r]>=0) {
- will_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>branch_regs[i].regmap[r])&1)<<r;
- wont_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>branch_regs[i].regmap[r])&1)<<r;
- }
- }
- }
- //}
- // Merge in delay slot
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(branch_regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
- if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- }
- }
- } else {
- // Conditional branch
- will_dirty_i=will_dirty_next;
- wont_dirty_i=wont_dirty_next;
- //if(ba[i]>start+i*4) // Disable recursion (for debugging)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- signed char target_reg=branch_regs[i].regmap[r];
- if(target_reg==regs[(ba[i]-start)>>2].regmap_entry[r]) {
- will_dirty_i&=will_dirty[(ba[i]-start)>>2]&(1<<r);
- wont_dirty_i|=wont_dirty[(ba[i]-start)>>2]&(1<<r);
- }
- else if(target_reg>=0) {
- will_dirty_i&=((unneeded_reg[(ba[i]-start)>>2]>>target_reg)&1)<<r;
- wont_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>target_reg)&1)<<r;
- }
- }
- }
- // Merge in delay slot
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if (1) { // !dops[i].likely)
- // Might not dirty if likely branch is not taken
- if(branch_regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) will_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
- if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- //if(regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- //if(regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- }
- }
- }
- }
- // Merge in delay slot (won't dirty)
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(regs[i].regmap[r]==dops[i].rt1) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt2) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt1) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i+1].rt2) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt1) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i].rt2) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt1) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==dops[i+1].rt2) wont_dirty_i|=1<<r;
- if(branch_regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
- }
- }
- if(wr) {
- #ifndef DESTRUCTIVE_WRITEBACK
- branch_regs[i].dirty&=wont_dirty_i;
- #endif
- branch_regs[i].dirty|=will_dirty_i;
- }
- }
- }
- }
- else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
- {
- // SYSCALL instruction (software interrupt)
- will_dirty_i=0;
- wont_dirty_i=0;
- }
- else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
- {
- // ERET instruction (return from interrupt)
- will_dirty_i=0;
- wont_dirty_i=0;
- }
- will_dirty_next=will_dirty_i;
- wont_dirty_next=wont_dirty_i;
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(regs[i].regmap[r]==dops[i].rt1) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt2) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]>33) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
- if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt1) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i].rt2) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
- if(i>istart) {
- if (!dops[i].is_jump)
- {
- // Don't store a register immediately after writing it,
- // may prevent dual-issue.
- if(regs[i].regmap[r]==dops[i-1].rt1) wont_dirty_i|=1<<r;
- if(regs[i].regmap[r]==dops[i-1].rt2) wont_dirty_i|=1<<r;
- }
- }
- }
- }
- // Save it
- will_dirty[i]=will_dirty_i;
- wont_dirty[i]=wont_dirty_i;
- // Mark registers that won't be dirtied as not dirty
- if(wr) {
- regs[i].dirty|=will_dirty_i;
- #ifndef DESTRUCTIVE_WRITEBACK
- regs[i].dirty&=wont_dirty_i;
- if(dops[i].is_jump)
- {
- if (i < iend-1 && !dops[i].is_ujump) {
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(regs[i].regmap[r]==regmap_pre[i+2][r]) {
- regs[i+2].wasdirty&=wont_dirty_i|~(1<<r);
- }else {/*printf("i: %x (%d) mismatch(+2): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/}
- }
- }
- }
- }
- else
- {
- if(i<iend) {
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- if(regs[i].regmap[r]==regmap_pre[i+1][r]) {
- regs[i+1].wasdirty&=wont_dirty_i|~(1<<r);
- }else {/*printf("i: %x (%d) mismatch(+1): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/}
- }
- }
- }
- }
- #endif
- }
- // Deal with changed mappings
- temp_will_dirty=will_dirty_i;
- temp_wont_dirty=wont_dirty_i;
- for(r=0;r<HOST_REGS;r++) {
- if(r!=EXCLUDE_REG) {
- int nr;
- if(regs[i].regmap[r]==regmap_pre[i][r]) {
- if(wr) {
- #ifndef DESTRUCTIVE_WRITEBACK
- regs[i].wasdirty&=wont_dirty_i|~(1<<r);
- #endif
- regs[i].wasdirty|=will_dirty_i&(1<<r);
- }
- }
- else if(regmap_pre[i][r]>=0&&(nr=get_reg(regs[i].regmap,regmap_pre[i][r]))>=0) {
- // Register moved to a different register
- will_dirty_i&=~(1<<r);
- wont_dirty_i&=~(1<<r);
- will_dirty_i|=((temp_will_dirty>>nr)&1)<<r;
- wont_dirty_i|=((temp_wont_dirty>>nr)&1)<<r;
- if(wr) {
- #ifndef DESTRUCTIVE_WRITEBACK
- regs[i].wasdirty&=wont_dirty_i|~(1<<r);
- #endif
- regs[i].wasdirty|=will_dirty_i&(1<<r);
- }
- }
- else {
- will_dirty_i&=~(1<<r);
- wont_dirty_i&=~(1<<r);
- if(regmap_pre[i][r]>0 && regmap_pre[i][r]<34) {
- will_dirty_i|=((unneeded_reg[i]>>regmap_pre[i][r])&1)<<r;
- wont_dirty_i|=((unneeded_reg[i]>>regmap_pre[i][r])&1)<<r;
- } else {
- wont_dirty_i|=1<<r;
- /*printf("i: %x (%d) mismatch: %d\n",start+i*4,i,r);assert(!((will_dirty>>r)&1));*/
- }
- }
- }
- }
- }
-}
-
-#ifdef DISASM
-#include <inttypes.h>
-void print_regmap(const char *name, const signed char *regmap)
-{
- char buf[5];
- int i, l;
- fputs(name, stdout);
- for (i = 0; i < HOST_REGS; i++) {
- l = 0;
- if (regmap[i] >= 0)
- l = snprintf(buf, sizeof(buf), "$%d", regmap[i]);
- for (; l < 3; l++)
- buf[l] = ' ';
- buf[l] = 0;
- printf(" r%d=%s", i, buf);
- }
- fputs("\n", stdout);
-}