git subrepo pull --force deps/lightrec
authorPaul Cercueil <paul@crapouillou.net>
Tue, 11 Jun 2024 08:34:16 +0000 (10:34 +0200)
committerPaul Cercueil <paul@crapouillou.net>
Tue, 11 Jun 2024 08:37:31 +0000 (10:37 +0200)
subrepo:
  subdir:   "deps/lightrec"
  merged:   "bd0b827922"
upstream:
  origin:   "https://github.com/pcercuei/lightrec.git"
  branch:   "master"
  commit:   "bd0b827922"
git-subrepo:
  version:  "0.4.6"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "110b9eb"

deps/lightrec/.gitrepo
deps/lightrec/constprop.c
deps/lightrec/disassembler.c
deps/lightrec/emitter.c
deps/lightrec/lightrec-private.h
deps/lightrec/lightrec.c
deps/lightrec/optimizer.c
deps/lightrec/regcache.c

index 73ce0b7..9e04deb 100644 (file)
@@ -6,7 +6,7 @@
 [subrepo]
        remote = https://github.com/pcercuei/lightrec.git
        branch = master
-       commit = 8d3db1a4e76c7b81301013f18650011b7e5eabf3
-       parent = fcd42d7decc2ed71801e4cbe575c4d2726b2743e
+       commit = bd0b82792284f22566bbfc78d8882e1e91b10516
+       parent = 1229a4ea3dea3e1e47c46cd7afed38860fd91a57
        method = merge
        cmdver = 0.4.6
index b21339a..97670bc 100644 (file)
@@ -736,7 +736,7 @@ lightrec_get_constprop_map(const struct lightrec_state *state,
        if ((min & 0xe0000000) != (max & 0xe0000000))
                return PSX_MAP_UNKNOWN;
 
-       pr_debug("Min: 0x%08x max: 0x%08x Known: 0x%08x Sign: 0x%08x\n",
+       pr_debug("Min: "X32_FMT" max: "X32_FMT" Known: "X32_FMT" Sign: "X32_FMT"\n",
                 min, max, v[reg].known, v[reg].sign);
 
        min = kunseg(min);
index 5111d17..f0aef60 100644 (file)
@@ -333,7 +333,7 @@ static int print_op_special(union code c, char *buf, size_t len,
                                lightrec_reg_name(c.r.rs),
                                lightrec_reg_name(c.r.rt));
        default:
-               return snprintf(buf, len, "unknown (0x%08x)", c.opcode);
+               return snprintf(buf, len, "unknown ("X32_FMT")", c.opcode);
        }
 }
 
@@ -362,7 +362,7 @@ static int print_op_cp(union code c, char *buf, size_t len, unsigned int cp)
                case OP_CP0_RFE:
                        return snprintf(buf, len, "rfe     ");
                default:
-                       return snprintf(buf, len, "unknown (0x%08x)", c.opcode);
+                       return snprintf(buf, len, "unknown ("X32_FMT")", c.opcode);
                }
        }
 }
@@ -380,7 +380,7 @@ static int print_op(union code c, u32 pc, char *buf, size_t len,
        case OP_REGIMM:
                *flags_ptr = opcode_branch_flags;
                *nb_flags = ARRAY_SIZE(opcode_branch_flags);
-               return snprintf(buf, len, "%s%s,0x%x",
+               return snprintf(buf, len, "%s%s,0x%"PRIx32,
                                regimm_opcodes[c.i.rt],
                                lightrec_reg_name(c.i.rs),
                                pc + 4 + ((s16)c.i.imm << 2));
@@ -388,14 +388,14 @@ static int print_op(union code c, u32 pc, char *buf, size_t len,
        case OP_JAL:
                *flags_ptr = opcode_branch_flags;
                *nb_flags = ARRAY_SIZE(opcode_branch_flags);
-               return snprintf(buf, len, "%s0x%x",
+               return snprintf(buf, len, "%s0x%"PRIx32,
                                std_opcodes[c.i.op],
                                (pc & 0xf0000000) | (c.j.imm << 2));
        case OP_BEQ:
                if (c.i.rs == c.i.rt) {
                        *flags_ptr = opcode_branch_flags;
                        *nb_flags = ARRAY_SIZE(opcode_branch_flags);
-                       return snprintf(buf, len, "b       0x%x",
+                       return snprintf(buf, len, "b       0x%"PRIx32,
                                        pc + 4 + ((s16)c.i.imm << 2));
                }
                fallthrough;
@@ -404,7 +404,7 @@ static int print_op(union code c, u32 pc, char *buf, size_t len,
        case OP_BGTZ:
                *flags_ptr = opcode_branch_flags;
                *nb_flags = ARRAY_SIZE(opcode_branch_flags);
-               return snprintf(buf, len, "%s%s,%s,0x%x",
+               return snprintf(buf, len, "%s%s,%s,0x%"PRIx32,
                                std_opcodes[c.i.op],
                                lightrec_reg_name(c.i.rs),
                                lightrec_reg_name(c.i.rt),
@@ -482,7 +482,7 @@ static int print_op(union code c, u32 pc, char *buf, size_t len,
                                lightrec_reg_name(get_mult_div_lo(c)),
                                lightrec_reg_name(c.r.rs), c.r.op);
        default:
-               return snprintf(buf, len, "unknown (0x%08x)", c.opcode);
+               return snprintf(buf, len, "unknown ("X32_FMT")", c.opcode);
        }
 }
 
@@ -518,7 +518,7 @@ void lightrec_print_disassembly(const struct block *block, const u32 *code_ptr)
 
                print_flags(buf3, sizeof(buf3), op, flags_ptr, nb_flags, is_io);
 
-               printf("0x%08x (0x%x)\t%s%*c%s%*c%s\n", pc, i << 2,
+               printf(X32_FMT" (0x%x)\t%s%*c%s%*c%s\n", pc, i << 2,
                       buf, 30 - (int)count, ' ', buf2, 30 - (int)count2, ' ', buf3);
        }
 }
index e1a176c..8612119 100644 (file)
@@ -136,8 +136,7 @@ void lightrec_emit_jump_to_interpreter(struct lightrec_cstate *state,
        lightrec_load_imm(reg_cache, _jit, JIT_V0, block->pc,
                          block->pc + (offset << 2));
        if (lightrec_store_next_pc()) {
-             jit_stxi_i(offsetof(struct lightrec_state, next_pc),
-                        LIGHTREC_REG_STATE, JIT_V0);
+             jit_stxi_i(lightrec_offset(next_pc), LIGHTREC_REG_STATE, JIT_V0);
        }
 
        jit_movi(JIT_V1, (uintptr_t)block);
@@ -157,8 +156,7 @@ static void lightrec_emit_eob(struct lightrec_cstate *state,
        lightrec_load_imm(reg_cache, _jit, JIT_V0, block->pc,
                          block->pc + (offset << 2));
        if (lightrec_store_next_pc()) {
-             jit_stxi_i(offsetof(struct lightrec_state, next_pc),
-                        LIGHTREC_REG_STATE, JIT_V0);
+             jit_stxi_i(lightrec_offset(next_pc), LIGHTREC_REG_STATE, JIT_V0);
        }
 
        jit_subi(LIGHTREC_REG_CYCLE, LIGHTREC_REG_CYCLE, state->cycles);
@@ -1175,15 +1173,16 @@ static void call_to_c_wrapper(struct lightrec_cstate *state,
        /* Make sure JIT_R1 is not mapped; it will be used in the C wrapper. */
        tmp2 = lightrec_alloc_reg(reg_cache, _jit, JIT_R1);
 
+       jit_movi(tmp2, (unsigned int)wrapper << (1 + __WORDSIZE / 32));
+
        tmp = lightrec_get_reg_with_value(reg_cache,
-                                         (intptr_t) state->state->wrappers_eps[wrapper]);
+                                         (intptr_t) state->state->c_wrapper);
        if (tmp < 0) {
                tmp = lightrec_alloc_reg_temp(reg_cache, _jit);
-               jit_ldxi(tmp, LIGHTREC_REG_STATE,
-                        offsetof(struct lightrec_state, wrappers_eps[wrapper]));
+               jit_ldxi(tmp, LIGHTREC_REG_STATE, lightrec_offset(c_wrapper));
 
                lightrec_temp_set_value(reg_cache, tmp,
-                                       (intptr_t) state->state->wrappers_eps[wrapper]);
+                                       (intptr_t) state->state->c_wrapper);
        }
 
        lightrec_free_reg(reg_cache, tmp2);
@@ -1232,8 +1231,8 @@ static void rec_io(struct lightrec_cstate *state,
                 * wrapper that it should write the REG_TEMP register instead of
                 * the actual output register of the opcode. */
                zero = lightrec_alloc_reg_in(reg_cache, _jit, 0, 0);
-               jit_stxi_c(offsetof(struct lightrec_state, in_delay_slot_n),
-                           LIGHTREC_REG_STATE, zero);
+               jit_stxi_c(lightrec_offset(in_delay_slot_n),
+                          LIGHTREC_REG_STATE, zero);
                lightrec_free_reg(reg_cache, zero);
        }
 
@@ -1297,7 +1296,7 @@ static void rec_store_memory(struct lightrec_cstate *cstate,
        u8 rs, rt, tmp = 0, tmp2 = 0, tmp3, addr_reg, addr_reg2;
        s16 imm = (s16)c.i.imm;
        s32 simm = (s32)imm << (1 - lut_is_32bit(state));
-       s32 lut_offt = offsetof(struct lightrec_state, code_lut);
+       s32 lut_offt = lightrec_offset(code_lut);
        bool no_mask = op_flag_no_mask(op->flags);
        bool add_imm = c.i.imm &&
                (c.i.op == OP_META_SWU
@@ -1560,19 +1559,18 @@ static void rec_store_direct(struct lightrec_cstate *cstate, const struct block
 
        /* Write NULL to the code LUT to invalidate any block that's there */
        if (lut_is_32bit(state))
-               jit_stxi_i(offsetof(struct lightrec_state, code_lut), tmp, tmp3);
+               jit_stxi_i(lightrec_offset(code_lut), tmp, tmp3);
        else
-               jit_stxi(offsetof(struct lightrec_state, code_lut), tmp, tmp3);
+               jit_stxi(lightrec_offset(code_lut), tmp, tmp3);
 
        if (c.i.op == OP_META_SWU) {
                /* With a SWU opcode, we might have touched the following 32-bit
                 * word, so invalidate it as well */
                if (lut_is_32bit(state)) {
-                       jit_stxi_i(offsetof(struct lightrec_state, code_lut) + 4,
-                                  tmp, tmp3);
+                       jit_stxi_i(lightrec_offset(code_lut) + 4, tmp, tmp3);
                } else {
-                       jit_stxi(offsetof(struct lightrec_state, code_lut)
-                                + sizeof(uintptr_t), tmp, tmp3);
+                       jit_stxi(lightrec_offset(code_lut) + sizeof(uintptr_t),
+                                tmp, tmp3);
                }
        }
 
@@ -2058,17 +2056,13 @@ static void rec_exit_early(struct lightrec_cstate *state,
        tmp = lightrec_alloc_reg_temp(reg_cache, _jit);
 
        jit_movi(tmp, exit_code);
-       jit_stxi_i(offsetof(struct lightrec_state, exit_flags),
-                  LIGHTREC_REG_STATE, tmp);
+       jit_stxi_i(lightrec_offset(exit_flags), LIGHTREC_REG_STATE, tmp);
 
-       jit_ldxi_i(tmp, LIGHTREC_REG_STATE,
-                  offsetof(struct lightrec_state, target_cycle));
+       jit_ldxi_i(tmp, LIGHTREC_REG_STATE, lightrec_offset(target_cycle));
        jit_subr(tmp, tmp, LIGHTREC_REG_CYCLE);
        jit_movi(LIGHTREC_REG_CYCLE, 0);
-       jit_stxi_i(offsetof(struct lightrec_state, target_cycle),
-                  LIGHTREC_REG_STATE, tmp);
-       jit_stxi_i(offsetof(struct lightrec_state, current_cycle),
-                  LIGHTREC_REG_STATE, tmp);
+       jit_stxi_i(lightrec_offset(target_cycle), LIGHTREC_REG_STATE, tmp);
+       jit_stxi_i(lightrec_offset(current_cycle), LIGHTREC_REG_STATE, tmp);
 
        lightrec_free_reg(reg_cache, tmp);
 
@@ -2140,8 +2134,7 @@ rec_mfc0(struct lightrec_cstate *state, const struct block *block, u16 offset)
 
        rt = lightrec_alloc_reg_out(reg_cache, _jit, c.i.rt, REG_EXT);
 
-       jit_ldxi_i(rt, LIGHTREC_REG_STATE,
-                  offsetof(struct lightrec_state, regs.cp0[c.r.rd]));
+       jit_ldxi_i(rt, LIGHTREC_REG_STATE, lightrec_offset(regs.cp0[c.r.rd]));
 
        lightrec_free_reg(reg_cache, rt);
 }
@@ -2192,15 +2185,12 @@ rec_mtc0(struct lightrec_cstate *state, const struct block *block, u16 offset)
 
        rt = lightrec_alloc_reg_in(reg_cache, _jit, c.i.rt, 0);
 
-       if (c.r.rd != 13) {
-               jit_stxi_i(offsetof(struct lightrec_state, regs.cp0[c.r.rd]),
-                          LIGHTREC_REG_STATE, rt);
-       }
+       if (c.r.rd != 13)
+               jit_stxi_i(lightrec_offset(regs.cp0[c.r.rd]), LIGHTREC_REG_STATE, rt);
 
        if (c.r.rd == 12 || c.r.rd == 13) {
                tmp = lightrec_alloc_reg_temp(reg_cache, _jit);
-               jit_ldxi_i(tmp, LIGHTREC_REG_STATE,
-                          offsetof(struct lightrec_state, regs.cp0[13]));
+               jit_ldxi_i(tmp, LIGHTREC_REG_STATE, lightrec_offset(regs.cp0[13]));
 
                tmp2 = lightrec_alloc_reg_temp(reg_cache, _jit);
        }
@@ -2213,10 +2203,8 @@ rec_mtc0(struct lightrec_cstate *state, const struct block *block, u16 offset)
                jit_ori(tmp, tmp, 0x0300);
                jit_xori(tmp, tmp, 0x0300);
                jit_orr(tmp, tmp, tmp2);
-               jit_ldxi_i(tmp2, LIGHTREC_REG_STATE,
-                          offsetof(struct lightrec_state, regs.cp0[12]));
-               jit_stxi_i(offsetof(struct lightrec_state, regs.cp0[13]),
-                          LIGHTREC_REG_STATE, tmp);
+               jit_ldxi_i(tmp2, LIGHTREC_REG_STATE, lightrec_offset(regs.cp0[12]));
+               jit_stxi_i(lightrec_offset(regs.cp0[13]), LIGHTREC_REG_STATE, tmp);
                status = tmp2;
        }
 
@@ -2244,14 +2232,11 @@ rec_mtc0(struct lightrec_cstate *state, const struct block *block, u16 offset)
        if (c.r.rd == 12 || c.r.rd == 13) {
                to_end = jit_beqi(tmp, 0);
 
-               jit_ldxi_i(tmp2, LIGHTREC_REG_STATE,
-                          offsetof(struct lightrec_state, target_cycle));
+               jit_ldxi_i(tmp2, LIGHTREC_REG_STATE, lightrec_offset(target_cycle));
                jit_subr(tmp2, tmp2, LIGHTREC_REG_CYCLE);
                jit_movi(LIGHTREC_REG_CYCLE, 0);
-               jit_stxi_i(offsetof(struct lightrec_state, target_cycle),
-                          LIGHTREC_REG_STATE, tmp2);
-               jit_stxi_i(offsetof(struct lightrec_state, current_cycle),
-                          LIGHTREC_REG_STATE, tmp2);
+               jit_stxi_i(lightrec_offset(target_cycle), LIGHTREC_REG_STATE, tmp2);
+               jit_stxi_i(lightrec_offset(current_cycle), LIGHTREC_REG_STATE, tmp2);
 
 
                jit_patch(to_end);
@@ -2294,7 +2279,7 @@ static void rec_cp0_CTC0(struct lightrec_cstate *state,
 
 static unsigned int cp2d_i_offset(u8 reg)
 {
-       return offsetof(struct lightrec_state, regs.cp2d[reg]);
+       return lightrec_offset(regs.cp2d[reg]);
 }
 
 static unsigned int cp2d_s_offset(u8 reg)
@@ -2304,7 +2289,7 @@ static unsigned int cp2d_s_offset(u8 reg)
 
 static unsigned int cp2c_i_offset(u8 reg)
 {
-       return offsetof(struct lightrec_state, regs.cp2c[reg]);
+       return lightrec_offset(regs.cp2c[reg]);
 }
 
 static unsigned int cp2c_s_offset(u8 reg)
@@ -2586,8 +2571,7 @@ static void rec_cp0_RFE(struct lightrec_cstate *state,
        jit_note(__FILE__, __LINE__);
 
        status = lightrec_alloc_reg_temp(reg_cache, _jit);
-       jit_ldxi_i(status, LIGHTREC_REG_STATE,
-                  offsetof(struct lightrec_state, regs.cp0[12]));
+       jit_ldxi_i(status, LIGHTREC_REG_STATE, lightrec_offset(regs.cp0[12]));
 
        tmp = lightrec_alloc_reg_temp(reg_cache, _jit);
 
@@ -2597,10 +2581,8 @@ static void rec_cp0_RFE(struct lightrec_cstate *state,
        jit_andi(status, status, ~0xful);
        jit_orr(status, status, tmp);
 
-       jit_ldxi_i(tmp, LIGHTREC_REG_STATE,
-                  offsetof(struct lightrec_state, regs.cp0[13]));
-       jit_stxi_i(offsetof(struct lightrec_state, regs.cp0[12]),
-                  LIGHTREC_REG_STATE, status);
+       jit_ldxi_i(tmp, LIGHTREC_REG_STATE, lightrec_offset(regs.cp0[13]));
+       jit_stxi_i(lightrec_offset(regs.cp0[12]), LIGHTREC_REG_STATE, status);
 
        /* Exit dynarec in case there's a software interrupt.
         * exit_flags = !!(status & cause & 0x0300) & status; */
@@ -2608,8 +2590,7 @@ static void rec_cp0_RFE(struct lightrec_cstate *state,
        jit_andi(tmp, tmp, 0x0300);
        jit_nei(tmp, tmp, 0);
        jit_andr(tmp, tmp, status);
-       jit_stxi_i(offsetof(struct lightrec_state, exit_flags),
-                  LIGHTREC_REG_STATE, tmp);
+       jit_stxi_i(lightrec_offset(exit_flags), LIGHTREC_REG_STATE, tmp);
 
        lightrec_free_reg(reg_cache, status);
        lightrec_free_reg(reg_cache, tmp);
@@ -2662,16 +2643,7 @@ static void rec_meta_MOV(struct lightrec_cstate *state,
        unload_rd = OPT_EARLY_UNLOAD
                && LIGHTREC_FLAGS_GET_RD(op->flags) == LIGHTREC_REG_UNLOAD;
 
-       if (c.m.rs && !lightrec_reg_is_loaded(reg_cache, c.m.rs)) {
-               /* The source register is not yet loaded - we can load its value
-                * from the register cache directly into the target register. */
-               rd = lightrec_alloc_reg_out(reg_cache, _jit, c.m.rd, REG_EXT);
-
-               jit_ldxi_i(rd, LIGHTREC_REG_STATE,
-                          offsetof(struct lightrec_state, regs.gpr) + (c.m.rs << 2));
-
-               lightrec_free_reg(reg_cache, rd);
-       } else if (unload_rd) {
+       if (unload_rd) {
                /* If the destination register will be unloaded right after the
                 * MOV meta-opcode, we don't actually need to write any host
                 * register - we can just store the source register directly to
@@ -2681,8 +2653,7 @@ static void rec_meta_MOV(struct lightrec_cstate *state,
 
                rs = lightrec_alloc_reg_in(reg_cache, _jit, c.m.rs, 0);
 
-               jit_stxi_i(offsetof(struct lightrec_state, regs.gpr)
-                          + (c.m.rd << 2), LIGHTREC_REG_STATE, rs);
+               jit_stxi_i(lightrec_offset(regs.gpr) + (c.m.rd << 2), LIGHTREC_REG_STATE, rs);
 
                lightrec_free_reg(reg_cache, rs);
        } else {
index 0df9f93..920008c 100644 (file)
@@ -23,7 +23,8 @@
 #include <inttypes.h>
 #include <stdint.h>
 
-#define PC_FMT "PC 0x%08"PRIx32
+#define X32_FMT "0x%08"PRIx32
+#define PC_FMT "PC "X32_FMT
 
 #define ARRAY_SIZE(x) (sizeof(x) ? sizeof(x) / sizeof((x)[0]) : 0)
 
@@ -176,9 +177,9 @@ struct lightrec_state {
        u32 exit_flags;
        u32 old_cycle_counter;
        u32 cycles_per_op;
+       void *c_wrapper;
        struct block *dispatcher, *c_wrapper_block;
        void *c_wrappers[C_WRAPPERS_COUNT];
-       void *wrappers_eps[C_WRAPPERS_COUNT];
        struct blockcache *block_cache;
        struct recompiler *rec;
        struct lightrec_cstate *cstate;
@@ -201,6 +202,9 @@ struct lightrec_state {
        void *code_lut[];
 };
 
+#define lightrec_offset(ptr) \
+       offsetof(struct lightrec_state, ptr)
+
 u32 lightrec_rw(struct lightrec_state *state, union code op, u32 addr,
                u32 data, u32 *flags, struct block *block, u16 offset);
 
index 454007b..ec26bff 100644 (file)
@@ -942,9 +942,6 @@ static struct block * generate_wrapper(struct lightrec_state *state)
        struct block *block;
        jit_state_t *_jit;
        unsigned int i;
-       jit_node_t *addr[C_WRAPPERS_COUNT - 1];
-       jit_node_t *to_end[C_WRAPPERS_COUNT - 1];
-       u8 tmp = JIT_R1;
 
        block = lightrec_malloc(state, MEM_FOR_IR, sizeof(*block));
        if (!block)
@@ -961,20 +958,9 @@ static struct block * generate_wrapper(struct lightrec_state *state)
        jit_prolog();
        jit_tramp(256);
 
-       /* Add entry points */
-       for (i = C_WRAPPERS_COUNT - 1; i > 0; i--) {
-               jit_ldxi(tmp, LIGHTREC_REG_STATE,
-                        offsetof(struct lightrec_state, c_wrappers[i]));
-               to_end[i - 1] = jit_b();
-               addr[i - 1] = jit_indirect();
-       }
-
-       jit_ldxi(tmp, LIGHTREC_REG_STATE,
-                offsetof(struct lightrec_state, c_wrappers[0]));
-
-       for (i = 0; i < C_WRAPPERS_COUNT - 1; i++)
-               jit_patch(to_end[i]);
-       jit_movr(JIT_R1, tmp);
+       /* Load pointer to C wrapper */
+       jit_addr(JIT_R1, JIT_R1, LIGHTREC_REG_STATE);
+       jit_ldxi(JIT_R1, JIT_R1, lightrec_offset(c_wrappers));
 
        jit_epilog();
        jit_prolog();
@@ -982,7 +968,7 @@ static struct block * generate_wrapper(struct lightrec_state *state)
        /* Save all temporaries on stack */
        for (i = 0; i < NUM_TEMPS; i++) {
                if (i + FIRST_TEMP != 1) {
-                       jit_stxi(offsetof(struct lightrec_state, wrapper_regs[i]),
+                       jit_stxi(lightrec_offset(wrapper_regs[i]),
                                 LIGHTREC_REG_STATE, JIT_R(i + FIRST_TEMP));
                }
        }
@@ -993,29 +979,25 @@ static struct block * generate_wrapper(struct lightrec_state *state)
        jit_pushargr(LIGHTREC_REG_STATE);
        jit_pushargr(JIT_R2);
 
-       jit_ldxi_ui(JIT_R2, LIGHTREC_REG_STATE,
-                   offsetof(struct lightrec_state, target_cycle));
+       jit_ldxi_ui(JIT_R2, LIGHTREC_REG_STATE, lightrec_offset(target_cycle));
 
        /* state->current_cycle = state->target_cycle - delta; */
        jit_subr(LIGHTREC_REG_CYCLE, JIT_R2, LIGHTREC_REG_CYCLE);
-       jit_stxi_i(offsetof(struct lightrec_state, current_cycle),
-                  LIGHTREC_REG_STATE, LIGHTREC_REG_CYCLE);
+       jit_stxi_i(lightrec_offset(current_cycle), LIGHTREC_REG_STATE, LIGHTREC_REG_CYCLE);
 
        /* Call the wrapper function */
        jit_finishr(JIT_R1);
 
        /* delta = state->target_cycle - state->current_cycle */;
-       jit_ldxi_ui(LIGHTREC_REG_CYCLE, LIGHTREC_REG_STATE,
-                   offsetof(struct lightrec_state, current_cycle));
-       jit_ldxi_ui(JIT_R1, LIGHTREC_REG_STATE,
-                   offsetof(struct lightrec_state, target_cycle));
+       jit_ldxi_ui(LIGHTREC_REG_CYCLE, LIGHTREC_REG_STATE, lightrec_offset(current_cycle));
+       jit_ldxi_ui(JIT_R1, LIGHTREC_REG_STATE, lightrec_offset(target_cycle));
        jit_subr(LIGHTREC_REG_CYCLE, JIT_R1, LIGHTREC_REG_CYCLE);
 
        /* Restore temporaries from stack */
        for (i = 0; i < NUM_TEMPS; i++) {
                if (i + FIRST_TEMP != 1) {
                        jit_ldxi(JIT_R(i + FIRST_TEMP), LIGHTREC_REG_STATE,
-                                offsetof(struct lightrec_state, wrapper_regs[i]));
+                                lightrec_offset(wrapper_regs[i]));
                }
        }
 
@@ -1032,10 +1014,7 @@ static struct block * generate_wrapper(struct lightrec_state *state)
        if (!block->function)
                goto err_free_jit;
 
-       state->wrappers_eps[C_WRAPPERS_COUNT - 1] = block->function;
-
-       for (i = 0; i < C_WRAPPERS_COUNT - 1; i++)
-               state->wrappers_eps[i] = jit_address(addr[i]);
+       state->c_wrapper = block->function;
 
        if (ENABLE_DISASSEMBLER) {
                pr_debug("Wrapper block:\n");
@@ -1104,20 +1083,16 @@ static u32 lightrec_check_load_delay(struct lightrec_state *state, u32 pc, u8 re
 static void update_cycle_counter_before_c(jit_state_t *_jit)
 {
        /* update state->current_cycle */
-       jit_ldxi_i(JIT_R2, LIGHTREC_REG_STATE,
-                  offsetof(struct lightrec_state, target_cycle));
+       jit_ldxi_i(JIT_R2, LIGHTREC_REG_STATE, lightrec_offset(target_cycle));
        jit_subr(JIT_R1, JIT_R2, LIGHTREC_REG_CYCLE);
-       jit_stxi_i(offsetof(struct lightrec_state, current_cycle),
-                  LIGHTREC_REG_STATE, JIT_R1);
+       jit_stxi_i(lightrec_offset(current_cycle), LIGHTREC_REG_STATE, JIT_R1);
 }
 
 static void update_cycle_counter_after_c(jit_state_t *_jit)
 {
        /* Recalc the delta */
-       jit_ldxi_i(JIT_R1, LIGHTREC_REG_STATE,
-                  offsetof(struct lightrec_state, current_cycle));
-       jit_ldxi_i(JIT_R2, LIGHTREC_REG_STATE,
-                  offsetof(struct lightrec_state, target_cycle));
+       jit_ldxi_i(JIT_R1, LIGHTREC_REG_STATE, lightrec_offset(current_cycle));
+       jit_ldxi_i(JIT_R2, LIGHTREC_REG_STATE, lightrec_offset(target_cycle));
        jit_subr(LIGHTREC_REG_CYCLE, JIT_R2, JIT_R1);
 }
 
@@ -1125,7 +1100,7 @@ static void sync_next_pc(jit_state_t *_jit)
 {
        if (lightrec_store_next_pc()) {
                jit_ldxi_ui(JIT_V0, LIGHTREC_REG_STATE,
-                           offsetof(struct lightrec_state, next_pc));
+                           lightrec_offset(next_pc));
        }
 }
 
@@ -1133,7 +1108,8 @@ static struct block * generate_dispatcher(struct lightrec_state *state)
 {
        struct block *block;
        jit_state_t *_jit;
-       jit_node_t *to_end, *loop, *addr, *addr2, *addr3, *addr4, *addr5, *jmp, *jmp2;
+       jit_node_t *to_end, *loop, *loop2,
+                  *addr, *addr2, *addr3, *addr4, *addr5;
        unsigned int i;
        u32 offset;
 
@@ -1165,92 +1141,13 @@ static struct block * generate_dispatcher(struct lightrec_state *state)
        /* Call the block's code */
        jit_jmpr(JIT_V1);
 
-       if (OPT_REPLACE_MEMSET) {
-               /* Blocks will jump here when they need to call
-                * lightrec_memset() */
-               addr3 = jit_indirect();
-
-               jit_movr(JIT_V1, LIGHTREC_REG_CYCLE);
-
-               jit_prepare();
-               jit_pushargr(LIGHTREC_REG_STATE);
-
-               jit_finishi(lightrec_memset);
-               jit_retval(LIGHTREC_REG_CYCLE);
-
-               jit_ldxi_ui(JIT_V0, LIGHTREC_REG_STATE,
-                           offsetof(struct lightrec_state, regs.gpr[31]));
-               jit_subr(LIGHTREC_REG_CYCLE, JIT_V1, LIGHTREC_REG_CYCLE);
-
-               if (OPT_DETECT_IMPOSSIBLE_BRANCHES || OPT_HANDLE_LOAD_DELAYS)
-                       jmp = jit_b();
-       }
-
-       if (OPT_DETECT_IMPOSSIBLE_BRANCHES) {
-               /* Blocks will jump here when they reach a branch that should
-                * be executed with the interpreter, passing the branch's PC
-                * in JIT_V0 and the address of the block in JIT_V1. */
-               addr4 = jit_indirect();
-
-               sync_next_pc(_jit);
-               update_cycle_counter_before_c(_jit);
-
-               jit_prepare();
-               jit_pushargr(LIGHTREC_REG_STATE);
-               jit_pushargr(JIT_V1);
-               jit_pushargr(JIT_V0);
-               jit_finishi(lightrec_emulate_block);
-
-               jit_retval(JIT_V0);
-
-               update_cycle_counter_after_c(_jit);
-
-               if (OPT_HANDLE_LOAD_DELAYS)
-                       jmp2 = jit_b();
-
-       }
-
-       if (OPT_HANDLE_LOAD_DELAYS) {
-               /* Blocks will jump here when they reach a branch with a load
-                * opcode in its delay slot. The delay slot has already been
-                * executed; the load value is in (state->temp_reg), and the
-                * register number is in JIT_V1.
-                * Jump to a C function which will evaluate the branch target's
-                * first opcode, to make sure that it does not read the register
-                * in question; and if it does, handle it accordingly. */
-               addr5 = jit_indirect();
-
-               sync_next_pc(_jit);
-               update_cycle_counter_before_c(_jit);
-
-               jit_prepare();
-               jit_pushargr(LIGHTREC_REG_STATE);
-               jit_pushargr(JIT_V0);
-               jit_pushargr(JIT_V1);
-               jit_finishi(lightrec_check_load_delay);
-
-               jit_retval(JIT_V0);
-
-               update_cycle_counter_after_c(_jit);
-       }
-
        /* The block will jump here, with the number of cycles remaining in
         * LIGHTREC_REG_CYCLE */
        addr2 = jit_indirect();
 
        sync_next_pc(_jit);
 
-       if (OPT_HANDLE_LOAD_DELAYS && OPT_DETECT_IMPOSSIBLE_BRANCHES)
-             jit_patch(jmp2);
-
-       if (OPT_REPLACE_MEMSET
-           && (OPT_DETECT_IMPOSSIBLE_BRANCHES || OPT_HANDLE_LOAD_DELAYS)) {
-               jit_patch(jmp);
-       }
-
-       /* Store back the next PC to the lightrec_state structure */
-       offset = offsetof(struct lightrec_state, curr_pc);
-       jit_stxi_i(offset, LIGHTREC_REG_STATE, JIT_V0);
+       loop2 = jit_label();
 
        /* Jump to end if state->target_cycle < state->current_cycle */
        to_end = jit_blei(LIGHTREC_REG_CYCLE, 0);
@@ -1267,12 +1164,15 @@ static struct block * generate_dispatcher(struct lightrec_state *state)
                jit_lshi(JIT_V1, JIT_V1, 1);
        jit_add_state(JIT_V1, JIT_V1);
 
-       offset = offsetof(struct lightrec_state, code_lut);
+       offset = lightrec_offset(code_lut);
        if (lut_is_32bit(state))
                jit_ldxi_ui(JIT_V1, JIT_V1, offset);
        else
                jit_ldxi(JIT_V1, JIT_V1, offset);
 
+       /* Store back the current PC to the lightrec_state structure */
+       jit_stxi_i(lightrec_offset(curr_pc), LIGHTREC_REG_STATE, JIT_V0);
+
        /* If we get non-NULL, loop */
        jit_patch_at(jit_bnei(JIT_V1, 0), loop);
 
@@ -1309,8 +1209,7 @@ static struct block * generate_dispatcher(struct lightrec_state *state)
        }
 
        /* Reset JIT_V0 to the next PC */
-       jit_ldxi_ui(JIT_V0, LIGHTREC_REG_STATE,
-                   offsetof(struct lightrec_state, curr_pc));
+       jit_ldxi_ui(JIT_V0, LIGHTREC_REG_STATE, lightrec_offset(curr_pc));
 
        /* If we get non-NULL, loop */
        jit_patch_at(jit_bnei(JIT_V1, 0), loop);
@@ -1319,7 +1218,80 @@ static struct block * generate_dispatcher(struct lightrec_state *state)
        jit_note(__FILE__, __LINE__);
        jit_patch(to_end);
 
+       /* Store back the current PC to the lightrec_state structure */
+       jit_stxi_i(lightrec_offset(curr_pc), LIGHTREC_REG_STATE, JIT_V0);
+
        jit_retr(LIGHTREC_REG_CYCLE);
+
+       if (OPT_REPLACE_MEMSET) {
+               /* Blocks will jump here when they need to call
+                * lightrec_memset() */
+               addr3 = jit_indirect();
+
+               jit_movr(JIT_V1, LIGHTREC_REG_CYCLE);
+
+               jit_prepare();
+               jit_pushargr(LIGHTREC_REG_STATE);
+
+               jit_finishi(lightrec_memset);
+               jit_retval(LIGHTREC_REG_CYCLE);
+
+               jit_ldxi_ui(JIT_V0, LIGHTREC_REG_STATE, lightrec_offset(regs.gpr[31]));
+
+               jit_subr(LIGHTREC_REG_CYCLE, JIT_V1, LIGHTREC_REG_CYCLE);
+
+               jit_patch_at(jit_b(), loop2);
+       }
+
+       if (OPT_DETECT_IMPOSSIBLE_BRANCHES) {
+               /* Blocks will jump here when they reach a branch that should
+                * be executed with the interpreter, passing the branch's PC
+                * in JIT_V0 and the address of the block in JIT_V1. */
+               addr4 = jit_indirect();
+
+               sync_next_pc(_jit);
+               update_cycle_counter_before_c(_jit);
+
+               jit_prepare();
+               jit_pushargr(LIGHTREC_REG_STATE);
+               jit_pushargr(JIT_V1);
+               jit_pushargr(JIT_V0);
+               jit_finishi(lightrec_emulate_block);
+
+               jit_retval(JIT_V0);
+
+               update_cycle_counter_after_c(_jit);
+
+               jit_patch_at(jit_b(), loop2);
+
+       }
+
+       if (OPT_HANDLE_LOAD_DELAYS) {
+               /* Blocks will jump here when they reach a branch with a load
+                * opcode in its delay slot. The delay slot has already been
+                * executed; the load value is in (state->temp_reg), and the
+                * register number is in JIT_V1.
+                * Jump to a C function which will evaluate the branch target's
+                * first opcode, to make sure that it does not read the register
+                * in question; and if it does, handle it accordingly. */
+               addr5 = jit_indirect();
+
+               sync_next_pc(_jit);
+               update_cycle_counter_before_c(_jit);
+
+               jit_prepare();
+               jit_pushargr(LIGHTREC_REG_STATE);
+               jit_pushargr(JIT_V0);
+               jit_pushargr(JIT_V1);
+               jit_finishi(lightrec_check_load_delay);
+
+               jit_retval(JIT_V0);
+
+               update_cycle_counter_after_c(_jit);
+
+               jit_patch_at(jit_b(), loop2);
+       }
+
        jit_epilog();
 
        block->_jit = _jit;
@@ -1472,7 +1444,7 @@ static struct block * lightrec_precompile_block(struct lightrec_state *state,
        lightrec_register(MEM_FOR_MIPS_CODE, length);
 
        if (ENABLE_DISASSEMBLER) {
-               pr_debug("Disassembled block at PC: 0x%08x\n", block->pc);
+               pr_debug("Disassembled block at "PC_FMT"\n", block->pc);
                lightrec_print_disassembly(block, code);
        }
 
@@ -1747,8 +1719,8 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
                        block2 = lightrec_find_block(state->block_cache, offset);
                }
                if (block2) {
-                       pr_debug("Reap block 0x%08x as it's covered by block "
-                                "0x%08x\n", block2->pc, block->pc);
+                       pr_debug("Reap block "X32_FMT" as it's covered by block "
+                                X32_FMT"\n", block2->pc, block->pc);
 
                        /* Finally, reap the block. */
                        if (!ENABLE_THREADED_COMPILER) {
@@ -1766,7 +1738,7 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
                lightrec_reaper_continue(state->reaper);
 
        if (ENABLE_DISASSEMBLER) {
-               pr_debug("Compiling block at PC: 0x%08x\n", block->pc);
+               pr_debug("Compiling block at "PC_FMT"\n", block->pc);
                jit_disassemble();
        }
 
@@ -1789,7 +1761,7 @@ int lightrec_compile_block(struct lightrec_cstate *cstate,
        }
 
        if (oldjit) {
-               pr_debug("Block 0x%08x recompiled, reaping old jit context.\n",
+               pr_debug("Block "X32_FMT" recompiled, reaping old jit context.\n",
                         block->pc);
 
                if (ENABLE_THREADED_COMPILER) {
index cb9ba5b..0a3655b 100644 (file)
@@ -909,8 +909,8 @@ static int lightrec_transform_ops(struct lightrec_state *state, struct block *bl
                /* Transform all opcodes detected as useless to real NOPs
                 * (0x0: SLL r0, r0, #0) */
                if (op->opcode != 0 && is_nop(op->c)) {
-                       pr_debug("Converting useless opcode 0x%08x to NOP\n",
-                                       op->opcode);
+                       pr_debug("Converting useless opcode "X32_FMT" to NOP\n",
+                                op->opcode);
                        op->opcode = 0x0;
                }
 
@@ -1740,7 +1740,7 @@ static int lightrec_flag_io(struct lightrec_state *state, struct block *block)
                         * registers as address will never hit a code page. */
                        if (list->i.rs >= 28 && list->i.rs <= 29 &&
                            !state->maps[PSX_MAP_KERNEL_USER_RAM].ops) {
-                               pr_debug("Flaging opcode 0x%08x as not requiring invalidation\n",
+                               pr_debug("Flaging opcode "X32_FMT" as not requiring invalidation\n",
                                         list->opcode);
                                list->flags |= LIGHTREC_NO_INVALIDATE;
                        }
@@ -2245,7 +2245,7 @@ static int lightrec_replace_memset(struct lightrec_state *state, struct block *b
 
                if (i == ARRAY_SIZE(memset_code) - 1) {
                        /* success! */
-                       pr_debug("Block at PC 0x%x is a memset\n", block->pc);
+                       pr_debug("Block at "PC_FMT" is a memset\n", block->pc);
                        block_set_flags(block,
                                        BLOCK_IS_MEMSET | BLOCK_NEVER_COMPILE);
 
index 45d77c6..41d3778 100644 (file)
@@ -373,8 +373,7 @@ u8 lightrec_alloc_reg_in(struct regcache *cache, jit_state_t *_jit,
                lightrec_unload_nreg(cache, _jit, nreg, jit_reg);
 
        if (nreg->prio < REG_IS_LOADED && reg != 0) {
-               s16 offset = offsetof(struct lightrec_state, regs.gpr)
-                       + (reg << 2);
+               s16 offset = lightrec_offset(regs.gpr) + (reg << 2);
 
                nreg->zero_extended = flags & REG_ZEXT;
                nreg->extended = !nreg->zero_extended;
@@ -470,8 +469,7 @@ void lightrec_load_next_pc_imm(struct regcache *cache,
        }
 
        if (lightrec_store_next_pc()) {
-               jit_stxi_i(offsetof(struct lightrec_state, next_pc),
-                          LIGHTREC_REG_STATE, reg);
+               jit_stxi_i(lightrec_offset(next_pc), LIGHTREC_REG_STATE, reg);
                lightrec_free_reg(cache, reg);
        } else {
                nreg->prio = REG_IS_LOADED;
@@ -488,7 +486,7 @@ void lightrec_load_next_pc(struct regcache *cache, jit_state_t *_jit, u8 reg)
 
        if (lightrec_store_next_pc()) {
                jit_reg = lightrec_alloc_reg_in(cache, _jit, reg, 0);
-               offset = offsetof(struct lightrec_state, next_pc);
+               offset = lightrec_offset(next_pc);
                jit_stxi_i(offset, LIGHTREC_REG_STATE, jit_reg);
                lightrec_free_reg(cache, jit_reg);
 
@@ -504,7 +502,7 @@ void lightrec_load_next_pc(struct regcache *cache, jit_state_t *_jit, u8 reg)
        if (!nreg) {
                /* Not mapped - load the value from the register cache */
 
-               offset = offsetof(struct lightrec_state, regs.gpr) + (reg << 2);
+               offset = lightrec_offset(regs.gpr) + (reg << 2);
                jit_ldxi_ui(JIT_V0, LIGHTREC_REG_STATE, offset);
 
                nreg_v0->prio = REG_IS_LOADED;
@@ -533,7 +531,7 @@ void lightrec_load_next_pc(struct regcache *cache, jit_state_t *_jit, u8 reg)
        }
 
        if (lightrec_store_next_pc()) {
-               jit_stxi_i(offsetof(struct lightrec_state, next_pc),
+               jit_stxi_i(lightrec_offset(next_pc),
                           LIGHTREC_REG_STATE, JIT_V0);
        } else {
                lightrec_clean_reg(cache, _jit, JIT_V0);
@@ -574,7 +572,7 @@ static void clean_reg(jit_state_t *_jit,
 {
        /* If we get a dirty register, store back the old value */
        if (nreg->prio == REG_IS_DIRTY) {
-               s16 offset = offsetof(struct lightrec_state, regs.gpr)
+               s16 offset = lightrec_offset(regs.gpr)
                        + (nreg->emulated_register << 2);
 
                jit_stxi_i(offset, LIGHTREC_REG_STATE, jit_reg);