forth-riscv

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

commit a51e3023252990a63e7edd8c406b46abc739a307
parent 2b483904003bbec46c3ce450406f96edefe40fe7
Author: Christian Ermann <christianermann@gmail.com>
Date:   Sun, 17 Nov 2024 16:53:24 -0800

Store top of stack in 'w' register

Diffstat:
Mforth.s | 327+++++++++++++++++++++++++++++++++----------------------------------------------
1 file changed, 138 insertions(+), 189 deletions(-)

diff --git a/forth.s b/forth.s @@ -34,13 +34,13 @@ .endm .macro push_addr addr - la w, version_string push w + la w, \addr .endm .macro push_imm imm - li w, \imm push w + li w, \imm .endm .macro push reg @@ -150,13 +150,14 @@ _\label: .endm dovar: - push ra + push w + mv w, ra pop_ret ra ret docon: - load_cell w, 0(ra) push w + load_cell w, 0(ra) pop_ret ra ret @@ -213,30 +214,28 @@ defvar "source-id", source_id, 0x965ED1E2 # ----------------------------------------------------------------------------- defcode "type", type, 0x5127F14D - pop a1 # length - pop a0 # address + mv x, w + pop w push_ret ra jal uart_put_string pop_ret ra + pop w next defcode "emit", emit, 0x2D88474A - pop a0 jal uart_put_char + pop w next defcode "key", key, 0x6815C86C jal uart_get_char - push a0 next defcode "accept", accept, 0x08247E29 - pop w # max len pop x # address push_ret ra jal accept_impl pop_ret ra - push w # recv'd len next accept_impl: @@ -308,20 +307,20 @@ defword "source", source, 0x1BCF29D8 defcode "tib", tib, 0xC90B0194 # ( -- addr len ) + push w la w, _tib push w la w, _tib_len load_cell w, 0(w) - push w next defcode "fib", fib, 0xBCE49236 # ( -- addr len ) + push w la w, _fib push w la w, _fib_len load_cell w, 0(w) - push w next defword "skip-while", skip_while, 0xBBFD4B86 @@ -413,8 +412,8 @@ defword "parse-word", parse_word, 0xB218226F exit defcode ">number", to_number, 0x2F770E4C - pop x # word len - pop w # word addr + mv x, w + pop w mv y, zero # initial value mv s3, zero # sign flag la s4, _base @@ -464,13 +463,11 @@ _to_number_sign: _to_number_done: push y - push x + mv w, x next defcode "word>hash", word_to_hash, 0x50E0A245 - pop w # word address load_cell w, hash_offset(w) - push w # word hash next defword "find", find, 0xBDF0855A @@ -506,67 +503,66 @@ _find_next_word: .int _find_loop defcode ">cfa", to_cfa, 0x8CAC3233 - pop w addi w, w, code_offset - push w next defcode "execute", execute, 0xA01E3D98 - pop w load_cell x, 0(w) + pop w jr x # 'next' should be called by the executed word defword "interpret", interpret, 0x1F98C57A _interpret_start: jal parse_word - load_cell w, 0(psp) # dup, ?branch beqz w, _interpret_parse_area_empty jal two_dup jal find - load_cell w, 0(psp) # dup, ?branch beqz w, _interpret_word_not_found +_interpret_word_found: addi psp, psp, 2 * cell # nip, nip - store_cell w, 0(psp) - jal to_cfa - la w, _state # compiling? ?branch + addi w, w, code_offset load_cell w, 0(w) - beqz w, _interpret_execute_word - load_cell w, 0(psp) # dup immediate? 0= branch? - addi w, w, flag_offset - code_offset - lb w, 0(w) - andi w, w, flag_immediate - bnez w, _interpret_execute_word + # compiling? + la x, _state + load_cell x, 0(x) + beqz x, _interpret_execute_word + # immediate? + addi x, w, flag_offset - code_offset + lb x, 0(x) + andi x, x, flag_immediate + bnez x, _interpret_execute_word _interpret_compile_word: - jal fetch jal jal_to jal comma j _interpret_start _interpret_execute_word: - jal execute - jal branch - .int _interpret_start + mv x, w + pop w + jalr x + j _interpret_start _interpret_word_not_found: - addi psp, psp, cell - jal to_number pop w + jal to_number bnez w, _interpret_retry - jal compiling_q - jal q_branch - .int _interpret_start + pop w + # compiling? + la x, _state + load_cell x, 0(x) + beqz x, _interpret_start _interpret_compile_number: jal lit .int lit jal comma jal comma - jal branch - .int _interpret_start + j _interpret_start _interpret_retry: - jal drop - jal branch - .int _interpret_start + addi psp, psp, cell + load_cell w, 0(psp) + j _interpret_start _interpret_parse_area_empty: - addi psp, psp, 2 * cell + addi psp, psp, cell + pop w exit defword "evaluate", evaluate, 0xACE4360A @@ -589,34 +585,37 @@ _evaluate_done: exit defcode "branch", branch, 0xB6873945 - load_cell w, 0(ra) - mv ra, w + load_cell ra, 0(ra) next defcode "?branch", q_branch, 0x6AF3C1DE - pop w bnez w, _branch_done - load_cell w, 0(ra) - mv ra, w + pop w + load_cell ra, 0(ra) next _branch_done: + pop w addi ra, ra, cell next defcode "prompt", prompt, 0xDFE6493B + push w la w, _prompt la x, _prompt_len push_ret ra call uart_put_string pop_ret ra + pop w next defcode "okay", okay, 0xBA9EEB49 + push w la w, _okay la x, _okay_len push_ret ra call uart_put_string pop_ret ra + pop w next defword "quit", quit, 0x47878736 @@ -640,72 +639,62 @@ defword "abort", abort, 0xA52BCAF9 # ----------------------------------------------------------------------------- defcode "!", store, 0x240C8DEC - pop w # address - pop x # value + pop x store_cell x, 0(w) + pop w next defcode "@", fetch, 0xC50BF85F - pop w # address - load_cell x, 0(w) - push x + load_cell w, 0(w) next defcode "c!", char_store, 0x9829F909 - pop w pop x sb x, 0(w) + pop w next defcode "c@", char_fetch, 0x37296056 - pop w - lb x, 0(w) - push x + lb w, 0(w) next defcode "2!", two_store, 0x9CF2B11C - pop w pop x pop y store_cell x, 0(w) store_cell y, cell(w) + pop w next defcode "2@", two_fetch, 0x3DF21B8F - pop w - load_cell x, 0(w) load_cell y, cell(w) + load_cell w, 0(w) push y - push x next defcode "+!", add_store, 0x08DC01D1 - pop w # address - pop x # value to add - load_cell t0, 0(w) - add t0, t0, x - store_cell t0, 0(w) + pop x + load_cell y, 0(w) + add y, y, x + store_cell y, 0(w) + pop w next defcode "-!", sub_store, 0x24CD235B - pop w # address - pop x # value to add - load_cell t0, 0(w) - sub t0, t0, x - store_cell t0, 0(w) + pop x + load_cell y, 0(w) + sub y, y, x + store_cell y, 0(w) + pop w next defcode "cells", cells, 0xD94ACBB2 - pop w li x, cell mul w, w, x - push w next defcode "cell+", cell_plus, 0xB14A8CBA - pop w addi w, w, cell - push w next # ----------------------------------------------------------------------------- @@ -718,12 +707,12 @@ defword "here", here, 0x213B65CB exit defcode "lit", lit, 0x404CD5B6 + push w load_cell w, 0(ra) addi ra, ra, cell - push w next -defcode "lit-string", lit_string, 0xC7BE567C # TODO: ip -> ra +defcode "lit-string", lit_string, 0xC7BE567C # TODO: ip -> ra, w=tos load_cell x, 0(ip) # len addi ip, ip, cell mv w, ip # addr @@ -741,21 +730,21 @@ defword "allot", allot, 0xADB1A69F exit defcode ",", comma, 0x290C95CB - pop w la y, _dp load_cell x, 0(y) store_cell w, 0(x) addi x, x, cell store_cell x, 0(y) + pop w next defcode "c,", char_comma, 0xA32A0A5A - pop w la y, _dp load_cell x, 0(y) sb w, 0(x) addi x, x, 1 store_cell x, 0(y) + pop w next defword "align", align, 0x602C63DE @@ -778,102 +767,97 @@ defword "align", align, 0x602C63DE defcode "sp@", sp_fetch, 0xFC419F82 # ( -- addr ) - mv w, psp push w + mv w, psp next defcode "sp!", sp_store, 0x1D41D375 # ( addr -- ) - pop w mv psp, w + pop w next defcode "rp@", rp_fetch, 0x7AD905AD # ( -- addr ) - mv w, rsp push w + mv w, rsp next defcode "rp!", rp_store, 0x99D9367A # ( addr -- ) - pop w mv rsp, w + pop w next defcode ">r", to_ret, 0x47FCB8A9 - pop w push_ret w + pop w next defcode "r>", from_ret, 0x135408B1 - pop_ret w push w + pop_ret w next defcode "2>r" two_to_ret, 0x69F5D439 - pop w pop x push_ret x push_ret w + pop w next defcode "2r>", two_from_ret, 0xB54DEDC1 + push w pop_ret w pop_ret x push x - push w next defcode "dup", dup, 0xD330F226 - load_cell w, 0(psp) push w + load_cell w, 0(psp) next defcode "?dup", q_dup, 0xFD2928D3 - load_cell w, 0(psp) beqz w, _q_dup_done push w _q_dup_done: next defcode "swap", swap, 0x64ED874E - pop w - pop x - push w - push x + load_cell x, 0(psp) + store_cell w, 0(psp) + mv w, x next defcode "drop", drop, 0xA9A58D8C - addi psp, psp, cell + pop w next defcode "over", over, 0x31F6520F - load_cell w, cell(psp) push w + load_cell w, cell(psp) next defcode "nip", nip, 0x21A41868 - pop w - store_cell w, 0(psp) + addi psp, psp, cell next defcode "tuck", tuck, 0x8E26FCE8 - pop w - pop x - push w + load_cell x, 0(psp) + store_cell w, 0(psp) push x - push w next defcode "2dup", two_dup, 0x5E46F4D6 - load_cell w, 0(psp) - load_cell x, cell(psp) - push x + load_cell x, 0(psp) push w + push x next defcode "2drop", two_drop, 0xECFD129C - addi psp, psp, 2 * cell + addi psp, psp, cell + pop w next # ----------------------------------------------------------------------------- @@ -881,66 +865,48 @@ defcode "2drop", two_drop, 0xECFD129C # ----------------------------------------------------------------------------- defcode "+", plus, 0x2E0C9DAA - pop w pop x - add w, w, x - push w + add w, x, w next defcode "-", minus, 0x280C9438 pop x - pop w - sub w, w, x - push w + sub w, x, w next defcode "*", times, 0x2F0C9F3D - pop w pop x - mul w, w, x - push w + mul w, x, w next defcode "or", or_, 0x5D342984 - pop w pop x - or w, w, x - push w + or w, x, w next defcode "and", and_, 0x0F29C2A6 - pop w pop x - and w, w, x - push w + and w, x, w next defcode "lshift", lshift, 0x8DA53719 - pop w pop x - sll x, x, w - push x + sll w, x, w next defcode "rshift", rshift, 0x86294EF7 - pop w pop x - srl x, x, w - push x + srl w, x, w next defcode "ashift", ashift, 0x46A0EC68 - pop w pop x - sra x, x, w - push x + sra w, x, w next defcode "aligned", aligned, 0xC73174DF - pop w - addi w, w, 3 - andi w, w, 0xFFFFFFFC - push w + addi w, w, cell - 1 + andi w, w, -cell next # ----------------------------------------------------------------------------- @@ -948,65 +914,55 @@ defcode "aligned", aligned, 0xC73174DF # ----------------------------------------------------------------------------- defcode "0=", zero_equal, 0x14ED5DD6 - pop w mv x, zero bnez w, _zero_done addi x, x, -1 _zero_done: - push x + mv w, x next defcode "=", equal, 0x380CAD68 - pop w pop x beq w, x, _equal - push zero + mv w, zero next _equal: - push_imm -1 + li w, -1 next defcode "<>", not_equal, 0x93F7201F - pop w pop x bne w, x, _not_equal - push zero + mv w, zero next _not_equal: - push_imm -1 + li w, -1 next defcode ">", greater_than, 0x3B0CB221 - pop w pop x bgt x, w, _greater_than - push zero + mv w, zero next _greater_than: - push_imm -1 + li w, -1 next defcode "<", less_than, 0x390CAEFB - pop w pop x blt x, w, _less_than - push zero + mv w, zero next _less_than: - push_imm -1 + li w, -1 next -defword "min", min, 0xC98F4557 - jal two_dup - jal less_than - jal q_branch - .int _min_b -_min_a: - jal drop - exit -_min_b: - jal nip - exit +defcode "min", min, 0xC98F4557 + pop x + bgt x, w, _min_greater_than + mv w, x +_min_greater_than: + next # ----------------------------------------------------------------------------- # compiler @@ -1014,7 +970,7 @@ _min_b: defcode "jal-immed", jal_immed, 0xA914EF13 # encode a value as an immediate for a 'jal' instruction - pop x + mv x, w li y, 0x000FF000 # imm[19:12] and w, x, y li y, 0x00100000 # imm[20] @@ -1028,26 +984,21 @@ defcode "jal-immed", jal_immed, 0xA914EF13 andi y, x, 0x000007FE # imm[10:1] slli y, y, 20 add w, w, y - push w next defword "jal-to", jal_to, 0xC38EF054 # generate a 'jal ra, addr' instruction - pop w la x, _dp load_cell x, 0(x) sub w, w, x - push w jal jal_immed - pop w addi w, w, 0x000000EF # jal ra, imm - push w exit defword "jal-dovar", jal_dovar, 0x668658A5 # generate a 'jal ra, dovar' instruction - la w, dovar push w + la w, dovar jal jal_to exit @@ -1057,23 +1008,23 @@ defword "dovar,", dovar_comma, 0x1F514E5B exit defword "docol,", docol_comma, 0xFAE1EE9E - li w, 0xFE192E23 # sw ra, -4(s2) push w + li w, 0xFE192E23 # sw ra, -4(s2) jal comma - li w, 0xFFC90913 # addi s2, s2, -4 push w + li w, 0xFFC90913 # addi s2, s2, -4 jal comma exit defword "exit,", exit_comma, 0xD540F80B - li w, 0x00092083 # lw ra, 0(s2) push w + li w, 0x00092083 # lw ra, 0(s2) jal comma - li w, 0x00490913 # addi s2, s2, 4 push w + li w, 0x00490913 # addi s2, s2, 4 jal comma - li w, 0x00008067 # ret push w + li w, 0x00008067 # ret jal comma exit @@ -1106,12 +1057,11 @@ defword "create", create, 0x26BB595D exit defcode "hash", hash, 0xEDBF0FE3 - pop x # string length - pop w # string address + mv x, w + pop w push_ret ra jal hash_impl pop_ret ra - push w # string hash next hash_impl: # 32-bit fnv1a @@ -1128,37 +1078,34 @@ _hash_char: ret defcode "[", l_bracket, 0xDE0C1FBA, flags=flag_immediate - la w, _state - li x, state_immediate - store_cell x, 0(w) + la x, _state + li y, state_immediate + store_cell y, 0(x) next defcode "]", r_bracket, 0xD80C1648 - la w, _state - li x, state_compile - store_cell x, 0(w) + la x, _state + li y, state_compile + store_cell y, 0(x) next defcode "hidden", hidden, 0xF618F139 - pop w addi w, w, flag_offset lb x, 0(w) xori x, x, flag_hidden sb x, 0(w) + pop w next defcode "hidden?", hidden_q, 0x6F436C72 - pop w addi w, w, flag_offset - lb x, 0(w) - andi x, x, flag_hidden - push x + lb w, 0(w) + andi w, w, flag_hidden next defword ":", colon, 0x3F0CB86D jal create # create header - jal lit - .int -cell + push_imm -cell jal allot jal docol_comma # append 'docol' jal latest @@ -1191,6 +1138,7 @@ defcode "immediate?", immediate_q, 0x89F23E9F next # TODO: everything after this needs updated to work with subroutine threading +# and with w=tos defword "postpone", postpone, 0x933F531F, flags=flag_immediate .int parse_word, find # TODO: was word actually found? @@ -1354,6 +1302,7 @@ start: la psp, __stacktop la rsp, __stacktop_ret la ip, program + li w, 0xDEADC0DE push_addr version_string push_imm version_string_len