}
// count insns needed for mov/orr #imm
#ifdef HAVE_ARMV7
- for (i = 2, u = v; i > 0; i--, u >>= 8)
+ for (i = 2, u = v; i > 0 && u; i--, u >>= 8)
while (u > 0xff && !(u & 3))
u >>= 2;
if (u) { // 3+ insns needed...
return;
}
#else
- for (i = 2, u = v; i > 0; i--, u >>= 8)
+ for (i = 2, u = v; i > 0 && u; i--, u >>= 8)
while (u > 0xff && !(u & 3))
u >>= 2;
if (u) { // 3+ insns needed...
rn = rd;
v >>= 8, ror2 -= 8/2;
+ if (v && s) {
+ elprintf(EL_STATUS|EL_SVP|EL_ANOMALY, "op+s %x value too big", op);
+ exit(1);
+ }
} while (v);
}
if (sz == 0)
return;
// need branch over pool if not at block end
- if (jumpover) {
+ if (jumpover < 0 && sz == sizeof(u32)) {
+ // hack for SVP drc (patch logic detects distance 4)
+ sz += sizeof(u32);
+ } else if (jumpover) {
pool += sizeof(u32);
emith_xbranch(A_COND_AL, (u8 *)pool + sz, 0);
}
static void tr_mov16_cond(int cond, int r, int val)
{
- emith_op_imm(cond, 0, A_OP_MOV, r, val);
+ emith_move_r_imm_c(cond, r, val);
hostreg_r[r] = -1;
}
tmpv = tr_cond_check(op);
if (tmpv != A_COND_AL) {
jump_op = tcache_ptr;
- EOP_MOV_IMM(0, 0, 0); // placeholder for branch
+ EOP_C_B(tmpv, 0, 0); // placeholder for branch
}
tr_mov16(0, *pc);
tr_r0_to_STACK(*pc);
tr_flush_dirty_ST();
tr_flush_dirty_pmcrs();
block_end = emit_block_epilogue(ccount, end_cond, jump_pc, pc);
- emith_pool_commit(0);
emith_flush();
+ emith_pool_commit(-1);
if (tcache_ptr - (u32 *)tcache > DRC_TCACHE_SIZE/4) {
elprintf(EL_ANOMALY|EL_STATUS|EL_SVP, "tcache overflow!\n");
// stats
nblocks++;
- //printf("%i blocks, %i bytes, k=%.3f\n", nblocks, (tcache_ptr - tcache)*4,
- // (double)(tcache_ptr - tcache) / (double)n_in_ops);
+ //printf("%i blocks, %i bytes, k=%.3f\n", nblocks, (u8 *)tcache_ptr - tcache,
+ // (double)((u8 *)tcache_ptr - tcache) / (double)n_in_ops);
#ifdef DUMP_BLOCK
{