From 3107c849c014f9f26676ac7f8bc2592cb5c5de04 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 2 Sep 2024 12:54:37 +0200 Subject: [PATCH] git subrepo pull --force deps/lightrec subrepo: subdir: "deps/lightrec" merged: "ea20362c95" upstream: origin: "https://github.com/pcercuei/lightrec.git" branch: "master" commit: "ea20362c95" git-subrepo: version: "0.4.6" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "110b9eb" --- deps/lightrec/.gitrepo | 4 +-- deps/lightrec/constprop.c | 11 +++++- deps/lightrec/emitter.c | 76 ++++++++++++++++++--------------------- deps/lightrec/lightrec.c | 7 ++++ deps/lightrec/regcache.c | 12 +++++++ deps/lightrec/regcache.h | 2 ++ 6 files changed, 68 insertions(+), 44 deletions(-) diff --git a/deps/lightrec/.gitrepo b/deps/lightrec/.gitrepo index 698111964..0d3c14bf5 100644 --- a/deps/lightrec/.gitrepo +++ b/deps/lightrec/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/pcercuei/lightrec.git branch = master - commit = 601afca8e889bdda7040ff5c64f7bbd20d1d5f2c - parent = 459f02ad03fa10b5c403fed724d47fe5adfd5fb1 + commit = ea20362c9542f12fb6a0f27aa7df66b2af06b84d + parent = 8847df50c67c19c605f60a109d30556b74d08eee method = merge cmdver = 0.4.6 diff --git a/deps/lightrec/constprop.c b/deps/lightrec/constprop.c index 97670bcfc..d5002a822 100644 --- a/deps/lightrec/constprop.c +++ b/deps/lightrec/constprop.c @@ -59,7 +59,7 @@ static void lightrec_propagate_addi(u32 rs, u32 rd, const struct constprop_data *d, struct constprop_data *v) { - u32 end, bit, sum, min, mask, imm, value; + u32 end, bit, sum, min, max, mask, imm, value; struct constprop_data result = { .value = v[rd].value, .known = v[rd].known, @@ -110,6 +110,15 @@ static void lightrec_propagate_addi(u32 rs, u32 rd, * sign bits are known. */ min = get_min_value(&v[rs]) + get_min_value(d); + max = get_max_value(&v[rs]) + + get_max_value(d); + + /* The sum may have less sign bits */ + if ((s32)min < 0) + mask &= min & max; + else + mask &= ~(min | mask); + result.value = (min & mask) | (result.value & ~mask); result.known |= mask << carry; diff --git a/deps/lightrec/emitter.c b/deps/lightrec/emitter.c index a59ff1d7e..f84f049f5 100644 --- a/deps/lightrec/emitter.c +++ b/deps/lightrec/emitter.c @@ -1300,7 +1300,7 @@ static void rec_store_memory(struct lightrec_cstate *cstate, struct opcode *op = &block->opcode_list[offset]; jit_state_t *_jit = block->_jit; union code c = op->c; - u8 rs, rt, tmp = 0, tmp2 = 0, tmp3, addr_reg, addr_reg2; + u8 rs, rt, tmp = 0, tmp2 = 0, tmp3, addr_reg, addr_reg2, src_reg; s16 imm = (s16)c.i.imm; s32 simm = (s32)imm << (1 - lut_is_32bit(state)); s32 lut_offt = lightrec_offset(code_lut); @@ -1342,25 +1342,23 @@ static void rec_store_memory(struct lightrec_cstate *cstate, } rt = lightrec_alloc_reg_in(reg_cache, _jit, in_reg, 0); + src_reg = rt; if (is_big_endian() && swap_code && in_reg) { tmp3 = lightrec_alloc_reg_temp(reg_cache, _jit); jit_new_node_ww(swap_code, tmp3, rt); - if (c.i.op == OP_META_SWU) - jit_unstr(addr_reg2, tmp3, LIGHTNING_UNALIGNED_32BIT); - else - jit_new_node_www(code, imm, addr_reg2, tmp3); - - lightrec_free_reg(reg_cache, tmp3); - } else if (c.i.op == OP_META_SWU) { - jit_unstr(addr_reg2, rt, LIGHTNING_UNALIGNED_32BIT); - } else { - jit_new_node_www(code, imm, addr_reg2, rt); + lightrec_free_reg(reg_cache, rt); + src_reg = tmp3; } - lightrec_free_reg(reg_cache, rt); + if (c.i.op == OP_META_SWU) + jit_unstr(addr_reg2, src_reg, LIGHTNING_UNALIGNED_32BIT); + else + jit_new_node_www(code, imm, addr_reg2, src_reg); + + lightrec_free_reg(reg_cache, src_reg); if (invalidate) { tmp3 = lightrec_alloc_reg_in(reg_cache, _jit, 0, 0); @@ -1445,7 +1443,7 @@ static void rec_store_direct_no_invalidate(struct lightrec_cstate *cstate, jit_state_t *_jit = block->_jit; jit_node_t *to_not_ram, *to_end; bool swc2 = c.i.op == OP_SWC2; - u8 addr_reg, tmp, tmp2 = 0, rs, rt, in_reg = swc2 ? REG_TEMP : c.i.rt; + u8 addr_reg, tmp, tmp2 = 0, rs, rt, src_reg, in_reg = swc2 ? REG_TEMP : c.i.rt; s16 imm; jit_note(__FILE__, __LINE__); @@ -1489,25 +1487,23 @@ static void rec_store_direct_no_invalidate(struct lightrec_cstate *cstate, } rt = lightrec_alloc_reg_in(reg_cache, _jit, in_reg, 0); + src_reg = rt; if (is_big_endian() && swap_code && in_reg) { tmp2 = lightrec_alloc_reg_temp(reg_cache, _jit); jit_new_node_ww(swap_code, tmp2, rt); + src_reg = tmp2; - if (c.i.op == OP_META_SWU) - jit_unstr(tmp, tmp2, LIGHTNING_UNALIGNED_32BIT); - else - jit_new_node_www(code, imm, tmp, tmp2); - - lightrec_free_reg(reg_cache, tmp2); - } else if (c.i.op == OP_META_SWU) { - jit_unstr(tmp, rt, LIGHTNING_UNALIGNED_32BIT); - } else { - jit_new_node_www(code, imm, tmp, rt); + lightrec_free_reg(reg_cache, rt); } - lightrec_free_reg(reg_cache, rt); + if (c.i.op == OP_META_SWU) + jit_unstr(tmp, src_reg, LIGHTNING_UNALIGNED_32BIT); + else + jit_new_node_www(code, imm, tmp, src_reg); + + lightrec_free_reg(reg_cache, src_reg); lightrec_free_reg(reg_cache, tmp); } @@ -1521,7 +1517,7 @@ static void rec_store_direct(struct lightrec_cstate *cstate, const struct block jit_state_t *_jit = block->_jit; jit_node_t *to_not_ram, *to_end; bool swc2 = c.i.op == OP_SWC2; - u8 addr_reg, tmp, tmp2, tmp3, rs, rt, reg_imm; + u8 src_reg, addr_reg, tmp, tmp2, tmp3, rs, rt, reg_imm; u8 in_reg = swc2 ? REG_TEMP : c.i.rt; u32 mask; bool different_offsets = state->offset_ram != state->offset_scratch; @@ -1602,25 +1598,23 @@ static void rec_store_direct(struct lightrec_cstate *cstate, const struct block lightrec_free_reg(reg_cache, reg_imm); rt = lightrec_alloc_reg_in(reg_cache, _jit, in_reg, 0); + src_reg = rt; if (is_big_endian() && swap_code && in_reg) { tmp = lightrec_alloc_reg_temp(reg_cache, _jit); jit_new_node_ww(swap_code, tmp, rt); + src_reg = tmp; - if (c.i.op == OP_META_SWU) - jit_unstr(tmp2, tmp, LIGHTNING_UNALIGNED_32BIT); - else - jit_new_node_www(code, 0, tmp2, tmp); - - lightrec_free_reg(reg_cache, tmp); - } else if (c.i.op == OP_META_SWU) { - jit_unstr(tmp2, rt, LIGHTNING_UNALIGNED_32BIT); - } else { - jit_new_node_www(code, 0, tmp2, rt); + lightrec_free_reg(reg_cache, rt); } - lightrec_free_reg(reg_cache, rt); + if (c.i.op == OP_META_SWU) + jit_unstr(tmp2, src_reg, LIGHTNING_UNALIGNED_32BIT); + else + jit_new_node_www(code, 0, tmp2, src_reg); + + lightrec_free_reg(reg_cache, src_reg); lightrec_free_reg(reg_cache, tmp2); } @@ -1882,19 +1876,19 @@ static void rec_load_direct(struct lightrec_cstate *cstate, else addr_mask = 0x1fffffff; - reg_imm = lightrec_alloc_reg_temp_with_value(reg_cache, _jit, - addr_mask); if (!state->mirrors_mapped) { + reg_imm = lightrec_alloc_reg_temp_with_value(reg_cache, _jit, + addr_mask); jit_andi(tmp, addr_reg, BIT(28)); jit_rshi_u(tmp, tmp, 28 - 22); jit_orr(tmp, tmp, reg_imm); jit_andr(rt, addr_reg, tmp); + + lightrec_free_reg(reg_cache, reg_imm); } else { - jit_andr(rt, addr_reg, reg_imm); + rec_and_mask(cstate, _jit, rt, addr_reg, addr_mask); } - lightrec_free_reg(reg_cache, reg_imm); - if (state->offset_ram) { offt_reg = lightrec_get_reg_with_value(reg_cache, state->offset_ram); diff --git a/deps/lightrec/lightrec.c b/deps/lightrec/lightrec.c index ae1705318..5f6a8712f 100644 --- a/deps/lightrec/lightrec.c +++ b/deps/lightrec/lightrec.c @@ -3,6 +3,7 @@ * Copyright (C) 2014-2021 Paul Cercueil */ +#include "arch.h" #include "blockcache.h" #include "debug.h" #include "disassembler.h" @@ -1138,6 +1139,9 @@ static struct block * generate_dispatcher(struct lightrec_state *state) loop = jit_label(); + if (!arch_has_fast_mask()) + jit_movi(JIT_R1, 0x1fffffff); + /* Call the block's code */ jit_jmpr(JIT_V1); @@ -1582,6 +1586,9 @@ int lightrec_compile_block(struct lightrec_cstate *cstate, if (OPT_PRELOAD_PC && (block->flags & BLOCK_PRELOAD_PC)) lightrec_preload_pc(cstate->reg_cache, _jit); + if (!arch_has_fast_mask()) + lightrec_preload_imm(cstate->reg_cache, _jit, JIT_R1, 0x1fffffff); + cstate->cycles = 0; cstate->nb_local_branches = 0; cstate->nb_targets = 0; diff --git a/deps/lightrec/regcache.c b/deps/lightrec/regcache.c index 41d37789d..51ce9b9a6 100644 --- a/deps/lightrec/regcache.c +++ b/deps/lightrec/regcache.c @@ -699,6 +699,18 @@ void lightrec_preload_pc(struct regcache *cache, jit_state_t *_jit) jit_live(JIT_V0); } +void lightrec_preload_imm(struct regcache *cache, jit_state_t *_jit, + u8 jit_reg, u32 imm) +{ + struct native_register *nreg; + + nreg = lightning_reg_to_lightrec(cache, jit_reg); + nreg->prio = REG_IS_TEMP_VALUE; + nreg->value = imm; + + jit_live(jit_reg); +} + struct regcache * lightrec_regcache_init(struct lightrec_state *state) { struct regcache *cache; diff --git a/deps/lightrec/regcache.h b/deps/lightrec/regcache.h index 23a775cee..a8db39f3c 100644 --- a/deps/lightrec/regcache.h +++ b/deps/lightrec/regcache.h @@ -70,6 +70,8 @@ void lightrec_set_reg_out_flags(struct regcache *cache, u8 jit_reg, u8 flags); void lightrec_regcache_reset(struct regcache *cache); void lightrec_preload_pc(struct regcache *cache, jit_state_t *_jit); +void lightrec_preload_imm(struct regcache *cache, jit_state_t *_jit, + u8 jit_reg, u32 imm); void lightrec_free_reg(struct regcache *cache, u8 jit_reg); void lightrec_free_regs(struct regcache *cache);