commit f903c057c9c6fc6b5d21281b82043aa9e04b08be
parent 2d633a55cc7463e140c4bd2b10475c947386d6cc
Author: Christian Ermann <christian.ermann@joescan.com>
Date: Fri, 11 Jul 2025 19:32:48 -0700
Fix 'literal' for immediates with bit 12 set
Diffstat:
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/src/forth.s b/src/forth.s
@@ -698,41 +698,50 @@ _postpone_fail:
_postpone_done:
exit
-defword "literal", literal, 0xECB9D8E4, flags=flag_immediate
- push w
- li w, 0xFFC10113 # addi psp, psp, -4
+defword "push,", push_comma, 0x264FE863, flags=flag_immediate
push w
li w, 0xFEA12E23 # sw w, -4(psp)
jal lit_comma
+ push w
+ li w, 0xFFC10113 # addi psp, psp, -4
jal lit_comma
+ exit
+
+defword "literal", literal, 0xECB9D8E4, flags=flag_immediate
+ jal push_comma
mv x, w
_literal_small_1:
- # emit `addi w, zero, immed`
+ # encode `addi w, zero, immed`
andi w, x, -1 # 0xFFF
slli w, w, 20
addi w, w, 0x513
+ # when immed > 4095, we need to use a 2 instruction sequence
li y, 0xFFF
- bltu x, y, _literal_small_2
+ bgtu x, y, _literal_large_1
+ # when bit 12 isn't set, we're done
+ srli y, x, 11
+ andi y, y, 1
+ beqz y, _literal_small_2
_literal_large_1:
- # change to `addi w, w, immed`
+ # change `addi w, zero, immed` to `addi w, w, immed`
li y, 0xA
slli y, y, 15
add w, w, y
push w
- # encode upper immediate
+ # encode `lui w, immed`
li w, 0xFFFFF000
and w, x, w
+ # when bit 12 is set, we need to correct for sign ext. from 'addi'
srli y, x, 11
andi y, y, 1
beqz y, _literal_large_2
li y, 0x00001000
add w, w, y
_literal_large_2:
- # emit `lui w, immed`
addi w, w, 0x537
- jal lit_comma
+ jal lit_comma # emits `lui`
_literal_small_2:
- jal lit_comma
+ jal lit_comma # emits `addi`
exit
defcode "word>hash", word_to_hash, 0x50E0A245