summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorAlessandro Gatti <a.gatti@frob.it>2024-08-01 21:21:38 +0200
committerDamien George <damien@micropython.org>2024-08-19 15:53:50 +1000
commitda0e027fa5699ce2676568fecba1f55a30344f7b (patch)
tree07aabcc648a2162aef8635ba162ce171b122199f /py
parent326e1149eccc2521527e62be66f1a0ae9f6600d0 (diff)
downloadmicropython-da0e027fa5699ce2676568fecba1f55a30344f7b.tar.gz
micropython-da0e027fa5699ce2676568fecba1f55a30344f7b.zip
py/asmrv32: Emit C.LW opcodes only when necessary.
The RV32 emitter sometimes generated short load opcodes even when it was not supposed to. This commit fixes an off-by-one error in its offset eligibility range calculation and corrects one case of offset calculation, operating on the raw label index number rather than its effective offset in the stack (C.LW assumes all loads are word-aligned). Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
Diffstat (limited to 'py')
-rw-r--r--py/asmrv32.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/py/asmrv32.c b/py/asmrv32.c
index a68401cf32..f121c1ef6b 100644
--- a/py/asmrv32.c
+++ b/py/asmrv32.c
@@ -301,7 +301,7 @@ void asm_rv32_emit_call_ind(asm_rv32_t *state, mp_uint_t index) {
mp_uint_t offset = index * ASM_WORD_SIZE;
state->saved_registers_mask |= (1U << ASM_RV32_REG_RA);
- if (IS_IN_C_REGISTER_WINDOW(REG_FUN_TABLE) && IS_IN_C_REGISTER_WINDOW(INTERNAL_TEMPORARY) && FIT_SIGNED(offset, 7)) {
+ if (IS_IN_C_REGISTER_WINDOW(REG_FUN_TABLE) && IS_IN_C_REGISTER_WINDOW(INTERNAL_TEMPORARY) && FIT_UNSIGNED(offset, 6)) {
// c.lw temporary, offset(fun_table)
// c.jalr temporary
asm_rv32_opcode_clw(state, MAP_IN_C_REGISTER_WINDOW(INTERNAL_TEMPORARY), MAP_IN_C_REGISTER_WINDOW(REG_FUN_TABLE), offset);
@@ -487,7 +487,7 @@ void asm_rv32_emit_mov_reg_local_addr(asm_rv32_t *state, mp_uint_t rd, mp_uint_t
void asm_rv32_emit_load_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) {
mp_int_t scaled_offset = offset * sizeof(ASM_WORD_SIZE);
- if (IS_IN_C_REGISTER_WINDOW(rd) && IS_IN_C_REGISTER_WINDOW(rs) && FIT_SIGNED(offset, 7)) {
+ if (scaled_offset >= 0 && IS_IN_C_REGISTER_WINDOW(rd) && IS_IN_C_REGISTER_WINDOW(rs) && FIT_UNSIGNED(scaled_offset, 6)) {
// c.lw rd', offset(rs')
asm_rv32_opcode_clw(state, MAP_IN_C_REGISTER_WINDOW(rd), MAP_IN_C_REGISTER_WINDOW(rs), scaled_offset);
return;