X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=deps%2Flightrec%2Fregcache.c;h=41d37789d004673e7f6d59a387e3a57e0ebb6fde;hb=8afce295870dc97704b0e9e1efe1801b6b56090d;hp=2a7ffe92b2032100b50b51272fae8c42bae27577;hpb=384af87540d751ef274e5956d58f4bbc153a34a9;p=pcsx_rearmed.git diff --git a/deps/lightrec/regcache.c b/deps/lightrec/regcache.c index 2a7ffe92..41d37789 100644 --- a/deps/lightrec/regcache.c +++ b/deps/lightrec/regcache.c @@ -11,7 +11,7 @@ #include #include -#define REG_PC (offsetof(struct lightrec_state, next_pc) / sizeof(u32)) +#define REG_PC (offsetof(struct lightrec_state, curr_pc) / sizeof(u32)) enum reg_priority { REG_IS_TEMP, @@ -296,6 +296,21 @@ void lightrec_temp_set_value(struct regcache *cache, u8 jit_reg, intptr_t value) nreg->value = value; } +u8 lightrec_alloc_reg_temp_with_value(struct regcache *cache, + jit_state_t *_jit, intptr_t value) +{ + s8 reg; + + reg = lightrec_get_reg_with_value(cache, value); + if (reg < 0) { + reg = lightrec_alloc_reg_temp(cache, _jit); + jit_movi((u8)reg, value); + lightrec_temp_set_value(cache, (u8)reg, value); + } + + return (u8)reg; +} + u8 lightrec_alloc_reg_out(struct regcache *cache, jit_state_t *_jit, u16 reg, u8 flags) { @@ -358,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; @@ -400,6 +414,22 @@ u8 lightrec_alloc_reg_in(struct regcache *cache, jit_state_t *_jit, return jit_reg; } +void lightrec_remap_reg(struct regcache *cache, jit_state_t *_jit, + u8 jit_reg, u16 reg_out, bool discard) +{ + struct native_register *nreg; + + lightrec_discard_reg_if_loaded(cache, reg_out); + + nreg = lightning_reg_to_lightrec(cache, jit_reg); + clean_reg(_jit, nreg, jit_reg, !discard); + + nreg->output = true; + nreg->emulated_register = reg_out; + nreg->extend = nreg->extended; + nreg->zero_extend = nreg->zero_extended; +} + static bool reg_pc_is_mapped(struct regcache *cache) { struct native_register *nreg = lightning_reg_to_lightrec(cache, JIT_V0); @@ -422,20 +452,30 @@ void lightrec_load_next_pc_imm(struct regcache *cache, jit_state_t *_jit, u32 pc, u32 imm) { struct native_register *nreg = lightning_reg_to_lightrec(cache, JIT_V0); + u8 reg = JIT_V0; + + if (lightrec_store_next_pc()) + reg = lightrec_alloc_reg_temp(cache, _jit); if (reg_pc_is_mapped(cache)) { /* JIT_V0 contains next PC - so we can overwrite it */ - lightrec_load_imm(cache, _jit, JIT_V0, pc, imm); + lightrec_load_imm(cache, _jit, reg, pc, imm); } else { /* JIT_V0 contains something else - invalidate it */ - lightrec_unload_reg(cache, _jit, JIT_V0); + if (reg == JIT_V0) + lightrec_unload_reg(cache, _jit, JIT_V0); - jit_movi(JIT_V0, imm); + jit_movi(reg, imm); } - nreg->prio = REG_IS_LOADED; - nreg->emulated_register = -1; - nreg->locked = true; + if (lightrec_store_next_pc()) { + jit_stxi_i(lightrec_offset(next_pc), LIGHTREC_REG_STATE, reg); + lightrec_free_reg(cache, reg); + } else { + nreg->prio = REG_IS_LOADED; + nreg->emulated_register = -1; + nreg->locked = true; + } } void lightrec_load_next_pc(struct regcache *cache, jit_state_t *_jit, u8 reg) @@ -444,6 +484,15 @@ void lightrec_load_next_pc(struct regcache *cache, jit_state_t *_jit, u8 reg) u16 offset; u8 jit_reg; + if (lightrec_store_next_pc()) { + jit_reg = lightrec_alloc_reg_in(cache, _jit, reg, 0); + offset = lightrec_offset(next_pc); + jit_stxi_i(offset, LIGHTREC_REG_STATE, jit_reg); + lightrec_free_reg(cache, jit_reg); + + return; + } + /* Invalidate JIT_V0 if it is not mapped to 'reg' */ nreg_v0 = lightning_reg_to_lightrec(cache, JIT_V0); if (nreg_v0->prio >= REG_IS_LOADED && nreg_v0->emulated_register != reg) @@ -453,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; @@ -481,10 +530,15 @@ void lightrec_load_next_pc(struct regcache *cache, jit_state_t *_jit, u8 reg) lightrec_discard_nreg(nreg); } - lightrec_clean_reg(cache, _jit, JIT_V0); + if (lightrec_store_next_pc()) { + jit_stxi_i(lightrec_offset(next_pc), + LIGHTREC_REG_STATE, JIT_V0); + } else { + lightrec_clean_reg(cache, _jit, JIT_V0); - nreg_v0->zero_extended = true; - nreg_v0->locked = true; + nreg_v0->zero_extended = true; + nreg_v0->locked = true; + } } static void free_reg(struct native_register *nreg) @@ -518,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); @@ -632,7 +686,7 @@ void lightrec_regcache_reset(struct regcache *cache) memset(&cache->lightrec_regs, 0, sizeof(cache->lightrec_regs)); } -void lightrec_preload_pc(struct regcache *cache) +void lightrec_preload_pc(struct regcache *cache, jit_state_t *_jit) { struct native_register *nreg; @@ -641,6 +695,8 @@ void lightrec_preload_pc(struct regcache *cache) nreg->emulated_register = REG_PC; nreg->prio = REG_IS_LOADED; nreg->zero_extended = true; + + jit_live(JIT_V0); } struct regcache * lightrec_regcache_init(struct lightrec_state *state)