forth-riscv

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

commit 1a74ad03c8760e54a6d25735a10444beeccb36be
parent c0fec2a510ce08c3a9d6888931b97d1bc18f59f7
Author: Christian Ermann <christianermann@gmail.com>
Date:   Sun, 27 Oct 2024 19:08:34 -0700

Add 'hash' and 'create' to create new headers at runtime

Diffstat:
Mforth.s | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mriscv32-virt.ld | 6++++--
2 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/forth.s b/forth.s @@ -174,7 +174,7 @@ find_impl: # x = word name length push_ret ra jal hash_impl # w = word hash - la s3, latest + la s3, _latest load_cell s3, 0(s3) _check_word_hidden: lb t0, flag_offset(s3) @@ -223,6 +223,66 @@ defword "quit", 4, 0, 0x47878736, quit, branch .int branch .int -dcell +defcode "create", 6, 0, 0x26BB595D, create, quit + pop x # name length + pop w # name address + jal create_impl + next + +create_impl: + push_ret ra + jal hash_impl + pop_ret ra + + la t0, here + load_cell t1, 0(t0) + + la t2, _latest + load_cell t3, 0(t2) + + store_cell t1, 0(t2) # update 'latest' to point 'here' + store_cell t3, 0(t1) # add link to last word + addi t1, t1, cell + + # store hash + store_cell w, 0(t1) + addi t1, t1, cell + + # store meta address + # TODO: store info about word at address + store_cell zero, 0(t1) + addi t1, t1, cell + + # store flags + sb zero, 0(t1) + addi t1, t1, 1 + + # align to cell boundary + addi t1, t1, 3 + andi t1, t1, 0xFFFFFFFC + store_cell t1, 0(t0) + ret + +defcode "hash", 4, 0, 0xEDBF0FE3, hash, create + pop x # string length + pop w # string address + jal hash_impl + push w # string hash + next + +hash_impl: # 32-bit fnv1a + li t0, 2166136261 # hash + li t1, 16777619 # prime +_hash_char: + lb t2, 0(w) + addi w, w, 1 + addi x, x, -1 + xor t0, t0, t2 + mul t0, t0, t1 + bgtz x, _hash_char + mv w, t0 + ret + .section ".rodata" program: .int type @@ -233,7 +293,9 @@ version_string: version_string_len = (. - version_string) word_buffer: .space 255 -latest: .int name_find +_latest: .int name_hash +here: .int __here_start +meta: .int __meta_start .section ".text.boot" start: diff --git a/riscv32-virt.ld b/riscv32-virt.ld @@ -4,7 +4,7 @@ OUTPUT_ARCH(riscv) ENTRY(start) MEMORY { - RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x8000000 + RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 128M } SECTIONS { @@ -14,6 +14,8 @@ SECTIONS { . = ORIGIN(RAM); .text : { *(.text.boot); *(.text); *(.text.*) } >RAM - .rodata : { *(.rodata); } >RAM + .rodata : { *(.rodata) } >RAM + __here_start = .; + __meta_start = __here_start + 0x7000000; }