X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=deps%2Flightrec%2Flightrec.c;h=ffa40f0938af4634c1607ad014cac6e269ceaa3f;hb=3e629be971c683d914844b487e366e0acf55539a;hp=ba734ad29b775fb398d812f80e139d60b0246c4b;hpb=d8b04acd965a598d4f952fe15a613582ff685d43;p=pcsx_rearmed.git diff --git a/deps/lightrec/lightrec.c b/deps/lightrec/lightrec.c index ba734ad2..ffa40f09 100644 --- a/deps/lightrec/lightrec.c +++ b/deps/lightrec/lightrec.c @@ -241,7 +241,7 @@ lightrec_get_map(struct lightrec_state *state, void **host, u32 kaddr) } u32 lightrec_rw(struct lightrec_state *state, union code op, - u32 addr, u32 data, u16 *flags, struct block *block) + u32 addr, u32 data, u32 *flags, struct block *block) { const struct lightrec_mem_map *map; const struct lightrec_mem_map_ops *ops; @@ -309,7 +309,7 @@ u32 lightrec_rw(struct lightrec_state *state, union code op, } static void lightrec_rw_helper(struct lightrec_state *state, - union code op, u16 *flags, + union code op, u32 *flags, struct block *block) { u32 ret = lightrec_rw(state, op, state->regs.gpr[op.i.rs], @@ -331,17 +331,16 @@ static void lightrec_rw_helper(struct lightrec_state *state, } } -static void lightrec_rw_cb(struct lightrec_state *state) +static void lightrec_rw_cb(struct lightrec_state *state, u32 arg) { - lightrec_rw_helper(state, (union code)state->c_wrapper_arg, NULL, NULL); + lightrec_rw_helper(state, (union code) arg, NULL, NULL); } -static void lightrec_rw_generic_cb(struct lightrec_state *state) +static void lightrec_rw_generic_cb(struct lightrec_state *state, u32 arg) { struct block *block; struct opcode *op; bool was_tagged; - u32 arg = state->c_wrapper_arg; u16 offset = (u16)arg; block = lightrec_find_block_from_lut(state->block_cache, @@ -362,6 +361,7 @@ static void lightrec_rw_generic_cb(struct lightrec_state *state) "for recompilation\n", block->pc); block->flags |= BLOCK_SHOULD_RECOMPILE; + lut_write(state, lut_offset(block->pc), NULL); } } @@ -370,6 +370,16 @@ static u32 clamp_s32(s32 val, s32 min, s32 max) return val < min ? min : val > max ? max : val; } +static u16 load_u16(u32 *ptr) +{ + return ((struct u16x2 *) ptr)->l; +} + +static void store_u16(u32 *ptr, u16 value) +{ + ((struct u16x2 *) ptr)->l = value; +} + static u32 lightrec_mfc2(struct lightrec_state *state, u8 reg) { s16 gteir1, gteir2, gteir3; @@ -382,18 +392,18 @@ static u32 lightrec_mfc2(struct lightrec_state *state, u8 reg) case 9: case 10: case 11: - return (s32)(s16) state->regs.cp2d[reg]; + return (s32)(s16) load_u16(&state->regs.cp2d[reg]); case 7: case 16: case 17: case 18: case 19: - return (u16) state->regs.cp2d[reg]; + return load_u16(&state->regs.cp2d[reg]); case 28: case 29: - gteir1 = (s16) state->regs.cp2d[9]; - gteir2 = (s16) state->regs.cp2d[10]; - gteir3 = (s16) state->regs.cp2d[11]; + gteir1 = (s16) load_u16(&state->regs.cp2d[9]); + gteir2 = (s16) load_u16(&state->regs.cp2d[10]); + gteir3 = (s16) load_u16(&state->regs.cp2d[11]); return clamp_s32(gteir1 >> 7, 0, 0x1f) << 0 | clamp_s32(gteir2 >> 7, 0, 0x1f) << 5 | @@ -519,16 +529,15 @@ static void lightrec_ctc2(struct lightrec_state *state, u8 reg, u32 data) case 27: case 29: case 30: - data = (s32)(s16) data; + store_u16(&state->regs.cp2c[reg], data); break; case 31: data = (data & 0x7ffff000) | !!(data & 0x7f87e000) << 31; fallthrough; default: + state->regs.cp2c[reg] = data; break; } - - state->regs.cp2c[reg] = data; } void lightrec_mtc(struct lightrec_state *state, union code op, u32 data) @@ -541,9 +550,9 @@ void lightrec_mtc(struct lightrec_state *state, union code op, u32 data) lightrec_mtc2(state, op.r.rd, data); } -static void lightrec_mtc_cb(struct lightrec_state *state) +static void lightrec_mtc_cb(struct lightrec_state *state, u32 arg) { - union code op = (union code) state->c_wrapper_arg; + union code op = (union code) arg; lightrec_mtc(state, op, state->regs.gpr[op.r.rt]); } @@ -572,9 +581,9 @@ void lightrec_cp(struct lightrec_state *state, union code op) (*state->ops.cop2_op)(state, op.opcode); } -static void lightrec_cp_cb(struct lightrec_state *state) +static void lightrec_cp_cb(struct lightrec_state *state, u32 arg) { - lightrec_cp(state, (union code) state->c_wrapper_arg); + lightrec_cp(state, (union code) arg); } static void lightrec_syscall_cb(struct lightrec_state *state) @@ -587,7 +596,7 @@ static void lightrec_break_cb(struct lightrec_state *state) lightrec_set_exit_flags(state, LIGHTREC_EXIT_BREAK); } -struct block * lightrec_get_block(struct lightrec_state *state, u32 pc) +static struct block * lightrec_get_block(struct lightrec_state *state, u32 pc) { struct block *block = lightrec_find_block(state->block_cache, pc); @@ -698,11 +707,11 @@ static void * get_next_block_func(struct lightrec_state *state, u32 pc) } static s32 c_function_wrapper(struct lightrec_state *state, s32 cycles_delta, - void (*f)(struct lightrec_state *)) + void (*f)(struct lightrec_state *, u32), u32 arg) { state->current_cycle = state->target_cycle - cycles_delta; - (*f)(state); + (*f)(state, arg); return state->target_cycle - state->current_cycle; } @@ -848,6 +857,8 @@ static struct block * generate_wrapper(struct lightrec_state *state) for (i = 0; i < NUM_TEMPS; i++) jit_stxi(stack_ptr + i * sizeof(uintptr_t), JIT_FP, JIT_R(i)); + jit_getarg(JIT_R1, jit_arg()); + /* Jump to the trampoline */ to_tramp = jit_jmpi(); @@ -880,6 +891,7 @@ static struct block * generate_wrapper(struct lightrec_state *state) jit_pushargr(LIGHTREC_REG_STATE); jit_pushargr(LIGHTREC_REG_CYCLE); jit_pushargr(JIT_R0); + jit_pushargr(JIT_R1); jit_finishi(c_function_wrapper); jit_retval_i(LIGHTREC_REG_CYCLE); @@ -1344,18 +1356,15 @@ int lightrec_compile_block(struct lightrec_cstate *cstate, continue; } - cstate->cycles += lightrec_cycles_of_opcode(elm->c); - if (should_emulate(elm)) { pr_debug("Branch at offset 0x%x will be emulated\n", i << 2); lightrec_emit_eob(cstate, block, i, false); - skip_next = !(elm->flags & LIGHTREC_NO_DS); + skip_next = !op_flag_no_ds(elm->flags); } else { lightrec_rec_opcode(cstate, block, i); - skip_next = has_delay_slot(elm->c) && - !(elm->flags & LIGHTREC_NO_DS); + skip_next = !op_flag_no_ds(elm->flags) && has_delay_slot(elm->c); #if _WIN32 /* FIXME: GNU Lightning on Windows seems to use our * mapped registers as temporaries. Until the actual bug @@ -1364,6 +1373,8 @@ int lightrec_compile_block(struct lightrec_cstate *cstate, lightrec_regcache_mark_live(cstate->reg_cache, _jit); #endif } + + cstate->cycles += lightrec_cycles_of_opcode(elm->c); } for (i = 0; i < cstate->nb_branches; i++) @@ -1392,11 +1403,7 @@ int lightrec_compile_block(struct lightrec_cstate *cstate, pr_err("Unable to find branch target\n"); } - jit_ldxi(JIT_R0, LIGHTREC_REG_STATE, - offsetof(struct lightrec_state, eob_wrapper_func)); - - jit_jmpr(JIT_R0); - + jit_patch_abs(jit_jmpi(), state->eob_wrapper_func); jit_ret(); jit_epilog(); @@ -1758,6 +1765,10 @@ void lightrec_destroy(struct lightrec_state *state) state->current_cycle = ~state->current_cycle; lightrec_print_info(state); + lightrec_free_block_cache(state->block_cache); + lightrec_free_block(state, state->dispatcher); + lightrec_free_block(state, state->c_wrapper_block); + if (ENABLE_THREADED_COMPILER) { lightrec_free_recompiler(state->rec); lightrec_reaper_destroy(state->reaper); @@ -1765,9 +1776,6 @@ void lightrec_destroy(struct lightrec_state *state) lightrec_free_cstate(state->cstate); } - lightrec_free_block_cache(state->block_cache); - lightrec_free_block(state, state->dispatcher); - lightrec_free_block(state, state->c_wrapper_block); finish_jit(); if (ENABLE_CODE_BUFFER && state->tlsf) tlsf_destroy(state->tlsf);