From: Ralph Ronnquist Date: Tue, 18 May 2021 04:46:29 +0000 (+1000) Subject: macros in separate file X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=365af483341a063a1bfba09dcaa03bf2373ad4a8;p=rrq%2Frrqforth.git macros in separate file --- diff --git a/machine.asm b/machine.asm index ddfb971..058da15 100644 --- a/machine.asm +++ b/machine.asm @@ -42,6 +42,111 @@ ;;; clobbers rdi rsi rdx rcx r8 r9 r11 ;;; rax = syscall id ;;; -;;; function calling +;;; ###################################################################### + +;;; ============================================================ +;;; FORTH machine model +;;; rsp = data stack pointer +;;; rbp = return stack pointer +;;; rsi = instruction pointer + +;;; ======================================== +;;; The pushr macro pushes x onto the return stack +;;; The popr macro pops x from the return stack +macro pushr x { + sub rbp, 8 + mov [rbp], x +} + +macro popr x { + mov x, [rbp] + add rbp, 8 +} + +;;; ======================================== +;;; The next macro "moves" execution to the next FORTH instruction, +;;; using rsi as instruction pointer. It points to the doer field of a +;;; word, which points to the assembly code that implements the +;;; execution effect of the word. That doer code is entered with rsi +;;; referring to the subsequent address in the colling word, and rax +;;; referring to the doer field of the called word. + +macro next { + lodsq ; mov rax, [rsi] + add rsi,8 + jmp qword [rax] ; goto code of that FORTH word (64 bit jump) +} + +;;; ======================================== +;;; The FORTH macro transitions to inline FORTH execution. +macro FORTH { + local forthcode + mov rsi,forthcode + next + ;; align 8 +forthcode: +} + +;;; ======================================== +;;; The ENDFORTH macro transitions back to inline assembler after FORTH + +macro ENDFORTH { + dq inline_code +} + +;;; ======================================== +;;; The DOFORTH lays out a single FORTH call + +macro DOFORTH label { + FORTH + dq label + ENDFORTH +} + +;;; ======================================== +;;; Macro WORD starts a FORTH word definition in this code +;;; + previous_word = 0 ; Used for chaining the words + + IMMEDIATE = 1 ; optional flag (symbol) + +macro WORD label, name, doer, flags { + ;; align 8 +label#_TFA: + ;; TFA + dq previous_word + previous_word = label#_TFA + ;; PFA +label#_PFA: + db flags + 0 + db label - $ - 2 + db name + db 0 + ;; align 8 + +label#_OFF: + dq 0 ; The DOES offset. Defaults to 0. + ;; also CFA = pointer to "doer" +label: + if doer eq + dq doforth + else + if doer in + dq label#_DFA + else + dq doer + end if + end if + ;; DFA +label#_DFA: +} + +;;; ======================================== +;;; The block macro lays out the length for a subsequent block to the +;;; given label. +macro BLOCK endlabel { + local datastart + dq endlabel - datastart +datastart: + } diff --git a/rrqforth.asm b/rrqforth.asm index 673f771..41bab41 100644 --- a/rrqforth.asm +++ b/rrqforth.asm @@ -2,100 +2,7 @@ format elf64 executable entry main -;;; ======================================== -;;; The pushr macro pushes x onto the return stack -;;; The popr macro pops x from the return stack -macro pushr x { - sub rbp, 8 - mov [rbp], x -} - -macro popr x { - mov x, [rbp] - add rbp, 8 -} - -;;; ======================================== -;;; The next macro "moves" execution to the next FORTH instruction, -;;; using rsi as instruction pointer. It points to the doer field of a -;;; word, which points to the assembly code that implements the -;;; execution effect of the word. That doer code is entered with rsi -;;; referring to the subsequent address in the colling word, and rax -;;; referring to the doer field of the called word. - -macro next { - lodsq ; mov rax, [rsi] + add rsi,8 - jmp qword [rax] ; goto code of that FORTH word (64 bit jump) -} - -;;; ======================================== -;;; The FORTH macro transitions to inline FORTH execution. -macro FORTH { - local forthcode - mov rsi,forthcode - next - ;; align 8 -forthcode: -} - -;;; ======================================== -;;; The ENDFORTH macro transitions back to inline assembler after FORTH -;;; ======================================== -macro ENDFORTH { - dq inline_code -} - -;;; ======================================== -;;; The DOFORTH lays out a single FORTH call -;;; ======================================== -macro DOFORTH label { - FORTH - dq label - ENDFORTH -} - -;;; Macro WORD starts a FORTH word definition in this code -;;; - previous_word = 0 ; Used for chaining the words - - IMMEDIATE = 1 ; optional flag - -macro WORD label, name, doer, flags { - ;; align 8 -label#_TFA: - ;; TFA - dq previous_word - previous_word = label#_TFA - ;; PFA -label#_PFA: - db flags + 0 - db label - $ - 2 - db name - db 0 - ;; align 8 - -label#_OFF: - dq 0 ; The DOES offset. Defaults to 0. - ;; also CFA = pointer to "doer" -label: - if doer eq - dq doforth - else - if doer in - dq label#_DFA - else - dq doer - end if - end if - ;; DFA -label#_DFA: -} - -;;; ============================================================ -;;; FORTH machine model -;;; rsp = data stack pointer -;;; rbp = return stack pointer -;;; rsi = instruction pointer +include 'machine.asm' ;;; ============================================================