git subrepo pull --force deps/lightrec
authorPaul Cercueil <paul@crapouillou.net>
Mon, 2 Sep 2024 10:54:37 +0000 (12:54 +0200)
committerPaul Cercueil <paul@crapouillou.net>
Mon, 2 Sep 2024 10:54:37 +0000 (12:54 +0200)
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
deps/lightrec/constprop.c
deps/lightrec/emitter.c
deps/lightrec/lightrec.c
deps/lightrec/regcache.c
deps/lightrec/regcache.h

index 6981119..0d3c14b 100644 (file)
@@ -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
index 97670bc..d5002a8 100644 (file)
@@ -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;
index a59ff1d..f84f049 100644 (file)
@@ -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);
index ae17053..5f6a871 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2014-2021 Paul Cercueil <paul@crapouillou.net>
  */
 
+#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;
index 41d3778..51ce9b9 100644 (file)
@@ -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;
index 23a775c..a8db39f 100644 (file)
@@ -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);