Skip to content

Commit

Permalink
regcache: Add support for zero-extending registers
Browse files Browse the repository at this point in the history
With the REG_ZEXT flag, the lightrec_alloc_reg_{in,out} functions will
zero-extend the registers.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
  • Loading branch information
pcercuei committed Apr 25, 2021
1 parent 61716a6 commit 51d42d5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
32 changes: 27 additions & 5 deletions regcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
#include <stddef.h>

struct native_register {
bool used, loaded, dirty, output, extend, extended, locked;
bool used, loaded, dirty, output, extend, extended,
zero_extend, zero_extended, locked;
s8 emulated_register;
};

Expand Down Expand Up @@ -148,6 +149,7 @@ static struct native_register * alloc_in_out(struct regcache *cache,
static void lightrec_discard_nreg(struct native_register *nreg)
{
nreg->extended = false;
nreg->zero_extended = false;
nreg->loaded = false;
nreg->output = false;
nreg->dirty = false;
Expand Down Expand Up @@ -236,6 +238,7 @@ u8 lightrec_alloc_reg_out(struct regcache *cache, jit_state_t *_jit,
nreg->output = true;
nreg->emulated_register = reg;
nreg->extend = flags & REG_EXT;
nreg->zero_extend = flags & REG_ZEXT;
return jit_reg;
}

Expand Down Expand Up @@ -263,27 +266,43 @@ u8 lightrec_alloc_reg_in(struct regcache *cache, jit_state_t *_jit,
s16 offset = offsetof(struct lightrec_state, native_reg_cache)
+ (reg << 2);

nreg->zero_extended = flags & REG_ZEXT;
nreg->extended = !nreg->zero_extended;

/* Load previous value from register cache */
jit_ldxi_i(jit_reg, LIGHTREC_REG_STATE, offset);
if (nreg->zero_extended)
jit_ldxi_ui(jit_reg, LIGHTREC_REG_STATE, offset);
else
jit_ldxi_i(jit_reg, LIGHTREC_REG_STATE, offset);

nreg->loaded = true;
nreg->extended = true;
}

/* Clear register r0 before use */
if (reg == 0 && (!nreg->loaded || nreg->dirty)) {
jit_movi(jit_reg, 0);
nreg->extended = true;
nreg->zero_extended = true;
nreg->loaded = true;
}

nreg->used = true;
nreg->output = false;
nreg->emulated_register = reg;

if ((flags & REG_EXT) && !nreg->extended) {
if ((flags & REG_EXT) && !nreg->extended &&
(!nreg->zero_extended || !(flags & REG_ZEXT))) {
nreg->extended = true;
nreg->zero_extended = false;
#if __WORDSIZE == 64
jit_extr_i(jit_reg, jit_reg);
#endif
} else if (!(flags & REG_EXT) && (flags & REG_ZEXT) &&
!nreg->zero_extended) {
nreg->zero_extended = true;
nreg->extended = false;
#if __WORDSIZE == 64
jit_extr_ui(jit_reg, jit_reg);
#endif
}

Expand Down Expand Up @@ -311,6 +330,7 @@ u8 lightrec_request_reg_in(struct regcache *cache, jit_state_t *_jit,
jit_ldxi_i(jit_reg, LIGHTREC_REG_STATE, offset);

nreg->extended = true;
nreg->zero_extended = false;
nreg->used = true;
nreg->loaded = true;
nreg->emulated_register = reg;
Expand All @@ -323,8 +343,10 @@ static void free_reg(struct native_register *nreg)
/* Set output registers as dirty */
if (nreg->used && nreg->output && nreg->emulated_register > 0)
nreg->dirty = true;
if (nreg->output)
if (nreg->output) {
nreg->extended = nreg->extend;
nreg->zero_extended = nreg->zero_extend;
}
nreg->used = false;
}

Expand Down
1 change: 1 addition & 0 deletions regcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

/* Flags for lightrec_alloc_reg_in / lightrec_alloc_reg_out. */
#define REG_EXT BIT(0) /* register is sign-extended */
#define REG_ZEXT BIT(1) /* register is zero-extended */

struct register_value {
_Bool known;
Expand Down

0 comments on commit 51d42d5

Please sign in to comment.