forth-riscv

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

commit 8bdb3375387459031f6315190c8a0ef2f382d1cb
parent 26459f69ca2732a62504a5ab655469f8af721ca6
Author: Christian Ermann <christianermann@gmail.com>
Date:   Mon,  2 Dec 2024 22:17:10 -0800

Add separate data, code, and execution areas to fix definitions

Diffstat:
Msrc/forth.s | 216++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/riscv32-virt.ld | 2++
2 files changed, 149 insertions(+), 69 deletions(-)

diff --git a/src/forth.s b/src/forth.s @@ -21,8 +21,8 @@ #define load_cell lw #define store_cell sw -.equ state_immediate, 0 -.equ state_compile, 1 +.equ state_executing, 0 +.equ state_compiling, 1 .equ flag_hidden, 0x20 .equ flag_immediate, 0x40 @@ -204,8 +204,13 @@ defvar "*", prefix_execute, 0x2F0C9F3D .int _prefix_address .int string_to_execute -defvar "latest-prefix", latest_prefix, 0x86C823C5 +defvar ":", prefix_define, 0x3F0CB86D + .int 0x3A .int _prefix_execute + .int string_to_define + +defvar "latest-prefix", latest_prefix, 0x86C823C5 + .int _prefix_define # ----------------------------------------------------------------------------- # constants and variables @@ -221,11 +226,20 @@ defconst "bl", bl, 0x412BAEAB .int 0x20 defvar "state", state, 0x783132F6 - .int state_immediate + .int state_executing -defvar "dp", dp, 0x491CB0B9 +defvar "data-pointer", data_pointer, 0x491CB0B9 .int __here_start +defvar "code-pointer", code_pointer, 0xB6A06E40 + .int __exec_start + 2*cell + +defvar "exec-heap", exec_heap, 0xA351EB55 + .int __exec_start + +defvar "code-heap", code_heap, 0xB6C1CD9D + .int __code_start + defvar "mp", mp, 0x532E0998 .int __meta_start @@ -575,8 +589,8 @@ defword "literal", literal, 0xECB9D8E4, flags=flag_immediate li w, 0xFFC10113 # addi psp, psp, -4 push w li w, 0xFEA12E23 # sw w, -4(psp) - jal comma - jal comma + jal compile_comma + jal compile_comma mv x, w _literal_small_1: # emit `addi w, zero, immed` @@ -602,9 +616,9 @@ _literal_large_1: _literal_large_2: # emit `lui w, immed` addi w, w, 0x537 - jal comma + jal compile_comma _literal_small_2: - jal comma + jal compile_comma exit defword "string>execute", string_to_execute, 0xC1A5C011 @@ -692,26 +706,32 @@ _match_prefix_done: next defword "interpret", interpret, 0x1F98C57A - la x, _dp - load_cell x, 0(x) - push_ret x - jal docol_comma _interpret_start: jal parse_word beqz w, _interpret_parse_area_empty jal match_prefix - bnez w, _interpret_execute_prefix + bnez w, _interpret_prefix _interpret_find_word: jal drop jal find beqz w, _interpret_retry _interpret_word_found: - addi w, w, code_offset + addi w, w, flag_offset + lb x, 0(w) + andi x, x, flag_immediate + addi w, w, code_offset - flag_offset + bnez x, _interpret_macro +_interpret_word: load_cell w, 0(w) jal jal_to - jal comma + jal compile_comma j _interpret_start -_interpret_execute_prefix: +_interpret_macro: + load_cell x, 0(w) + pop w + jalr x + j _interpret_start +_interpret_prefix: load_cell x, 0(w) pop w jalr x @@ -725,9 +745,37 @@ _interpret_retry: _interpret_parse_area_empty: addi psp, psp, cell pop w + jal interpret_execute + exit + +defword "(interpret-execute)", interpret_execute, 0x2477F685 + # check state + la x, _state + lw x, 0(x) + li y, state_executing + bne x, y, _inner_interpret_done + # append 'exit' jal exit_comma - pop_ret x + # save current execution heap address + push w + la w, _exec_heap + lw x, 0(w) + push_ret x + # set new execution heap address past compiled code + la y, _code_pointer + lw y, 0(y) + sw y, 0(w) + pop w + # execute jalr x + # reset code pointer and execution heap + pop_ret x + la y, _code_pointer + sw x, 0(y) + la y, _exec_heap + sw x, 0(y) + jal docol_comma +_inner_interpret_done: exit defword "bootstrap", bootstrap, 0x15C160D9 @@ -905,7 +953,7 @@ defcode "char+", char_plus, 0x25A90E02 # ----------------------------------------------------------------------------- defword "here", here, 0x213B65CB - jal dp + jal data_pointer jal fetch exit @@ -927,12 +975,12 @@ defcode "lit-string", lit_string, 0xC7BE567C # TODO: ip -> ra, w=tos next defword "allot", allot, 0xADB1A69F - jal dp + jal data_pointer jal add_store exit defcode ",", comma, 0x290C95CB - la y, _dp + la y, _data_pointer load_cell x, 0(y) store_cell w, 0(x) addi x, x, cell @@ -940,8 +988,9 @@ defcode ",", comma, 0x290C95CB pop w next + defcode "c,", char_comma, 0xA32A0A5A - la y, _dp + la y, _data_pointer load_cell x, 0(y) sb w, 0(x) addi x, x, 1 @@ -949,8 +998,17 @@ defcode "c,", char_comma, 0xA32A0A5A pop w next +defcode "compile," compile_comma, 0x8D0A6736 + la y, _code_pointer + load_cell x, 0(y) + store_cell w, 0(x) + addi x, x, cell + store_cell x, 0(y) + pop w + next + defword "align", align, 0x602C63DE - jal dp + jal data_pointer jal dup jal fetch jal lit @@ -1224,7 +1282,7 @@ defcode "jal-immed", jal_immed, 0xA914EF13 defword "jal-to", jal_to, 0xC38EF054 # generate a 'jal ra, addr' instruction - la x, _dp + la x, _code_pointer load_cell x, 0(x) sub w, w, x jal jal_immed @@ -1236,7 +1294,7 @@ defword "dovar,", dovar_comma, 0x1F514E5B push w la w, dovar jal jal_to - jal comma + jal compile_comma exit defword "docon,", docon_comma, 0x76DCA1A4 @@ -1244,28 +1302,28 @@ defword "docon,", docon_comma, 0x76DCA1A4 push w la w, docon jal jal_to - jal comma + jal compile_comma exit defword "docol,", docol_comma, 0xFAE1EE9E push w li w, 0xFE192E23 # sw ra, -4(s2) - jal comma + jal compile_comma push w li w, 0xFFC90913 # addi s2, s2, -4 - jal comma + jal compile_comma exit defword "exit,", exit_comma, 0xD540F80B push w li w, 0x00092083 # lw ra, 0(s2) - jal comma + jal compile_comma push w li w, 0x00490913 # addi s2, s2, 4 - jal comma + jal compile_comma push w li w, 0x00008067 # ret - jal comma + jal compile_comma exit defword "create-meta", create_meta, 0x001AE175 @@ -1293,34 +1351,45 @@ _create_meta_done: pop_ret w exit -defword "create", create, 0x26BB595D - jal parse_word - jal latest # link +defword "string>header", string_to_header, 0x16FBE3AB + jal latest jal fetch jal comma jal two_dup - jal hash # hash + jal hash jal comma jal create_meta jal comma - push_imm 0 # flags + push_imm 0 jal char_comma jal align # update latest - la x, _dp + la x, _data_pointer load_cell x, 0(x) addi x, x, -code_offset la y, _latest store_cell x, 0(y) # code field - la x, _dp - load_cell y, 0(x) - addi y, y, cell - store_cell y, -cell(y) - store_cell y, 0(x) - # append 'docol, dovar' + push w + la w, _code_heap + lw w, 0(w) + jal comma + exit + +defword "string>define", string_to_define, 0x888D086D + jal string_to_header + jal latest + jal fetch + jal hidden + jal r_bracket jal docol_comma - jal dovar_comma + push w + li w, -1 + exit + +defword "create", create, 0x26BB595D + jal parse_word + jal string_to_header exit defcode "hash", hash, 0xEDBF0FE3 @@ -1344,17 +1413,37 @@ _hash_char: mv w, t0 ret -defcode "[", l_bracket, 0xDE0C1FBA, flags=flag_immediate +defword "[", l_bracket, 0xDE0C1FBA, flags=flag_immediate + # set state la x, _state - li y, state_immediate - store_cell y, 0(x) - next + la y, state_executing + sw y, 0(x) + # save code pointer to code heap + la x, _code_pointer + lw x, 0(x) + la y, _code_heap + sw x, 0(y) + # set code pointer to execution heap + la x, _code_pointer + la y, _exec_heap + lw y, 0(y) + sw y, 0(x) + jal docol_comma + exit -defcode "]", r_bracket, 0xD80C1648 +defword "]", r_bracket, 0xD80C1648, flags=flag_immediate + # execute + jal interpret_execute + # set state la x, _state - li y, state_compile - store_cell y, 0(x) - next + li y, state_compiling + sw y, 0(x) + # set code pointer back to code heap + la x, _code_pointer + la y, _code_heap + lw y, 0(y) + sw y, 0(x) + exit defcode "hidden", hidden, 0xF618F139 addi w, w, flag_offset @@ -1370,16 +1459,6 @@ defcode "hidden?", hidden_q, 0x6F436C72 andi w, w, flag_hidden next -defword ":", colon, 0x3F0CB86D - jal create # create header - push_imm -cell - jal allot # erase 'dovar' - jal latest - jal fetch - jal hidden # hide word - jal r_bracket # enter 'compile' mode - exit - defword ";", semicolon, 0x3E0CB6DA, flags=flag_immediate jal exit_comma jal latest @@ -1388,13 +1467,6 @@ defword ";", semicolon, 0x3E0CB6DA, flags=flag_immediate jal l_bracket exit -defcode "compiling?", compiling_q, 0x94652AE2 - push w - la w, _state - load_cell w, 0(w) - andi w, w, state_compile - next - defcode "immediate?", immediate_q, 0x89F23E9F pop w addi w, w, flag_offset - code_offset @@ -1591,6 +1663,12 @@ start: la w, trap_table + 1 csrw mtvec, w + la w, __exec_start + li x, 0xFE192E23 # sw ra, -4(s2) + li y, 0xFFC90913 # addi s2, s2, -4 + sw x, 0(w) + sw y, cell(w) + la psp, __stacktop la rsp, __stacktop_ret la ip, program diff --git a/src/riscv32-virt.ld b/src/riscv32-virt.ld @@ -25,6 +25,8 @@ SECTIONS { .rodata : { *(.rodata) } >RAM . = ALIGN(4); __here_start = .; + __exec_start = . + 0x400; + __code_start = . + 0x800; __meta_start = __here_start + 0x7000000; __sys_control = 0x100000;