-#define HOST_REGS 13
-#define HOST_CCREG 10
-#define HOST_BTREG 8
-#define EXCLUDE_REG 11
-
#define HOST_IMM8 1
#define HAVE_CMOV_IMM 1
#define HAVE_CONDITIONAL_CALL 1
r14 = lr (link register)
r15 = pc (program counter) */
+#define HOST_REGS 13
+#define HOST_CCREG 10
+#define HOST_BTREG 8
+#define EXCLUDE_REG 11
+
+// Note: FP is set to &dynarec_local when executing generated code.
+// Thus the local variables are actually global and not on the stack.
#define FP 11
#define LR 14
#define HOST_TEMPREG 14
-// Note: FP is set to &dynarec_local when executing generated code.
-// Thus the local variables are actually global and not on the stack.
+#ifndef __MACH__
+#define CALLER_SAVE_REGS 0x100f
+#else
+#define CALLER_SAVE_REGS 0x120f
+#endif
+#define PREFERRED_REG_FIRST 4
+#define PREFERRED_REG_LAST 9
extern char *invc_ptr;
#include "pcnt.h"
#include "arm_features.h"
-#define CALLER_SAVE_REGS 0x0007ffff
-
#define unused __attribute__((unused))
void do_memhandler_pre();
emit_jmp(stubs[n].retaddr); // return address (invcode check)
set_jump_target(handler_jump, out);
- // TODO FIXME: regalloc should prefer callee-saved regs
if(!regs_saved)
save_regs(reglist);
void *handler=NULL;
static void alloc_reg(struct regstat *cur,int i,signed char reg)
{
int r,hr;
- int preferred_reg = (reg&7);
- if(reg==CCREG) preferred_reg=HOST_CCREG;
- if(reg==PTEMP||reg==FTEMP) preferred_reg=12;
+ int preferred_reg = PREFERRED_REG_FIRST
+ + reg % (PREFERRED_REG_LAST - PREFERRED_REG_FIRST + 1);
+ if (reg == CCREG) preferred_reg = HOST_CCREG;
+ if (reg == PTEMP || reg == FTEMP) preferred_reg = 12;
+ assert(PREFERRED_REG_FIRST != EXCLUDE_REG && EXCLUDE_REG != HOST_REGS);
// Don't allocate unused registers
if((cur->u>>reg)&1) return;
if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;}
}
}
+
// Try to allocate any available register, but prefer
// registers that have not been used recently.
- if(i>0) {
- for(hr=0;hr<HOST_REGS;hr++) {
- if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
- if(regs[i-1].regmap[hr]!=dops[i-1].rs1&®s[i-1].regmap[hr]!=dops[i-1].rs2&®s[i-1].regmap[hr]!=dops[i-1].rt1&®s[i-1].regmap[hr]!=dops[i-1].rt2) {
+ if (i > 0) {
+ for (hr = PREFERRED_REG_FIRST; ; ) {
+ if (cur->regmap[hr] < 0) {
+ int oldreg = regs[i-1].regmap[hr];
+ if (oldreg < 0 || (oldreg != dops[i-1].rs1 && oldreg != dops[i-1].rs2
+ && oldreg != dops[i-1].rt1 && oldreg != dops[i-1].rt2))
+ {
cur->regmap[hr]=reg;
cur->dirty&=~(1<<hr);
cur->isconst&=~(1<<hr);
return;
}
}
+ hr++;
+ if (hr == EXCLUDE_REG)
+ hr++;
+ if (hr == HOST_REGS)
+ hr = 0;
+ if (hr == PREFERRED_REG_FIRST)
+ break;
}
}
+
// Try to allocate any available register
- for(hr=0;hr<HOST_REGS;hr++) {
- if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
+ for (hr = PREFERRED_REG_FIRST; ; ) {
+ if (cur->regmap[hr] < 0) {
cur->regmap[hr]=reg;
cur->dirty&=~(1<<hr);
cur->isconst&=~(1<<hr);
return;
}
+ hr++;
+ if (hr == EXCLUDE_REG)
+ hr++;
+ if (hr == HOST_REGS)
+ hr = 0;
+ if (hr == PREFERRED_REG_FIRST)
+ break;
}
// Ok, now we have to evict someone