forth-riscv

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

commit e1101f39ffc6889db049fac88dbda2e813ff8347
parent 1a74ad03c8760e54a6d25735a10444beeccb36be
Author: Christian Ermann <christianermann@gmail.com>
Date:   Mon, 28 Oct 2024 10:50:00 -0700

Redefine 'create' as a high-level word

Diffstat:
Mforth.s | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mriscv32-virt.ld | 1+
2 files changed, 115 insertions(+), 32 deletions(-)

diff --git a/forth.s b/forth.s @@ -11,6 +11,7 @@ #define cell 4 #define dcell 8 +#define link_offset 0 #define hash_offset 4 #define meta_offset 8 #define flag_offset 12 @@ -98,6 +99,7 @@ meta_\label: .byte \name_length .ascii "\name" + .section ".rodata" .balign cell .globl \label \label: @@ -223,45 +225,124 @@ 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 +defcode "!", 1, 0, 0x240C8DEC, store, quit + pop w # address + pop x # value + store_cell x, 0(w) next -create_impl: - push_ret ra - jal hash_impl - pop_ret ra +defcode "@", 1, 0, 0xC50BF85F, fetch, store + pop w # address + load_cell x, 0(w) + push x + next - la t0, here - load_cell t1, 0(t0) +defcode "c!", 2, 0, 0x9829F909, char_store, fetch + pop w + pop x + sb x, 0(w) + next - la t2, _latest - load_cell t3, 0(t2) +defcode "c@", 2, 0, 0x37296056, char_fetch, char_store + pop w + lb x, 0(w) + push x + next - store_cell t1, 0(t2) # update 'latest' to point 'here' - store_cell t3, 0(t1) # add link to last word - addi t1, t1, cell +defcode "+!", 2, 0, 0x08DC01D1, add_store, char_fetch + pop w # address + pop x # value to add + load_cell t0, 0(w) + add t0, t0, x + store_cell t0, 0(w) + next - # store hash - store_cell w, 0(t1) - addi t1, t1, cell +defcode "-!", 2, 0, 0x24CD235B, sub_store, add_store + pop w # address + pop x # value to add + load_cell t0, 0(w) + sub t0, t0, x + store_cell t0, 0(w) + next - # store meta address - # TODO: store info about word at address - store_cell zero, 0(t1) - addi t1, t1, cell +defcode "dp", 2, 0, 0x491CB0B9, dp, sub_store + la w, _here + push w + next - # store flags - sb zero, 0(t1) - addi t1, t1, 1 +defcode "here", 4, 0, 0x213B65CB, here, dp + la w, _here + load_cell x, 0(w) + push x + next - # align to cell boundary - addi t1, t1, 3 - andi t1, t1, 0xFFFFFFFC - store_cell t1, 0(t0) - ret +defcode "latest", 6, 0, 0x41704246, latest, here + la w, _latest + push w + next + +defcode "lit", 3, 0, 0x404CD5B6, lit, latest + load_cell w, 0(ip) + addi ip, ip, cell + push w + next + +defcode "dup", 3, 0, 0xD330F226, dup, lit + load_cell w, 0(psp) + push w + next + +defcode "swap", 4, 0, 0x64ED874E, swap, dup + pop w + pop x + push w + push x + next + +defword "allot", 5, 0, 0xADB1A69F, allot, swap + .int dp, add_store + .int exit + +defword ",", 1, 0, 0x290C95CB, comma, allot + .int here, store # store value + .int lit, cell, allot # increment 'here' + .int exit + +defword "c,", 2, 0, 0xA32A0A5A, char_comma, comma + .int here, char_store # store value + .int lit, 1, allot # increment 'here' + .int exit + +defcode "aligned", 7, 0, 0xC73174DF, aligned, char_comma + pop w + addi w, w, 3 + andi w, w, 0xFFFFFFFC + push w + next + +defcode "align", 5, 0, 0xC73174DF, align, aligned + la w, _here + load_cell x, 0(w) + addi x, x, 3 + andi x, x, 0xFFFFFFFC + store_cell x, 0(w) + next + +defcode "+", 1, 0, 0xC4ADC675, plus, align + pop w + pop x + add w, w, x + push w + next + +defword "create", 6, 0, 0x26BB595D, create, plus + .int latest, fetch, comma # link + .int hash, comma # hash + .int lit, 0, comma # meta + .int lit, 0, char_comma # flags + .int align + .int here, lit, -code_offset, plus, latest, store # update 'latest' + .int exit defcode "hash", 4, 0, 0xEDBF0FE3, hash, create pop x # string length @@ -293,9 +374,10 @@ version_string: version_string_len = (. - version_string) word_buffer: .space 255 +.balign cell _latest: .int name_hash -here: .int __here_start -meta: .int __meta_start +_here: .int __here_start +_meta: .int __meta_start .section ".text.boot" start: diff --git a/riscv32-virt.ld b/riscv32-virt.ld @@ -15,6 +15,7 @@ SECTIONS { . = ORIGIN(RAM); .text : { *(.text.boot); *(.text); *(.text.*) } >RAM .rodata : { *(.rodata) } >RAM + . = ALIGN(4); __here_start = .; __meta_start = __here_start + 0x7000000; }