From a80b0b42e107b8856f0a98ff562819404fe48849 Mon Sep 17 00:00:00 2001 From: kub Date: Tue, 11 Apr 2023 19:08:36 +0000 Subject: [PATCH] svp drc, fix crash in jump patch --- cpu/drc/emit_arm.c | 13 ++++++++++--- pico/carthw/svp/compiler.c | 10 +++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/cpu/drc/emit_arm.c b/cpu/drc/emit_arm.c index 5a62c8bb..d32954e0 100644 --- a/cpu/drc/emit_arm.c +++ b/cpu/drc/emit_arm.c @@ -479,7 +479,7 @@ static void emith_op_imm2(int cond, int s, int op, int rd, int rn, unsigned int } // 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... @@ -492,7 +492,7 @@ static void emith_op_imm2(int cond, int s, int op, int rd, int rn, unsigned int 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... @@ -559,6 +559,10 @@ static void emith_op_imm2(int cond, int s, int op, int rd, int rn, unsigned int 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); } @@ -617,7 +621,10 @@ static void emith_pool_commit(int jumpover) 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); } diff --git a/pico/carthw/svp/compiler.c b/pico/carthw/svp/compiler.c index c48c665c..c472a600 100644 --- a/pico/carthw/svp/compiler.c +++ b/pico/carthw/svp/compiler.c @@ -359,7 +359,7 @@ static void tr_mov16(int r, int val) 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; } @@ -1437,7 +1437,7 @@ static int translate_op(unsigned int op, int *pc, int imm, int *end_cond, int *j 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); @@ -1792,8 +1792,8 @@ void *ssp_translate_block(int 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"); @@ -1803,8 +1803,8 @@ void *ssp_translate_block(int pc) // 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 { -- 2.39.5