#define MAXBLOCK 4096
#define MAX_OUTPUT_BLOCK_SIZE 262144
-int cycle_multiplier; // 100 for 1.0
-#define CLOCK_ADJUST(x) (((x) * cycle_multiplier + 50) / 100)
-
struct regstat
{
signed char regmap_entry[HOST_REGS];
u_int isconst;
u_int loadedconst; // host regs that have constants loaded
u_int waswritten; // MIPS regs that were used as store base before
- uint64_t constmap[HOST_REGS];
};
struct ll_entry
uint64_t p32[MAXBLOCK];
uint64_t pr32[MAXBLOCK];
signed char regmap_pre[MAXBLOCK][HOST_REGS];
- signed char regmap[MAXBLOCK][HOST_REGS];
- signed char regmap_entry[MAXBLOCK][HOST_REGS];
- uint64_t constmap[MAXBLOCK][HOST_REGS];
- struct regstat regs[MAXBLOCK];
- struct regstat branch_regs[MAXBLOCK];
+ static uint64_t current_constmap[HOST_REGS];
+ static uint64_t constmap[MAXBLOCK][HOST_REGS];
+ static struct regstat regs[MAXBLOCK];
+ static struct regstat branch_regs[MAXBLOCK];
signed char minimum_free_regs[MAXBLOCK];
u_int needed_reg[MAXBLOCK];
uint64_t requires_32bit[MAXBLOCK];
//#define DEBUG_CYCLE_COUNT 1
+int cycle_multiplier; // 100 for 1.0
+
+static int CLOCK_ADJUST(int x)
+{
+ int s=(x>>31)|1;
+ return (x * cycle_multiplier + s * 50) / 100;
+}
+
static void tlb_hacks()
{
#ifndef DISABLE_TLB
for (hr=0;hr<HOST_REGS;hr++) {
if(cur->regmap[hr]==reg) {
cur->isconst|=1<<hr;
- cur->constmap[hr]=value;
+ current_constmap[hr]=value;
}
else if((cur->regmap[hr]^64)==reg) {
cur->isconst|=1<<hr;
- cur->constmap[hr]=value>>32;
+ current_constmap[hr]=value>>32;
}
}
}
if(!reg) return 0;
for (hr=0;hr<HOST_REGS;hr++) {
if(cur->regmap[hr]==reg) {
- return cur->constmap[hr];
+ return current_constmap[hr];
}
}
printf("Unknown constant in r%d\n",reg);
uu&=~(1LL<<us2[i]);
gte_u&=~gte_rs[i];
if(gte_rs[i]&&rt1[i]&&(unneeded_reg[i+1]&(1ll<<rt1[i])))
- gte_u|=gte_rs[i]; // MFC2/CFC2 to dead register, unneeded
+ gte_u|=gte_rs[i]>e_unneeded[i+1]; // MFC2/CFC2 to dead register, unneeded
// Source-target dependencies
uu&=~(tdep<<dep1[i]);
uu&=~(tdep<<dep2[i]);
gte_rs[i]=gte_reg_reads[source[i]&0x3f];
gte_rt[i]=gte_reg_writes[source[i]&0x3f];
gte_rt[i]|=1ll<<63; // every op changes flags
+ if((source[i]&0x3f)==GTE_MVMVA) {
+ int v = (source[i] >> 15) & 3;
+ gte_rs[i]&=~0xe3fll;
+ if(v==3) gte_rs[i]|=0xe00ll;
+ else gte_rs[i]|=3ll<<(v*2);
+ }
break;
case FLOAT:
case FCONV:
branch_regs[i-1].is32|=1LL<<31;
}
memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
- memcpy(constmap[i],constmap[i-1],sizeof(current.constmap));
+ memcpy(constmap[i],constmap[i-1],sizeof(current_constmap));
break;
case RJUMP:
memcpy(&branch_regs[i-1],¤t,sizeof(current));
}
#endif
memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
- memcpy(constmap[i],constmap[i-1],sizeof(current.constmap));
+ memcpy(constmap[i],constmap[i-1],sizeof(current_constmap));
break;
case CJUMP:
if((opcode[i-1]&0x3E)==4) // BEQ/BNE
branch_regs[i-1].isconst=0;
branch_regs[i-1].wasconst=0;
memcpy(&branch_regs[i-1].regmap_entry,¤t.regmap,sizeof(current.regmap));
- memcpy(constmap[i],constmap[i-1],sizeof(current.constmap));
+ memcpy(constmap[i],constmap[i-1],sizeof(current_constmap));
}
else
if((opcode[i-1]&0x3E)==6) // BLEZ/BGTZ
branch_regs[i-1].isconst=0;
branch_regs[i-1].wasconst=0;
memcpy(&branch_regs[i-1].regmap_entry,¤t.regmap,sizeof(current.regmap));
- memcpy(constmap[i],constmap[i-1],sizeof(current.constmap));
+ memcpy(constmap[i],constmap[i-1],sizeof(current_constmap));
}
else
// Alloc the delay slot in case the branch is taken
branch_regs[i-1].isconst=0;
branch_regs[i-1].wasconst=0;
memcpy(&branch_regs[i-1].regmap_entry,¤t.regmap,sizeof(current.regmap));
- memcpy(constmap[i],constmap[i-1],sizeof(current.constmap));
+ memcpy(constmap[i],constmap[i-1],sizeof(current_constmap));
}
else
// Alloc the delay slot in case the branch is taken
regs[i].is32=current.is32;
regs[i].dirty=current.dirty;
regs[i].isconst=current.isconst;
- memcpy(constmap[i],current.constmap,sizeof(current.constmap));
+ memcpy(constmap[i],current_constmap,sizeof(current_constmap));
}
for(hr=0;hr<HOST_REGS;hr++) {
if(hr!=EXCLUDE_REG&®s[i].regmap[hr]>=0) {