From e086c1738e84f6952008d1d2efa4e36b31b061b3 Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Thu, 20 May 2021 20:48:17 +1000 Subject: [PATCH] reorganisation of code --- machine.asm | 19 +++--- memory.asm | 24 +++++++ rrqforth.asm | 174 +++++++++++++++++++++++++++++++------------------- syscalls.asm | 1 - wordlists.asm | 26 +------- 5 files changed, 142 insertions(+), 102 deletions(-) diff --git a/machine.asm b/machine.asm index 9031014..7f65bbe 100644 --- a/machine.asm +++ b/machine.asm @@ -103,10 +103,6 @@ macro DOFORTH label { ENDFORTH } - previous_word = 0 ; Used for chaining the words - - IMMEDIATE = 1 ; optional flag (symbol) - ;;; ======================================== ;;; Macro WORD starts a FORTH word definition in this code. ;;; The layout of a word is as follows: @@ -122,6 +118,8 @@ macro DOFORTH label { ;;; CFA: [8 bytes] pointer to the word's "doer" code ;;; DFA: [? bytes] the word's data field +IMMEDIATE = 1 ; optional flag (symbol) + macro WORD label, name, doer, flags, previous, offset { local pname ;; align 8 @@ -196,11 +194,12 @@ macro dfa2tfa reg { sub reg,24 mov reg,qword [reg] } -macro pushpname rg { ; ( reg -- chars* length ) - add rg,8 - push rg - sub rg,8 - push qword [rg] +;;; Code snippet to push a pname string with address and 64-bit length field. +;;; The register is advanced to point at the text part. +macro pushpname reg { + add reg,8 + push reg + push qword [reg-8] } ;;; ======================================== ;;; The BLOCK macro lays out the length for a subsequent block to the @@ -231,7 +230,7 @@ macro BRANCH zero,label { if zero in <0> dq p_zero_branch else - dq p_zero_branch + dq p_branch end if dq label - $ - 8 } diff --git a/memory.asm b/memory.asm index 6e945ff..64f54bc 100644 --- a/memory.asm +++ b/memory.asm @@ -1,5 +1,29 @@ ;;; This file defines "memory access words" + WORD p_tfa2cfa,'TFA>CFA',fasm + ;; ( tfa -- cfa ) + ;; Advance a word tfa pointer to the cfa field + mov rax,qword[rsp] + tfa2cfa rax + mov qword [rsp],rax + next + + WORD p_tfa2dfa,'TFA>DFA',fasm + ;; ( tfa -- dfa ) + ;; Advance a word tfa pointer to the dfa field + mov rax,qword[rsp] + tfa2dfa rax + mov qword [rsp],rax + next + + WORD p_dfa2tfa,'DFA>TFA',fasm + ;; ( dfa -- tfa ) + ;; Advance a word tfa pointer to the dfa field + mov rax,qword[rsp] + mov rax,qword [rax-24] ; tfa + mov qword [rsp],rax + next + WORD p_get, '@',fasm ;; ( addr -- v ) ;; Load value v from address addr diff --git a/rrqforth.asm b/rrqforth.asm index db4fe33..b6df047 100644 --- a/rrqforth.asm +++ b/rrqforth.asm @@ -2,58 +2,137 @@ format elf64 executable entry main +previous_word = 0 ; Used for chaining the words + include 'machine.asm' ;;; ============================================================ - segment readable writable executable + segment readable executable ;;; This is the very first word ;; FORTH is the last word of WORDLIST FORTH - WORD p_forth,'FORTH',dovalue + WORD p_forth,'FORTH',dowordlist ;; ( -- ) ;; Change to use this wordlist dq last_forth_word dq inline_code - mov rax,qword [p_forth_DFA] - mov qword [p_wordlist],rax - popr rsi - next - WORD p_syscall,'SYSCALL',dodoes,,,8 + WORD p_system,'SYSTEM',dowordlist ;; ( -- ) ;; Change to use this wordlist - dq last_syscall_word + dq last_system_word dq inline_code - mov rax,qword [p_syscall_DFA] - mov qword [p_wordlist],rax - popr rsi - next last_wordlists_word: - WORD p_wordlists,'WORDLISTS',dodoes,,,8 + WORD p_wordlists,'WORDLISTS',dowordlist ;; ( -- ) ;; Change to use this wordlist dq p_wordlists_TFA dq inline_code - mov rax,qword [p_wordlists_DFA] - mov qword [p_wordlist],rax - popr rsi + +;;; ======================================== +;;; These are the core "execution semantics" words, which are placed +;;; first so as to remain at the same binary address at successive +;;; compilations, which is helful for declaring special debugging gdb +;;; aliases. +;;; +;;; The DO* words are declared as "variables" to provide their +;;; assembled address when used in FORTH. +;;; +;;; The register context at entry to an "execution semantcs" code +;;; snippets is: +;;; rax = cfa* of word to execute +;;; rsi = cell* in the calling definition, after calling cell +;;; rsp = data stack pointer +;;; rbp = return stack pointer +;;; + + WORD p_dofasm,'doFASM',dovariable + ;; Execution semantics for assembly words. +dofasm: + add rax,8 + jmp rax + + WORD p_doforth,'doFORTH',dovariable ; + ;; Execution semantics for FORTH defition word. +doforth: + pushr rsi + lea rsi, [rax+8] ; rsi = the DFA of the rax word next + + WORD p_dodoes,'doDOES',dovariable + ;; Execution semantics for DOES> + ;; [cfa-8] holds the adjustment offset ("does offset") +dodoes: + pushr rsi + lea rsi, [rax+8] ; rsi = the DFA of the rax word + add rsi,qword [rax-8] ; adjust rsi by the "does offset' + next + + WORD p_dovariable,'doVARIABLE',dovariable + ;; Execution semantics for a variable ( -- addr ) + ;; rax points to CFA field +dovariable: + lea rax, [rax+8] ; rsi = the DFA of the rax word + push rax + next + + WORD p_dovalue,'doVALUE',dovariable + ;; Execution semantics for a value constant ( -- v ) + ;; rax points to CFA field +dovalue: + lea rax, [rax+8] ; rsi = the DFA of the rax word + push qword [rax] + next + + WORD p_dostring,'doSTRING',dovariable + ;; Execution semantics for a string constant ( -- addr n ) + ;; rax points to CFA field +dostring: + lea rax, [rax+8] ; rsi = the DFA of the rax word + pushpname rax + next + + WORD p_dowordlist,'doWORDLIST',dovariable + ;; Execution semantics for DOES> + ;; [cfa-8] holds the adjustment offset ("does offset") +dowordlist: + pushr rsi + lea rsi, [rax+8] ; rsi = the DFA of the rax word + add rsi,qword [rax-8] ; adjust rsi by the "does offset' + next + + +include 'syscalls.asm' + +;;; ======================================== +;;; The stacks are placed here. -include 'wordlists.asm' + segment readable writable - WORD return_stack,'RS',dovariable + WORD return_stack,'RETURN-STACK',dovariable ;; The return stack + BLOCK RS_TOP rb 1048576 ; 1 Mb return stack RS_TOP: ; The initial rbp - WORD data_stack,'DS',dovariable +last_system_word: + WORD data_stack,'DATA-STACK',dovariable ;; The data stack + BLOCK DS_TOP rb 1048576 ; 1 Mb data stack DS_TOP: ; The initial rsp +;;; ======================================== +;;; Core execution control words + + segment readable executable + +; At fasm compilation: reset previous_word to make a new word list +previous_word = last_wordlists_word + WORD inline_code,'[ASM]',fasm ;; ( -- ) ;; This transitions execution into inline assembler in the @@ -79,7 +158,7 @@ exit: ;; TERMINATE0 terminates the program with code 0 ;; ( -- ) - WORD terminate, 'TERMINATE0',fasm + WORD p_terminate, 'TERMINATE0',fasm pop rdx terminate_special: mov eax,60 @@ -106,47 +185,12 @@ p_zero_branch_SKIP: add rsi,8 next -;;; Execution semantics for a "fasm" WORD -dofasm: - add rax,8 - jmp rax -;;; Execution semantics for FORTH defition word -;;; At entry, rsi points into the calling definition, at the cell -;;; following the cell indicating this word, rax points to the CFA of -;;; this word. -doforth: - pushr rsi - lea rsi, [rax+8] ; rsi = the DFA of the rax word - next - -;;; Execution semantics for DOES> -;;; The cell at [cfa-8] holds an adjustment offset. -dodoes: - pushr rsi - lea rsi, [rax+8] ; rsi = the DFA of the rax word - add rsi,[rax-8] ; adjust rsi to the DOES> part - next - - ;; Execution semantics for a variable ( -- addr ) - ;; rax points to CFA field -dovariable: - add rax,8 - push rax - next - - ;; Execution semantics for a constant ( -- v ) - ;; rax points to CFA field -dovalue: - push qword [rax+8] - next - - ;; Execution semantics for a string constant ( -- addr n ) - ;; rax points to CFA field -dostring: - cfa2dfa rax - pushpname rax - next +;;; ======================================== +;;; Core extension(s) + segment readable writable executable + +include 'wordlists.asm' include 'memory.asm' include 'stack.asm' include 'math.asm' @@ -203,15 +247,13 @@ p_quit_ERROR: mov rbp,RS_TOP ; reset the return stack jmp main - ;; At fasm compilation: reset to make a new word list - previous_word = last_wordlists_word +;;; ======================================== -include 'syscalls.asm' - - -last_word: + segment readable writable heap_start: rb 1048576 ; +1 Mb heap rb 1048576 ; +1 Mb heap rb 1048576 ; +1 Mb heap + rb 1048576 ; +1 Mb heap + rb 1048576 ; +1 Mb heap diff --git a/syscalls.asm b/syscalls.asm index aeb3041..28bba07 100644 --- a/syscalls.asm +++ b/syscalls.asm @@ -369,5 +369,4 @@ end if SYSCALL 332,sys_statx,'SYS_STATX',0 SYSCALL 333,sys_io_pgetevents,'SYS_IO_PGETEVENTS',0 SYSCALL 334,sys_rseq,'SYS_RSEQ',0 -last_syscall_word: SYSCALL 335,sys_pkey_mprotect1,'SYS_PKEY_MPROTECT1',0 diff --git a/wordlists.asm b/wordlists.asm index 705f360..b2e8260 100644 --- a/wordlists.asm +++ b/wordlists.asm @@ -19,34 +19,10 @@ ;;; ;;; WORDLIST ( "name" -- ) = start - WORD p_tfa2cfa,'TFA>CFA',fasm - ;; ( tfa -- cfa ) - ;; Advance a word tfa pointer to the cfa field - mov rax,qword[rsp] - tfa2cfa rax - mov qword [rsp],rax - next - - WORD p_tfa2dfa,'TFA>DFA',fasm - ;; ( tfa -- dfa ) - ;; Advance a word tfa pointer to the dfa field - mov rax,qword[rsp] - tfa2dfa rax - mov qword [rsp],rax - next - - WORD p_dfa2tfa,'DFA>TFA',fasm - ;; ( dfa -- tfa ) - ;; Advance a word tfa pointer to the dfa field - mov rax,qword[rsp] - mov rax,qword [rax-24] ; tfa - mov qword [rsp],rax - next - WORD p_wordlist,'CURRENT-WORDLIST',dovariable ;; CURRENT-WORDLIST points to cfa of the currently active wordlist. dq p_forth_DFA - + WORD p_words,'WORDS',fasm ;; ( -- ) ;; Dump all words -- 2.39.2