Skip to content

Commit

Permalink
Merge pull request #844 from pcercuei/update-lightrec-20240902
Browse files Browse the repository at this point in the history
Update Lightrec 2024-09-02
  • Loading branch information
notaz committed Sep 2, 2024
2 parents 8847df5 + 3107c84 commit c0a75dc
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 44 deletions.
4 changes: 2 additions & 2 deletions deps/lightrec/.gitrepo
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 10 additions & 1 deletion deps/lightrec/constprop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
76 changes: 35 additions & 41 deletions deps/lightrec/emitter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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__);
Expand Down Expand Up @@ -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);
}

Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions deps/lightrec/lightrec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
12 changes: 12 additions & 0 deletions deps/lightrec/regcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions deps/lightrec/regcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit c0a75dc

Please sign in to comment.