static uint64_t unneeded_reg[MAXBLOCK];
static uint64_t branch_unneeded_reg[MAXBLOCK];
static signed char regmap_pre[MAXBLOCK][HOST_REGS]; // pre-instruction i?
- static uint64_t current_constmap[HOST_REGS];
- static uint64_t constmap[MAXBLOCK][HOST_REGS];
+ // contains 'real' consts at [i] insn, but may differ from what's actually
+ // loaded in host reg as 'final' value is always loaded, see get_final_value()
+ static uint32_t current_constmap[HOST_REGS];
+ static uint32_t constmap[MAXBLOCK][HOST_REGS];
static struct regstat regs[MAXBLOCK];
static struct regstat branch_regs[MAXBLOCK];
static signed char minimum_free_regs[MAXBLOCK];
}
}
-void set_const(struct regstat *cur,signed char reg,uint64_t value)
+static void set_const(struct regstat *cur, signed char reg, uint32_t value)
{
int hr;
if(!reg) return;
}
}
-void clear_const(struct regstat *cur,signed char reg)
+static void clear_const(struct regstat *cur, signed char reg)
{
int hr;
if(!reg) return;
}
}
-int is_const(struct regstat *cur,signed char reg)
+static int is_const(struct regstat *cur, signed char reg)
{
int hr;
if(reg<0) return 0;
}
return 0;
}
-uint64_t get_const(struct regstat *cur,signed char reg)
+
+static uint32_t get_const(struct regstat *cur, signed char reg)
{
int hr;
if(!reg) return 0;
else clear_const(current,rt1[i]);
}
else {
- set_const(current,rt1[i],((long long)((short)imm[i]))<<16); // LUI
+ set_const(current,rt1[i],imm[i]<<16); // LUI
}
dirty_reg(current,rt1[i]);
}
s2l=get_reg(i_regs->regmap,rs2[i]);
if(rs2[i]==0) // rx<r0
{
- assert(s1l>=0);
- if(opcode2[i]==0x2a) // SLT
+ if(opcode2[i]==0x2a&&rs1[i]!=0) { // SLT
+ assert(s1l>=0);
emit_shrimm(s1l,31,t);
- else // SLTU (unsigned can not be less than zero)
+ }
+ else // SLTU (unsigned can not be less than zero, 0<0)
emit_zeroreg(t);
}
else if(rs1[i]==0) // r0<rx
//extern int cycle;
u_int hr,reglist=0;
- for(hr=0;hr<HOST_REGS;hr++)
+ assem_debug("//do_insn_cmp %08x\n", start+i*4);
+ for (hr = 0; hr < HOST_REGS; hr++)
if(regs[i].regmap[hr]>=0) reglist|=1<<hr;
save_regs(reglist);
+ // write out changed consts to match the interpreter
+ if (i > 0 && !bt[i]) {
+ for (hr = 0; hr < HOST_REGS; hr++) {
+ int reg = regs[i-1].regmap[hr];
+ if (hr == EXCLUDE_REG || reg < 0)
+ continue;
+ if (!((regs[i-1].isconst >> hr) & 1))
+ continue;
+ if (i > 1 && reg == regs[i-2].regmap[hr] && constmap[i-1][hr] == constmap[i-2][hr])
+ continue;
+ emit_movimm(constmap[i-1][hr],0);
+ emit_storereg(reg, 0);
+ }
+ }
emit_movimm(start+i*4,0);
emit_writeword(0,&pcaddr);
emit_far_call(do_insn_cmp);
//emit_writeword(0,&cycle);
(void)get_reg2;
restore_regs(reglist);
+ assem_debug("\\\\do_insn_cmp\n");
}
#else
#define drc_dbg_emit_do_cmp(x)
else if(*adj==0||invert) {
int cycles=CLOCK_ADJUST(count+2);
// faster loop HACK
+#if 0
if (t&&*adj) {
int rel=t-i;
if(-NO_CYCLE_PENALTY_THR<rel&&rel<0)
cycles=CLOCK_ADJUST(*adj)+count+2-*adj;
}
+#endif
emit_addimm_and_set_flags(cycles,HOST_CCREG);
jaddr=out;
emit_jns(0);
dirty_reg(&branch_regs[i-1],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(constmap[i]));
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(constmap[i]));
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(constmap[i]));
}
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(constmap[i]));
}
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(constmap[i]));
}
else
// Alloc the delay slot in case the branch is taken
if(!is_ds[i]) {
regs[i].dirty=current.dirty;
regs[i].isconst=current.isconst;
- memcpy(constmap[i],current_constmap,sizeof(current_constmap));
+ memcpy(constmap[i],current_constmap,sizeof(constmap[i]));
}
for(hr=0;hr<HOST_REGS;hr++) {
if(hr!=EXCLUDE_REG&®s[i].regmap[hr]>=0) {