[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] riscv: Fix movi/relatives loading incorrect value
From: |
Kim Kuparinen |
Subject: |
[PATCH] riscv: Fix movi/relatives loading incorrect value |
Date: |
Tue, 16 Nov 2021 17:04:45 +0200 |
Currently when loading the low 32 bits of a 64-bit constant LUI sign-extends
the value, leading to situations where the high 32 bits of the register are
effectively subtracted by one.
Simplified example, using 8-bit registers: lui loads the upper two bits and
sign-extends them, addiw adds the bottom two bits and ignores overflow.
movi a0, 0b0010 1001
is expanded to
// lo
lui r0, 0b10 // r0 => 0b1111 1000
addiw r0, 0b01 // r0 => 0b1111 1001
// hi
lui a0, 0b00 // a0 => 0b0000 0000
addiw a0, b10 // a0 => 0b0000 0010
slli a0, 4 // a0 => 0b0010 0000
add a0, a0, r0 // a0 => 0b0001 1001
The fix I came up with is to detect if lo is negative and add one to hi,
cancelling out the effective -1.
---
lib/jit_riscv-cpu.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/jit_riscv-cpu.c b/lib/jit_riscv-cpu.c
index 388489f..7e21d24 100644
--- a/lib/jit_riscv-cpu.c
+++ b/lib/jit_riscv-cpu.c
@@ -1342,6 +1342,10 @@ _movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
jit_int32_t lo = i0 << 32 >> 32;
jit_word_t hi = i0 - lo;
jit_int32_t t0 = jit_get_reg(jit_class_gpr);
+
+ if(lo < 0)
+ hi++;
+
movi(rn(t0), (jit_int32_t)(hi >> 32));
movi(r0, lo);
lshi(rn(t0), rn(t0), 32);
@@ -1363,6 +1367,10 @@ _movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
LUI(r0, hi >> 12);
ADDIW(r0, r0, lo);
ww = i0 >> 32;
+
+ if(hi < 0)
+ ww++;
+
lo = ww << 20 >> 20;
hi = ww - lo;
LUI(rn(t0), hi >> 12);
@@ -2331,6 +2339,10 @@ _patch_at(jit_state_t *_jit, jit_word_t instr,
jit_word_t label)
i.w = u.i[2];
if (i.U.opcode == 55) { /* LUI */
ww = label >> 32;
+
+ if(hi < 0)
+ ww++;
+
lo = ww << 20 >> 20;
hi = ww - lo;
i.U.imm12_31 = hi >> 12;
--
2.33.0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] riscv: Fix movi/relatives loading incorrect value,
Kim Kuparinen <=