forth-riscv

My forth
git clone git://git.electrosoup.com/forth-riscv
Log | Files | Refs

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:
Msrc/forth.s | 29+++++++++++++++++++----------
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