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:
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;