svp drc, fix crash in jump patch
authorkub <derkub@gmail.com>
Tue, 11 Apr 2023 19:08:36 +0000 (19:08 +0000)
committerkub <derkub@gmail.com>
Tue, 11 Apr 2023 19:08:36 +0000 (19:08 +0000)
cpu/drc/emit_arm.c
pico/carthw/svp/compiler.c

index 5a62c8b..d32954e 100644 (file)
@@ -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);
        }
index c48c665..c472a60 100644 (file)
@@ -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
        {