+static void alloc_set(struct regstat *cur, int reg, int hr)
+{
+ cur->regmap[hr] = reg;
+ cur->dirty &= ~(1u << hr);
+ cur->isconst &= ~(1u << hr);
+ cur->noevict |= 1u << hr;
+}
+
+static void evict_alloc_reg(struct regstat *cur, int i, int reg, int preferred_hr)
+{
+ u_char hsn[MAXREG+1];
+ int j, r, hr;
+ memset(hsn, 10, sizeof(hsn));
+ lsn(hsn, i);
+ //printf("hsn(%x): %d %d %d %d %d %d %d\n",start+i*4,hsn[cur->regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]);
+ if(i>0) {
+ // Don't evict the cycle count at entry points, otherwise the entry
+ // stub will have to write it.
+ if(dops[i].bt&&hsn[CCREG]>2) hsn[CCREG]=2;
+ if (i>1 && hsn[CCREG] > 2 && dops[i-2].is_jump) hsn[CCREG]=2;
+ for(j=10;j>=3;j--)
+ {
+ // Alloc preferred register if available
+ if (!((cur->noevict >> preferred_hr) & 1)
+ && hsn[cur->regmap[preferred_hr]] == j)
+ {
+ alloc_set(cur, reg, preferred_hr);
+ return;
+ }
+ for(r=1;r<=MAXREG;r++)
+ {
+ if(hsn[r]==j&&r!=dops[i-1].rs1&&r!=dops[i-1].rs2&&r!=dops[i-1].rt1&&r!=dops[i-1].rt2) {
+ for(hr=0;hr<HOST_REGS;hr++) {
+ if (hr == EXCLUDE_REG || ((cur->noevict >> hr) & 1))
+ continue;
+ if(hr!=HOST_CCREG||j<hsn[CCREG]) {
+ if(cur->regmap[hr]==r) {
+ alloc_set(cur, reg, hr);
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ for(j=10;j>=0;j--)
+ {
+ for(r=1;r<=MAXREG;r++)
+ {
+ if(hsn[r]==j) {
+ for(hr=0;hr<HOST_REGS;hr++) {
+ if (hr == EXCLUDE_REG || ((cur->noevict >> hr) & 1))
+ continue;
+ if(cur->regmap[hr]==r) {
+ alloc_set(cur, reg, hr);
+ return;
+ }
+ }
+ }
+ }
+ }
+ SysPrintf("This shouldn't happen (evict_alloc_reg)\n");
+ abort();
+}
+