X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=machine.asm;h=f1fb51c9015e4dc7533df6596915982f36cbf87d;hb=af617c57b198d0b1e55e77ed2e67c57365007f29;hp=a8bfbd8f7652985a63836f81a38165211ec5efbb;hpb=69125f1514739aa5dcee13a29eb161a229e47eed;p=rrq%2Frrqforth.git diff --git a/machine.asm b/machine.asm index a8bfbd8..f1fb51c 100644 --- a/machine.asm +++ b/machine.asm @@ -73,6 +73,7 @@ macro popr x { ;;; referring to the doer field of the called word. macro next { + call p_calltrace_DFA lodsq ; mov rax, [rsi] + add rsi,8 jmp qword [rax] ; goto code of that FORTH word (64 bit jump) } @@ -97,42 +98,64 @@ macro ENDFORTH { ;;; ======================================== ;;; The DOFORTH lays out a single FORTH call -macro DOFORTH label { +macro DOFORTH [label] { +common FORTH +forward dq label +common 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 { +;;; Macro WORD starts a FORTH word definition in this code. +;;; The layout of a word is as follows: +;;; TFA: [8 bytes] pointer to previous word in the word list +;;; [8 bytes] pointer to the word's CFA +;;; [8 bytes] a flags field +;;; [8 bytes] the length of the word's pname +;;; [varying] the word's pname +;;; [1 byte] NUL -- making an asciiz of the pname +;;; ;;[? bytes] 0-7 bytes for address alignment to [disabled] +;;; [8 bytes] pointer to the word's TFA +;;; OFF: [8 bytes] the DOES offset for the word +;;; 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 label#_TFA: ;; TFA - dq previous_word + if previous eq + dq previous_word + else + dq previous + end if previous_word = label#_TFA ;; PFA +label#_pCFA: + dq label#_CFA ; link to CFA of word + dq flags + 0 label#_PFA: - db flags + 0 - db label - $ - 2 + dq pname - $ - 8 db name - db 0 +pname: db 0 ; extra NUL byte ;; align 8 - +label#_pTFA: + dq label#_TFA ; link to TFA of word label#_OFF: - dq 0 ; The DOES offset. Defaults to 0. + dq offset + 0 ; The DOES offset. Defaults to 0. ;; also CFA = pointer to "doer" +label#_CFA: label: if doer eq dq doforth else if doer in - dq label#_DFA + dq dofasm ; label#_DFA else dq doer end if @@ -141,6 +164,47 @@ label: label#_DFA: } +macro tfa2cfa reg { + mov reg,qword [reg+8] +} +macro tfa2does reg { + tfa2cfa reg + sub reg,8 +} +macro tfa2dfa reg { + tfa2cfa reg + add reg,8 +} +macro tfa2flags reg { + add reg,16 +} +macro tfa2pfa reg { + add reg,24 +} +macro tfa2pname reg { + add reg,32 +} +macro cfa2tfa reg { + sub reg,16 + mov reg,qword [reg] +} +macro cfa2dfa reg { + add reg,8 +} +macro dfa2cfa reg { + sub reg,8 +} +macro dfa2tfa reg { + sub reg,24 + mov reg,qword [reg] +} +;;; 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 ;;; given label. @@ -151,11 +215,12 @@ datastart: } ;;; ======================================== -;;; The STRING macro lays out length byte and data for s short string +;;; The STRING macro lays out length cell and data for several string +;;; components. macro STRING [data] { common local datastart, dataend - db dataend - datastart + dq dataend - datastart datastart: forward db data @@ -163,3 +228,25 @@ common dataend: } +;;; ======================================== +;;; The BRANCH macro lays out FORTH words BRANCH and 0BRANCH with offset +macro BRANCH zero,label { + if zero in <0> + dq p_zero_branch + else + dq p_branch + end if + dq label - $ - 8 +} + +;;; ======================================== +;;; The STREAM macro starts an in-core FORTH STREAM area. See WORD +;;; STREAM for details. + macro STREAM endlabel { + local datastart + dq $+32 + dq -1 + dq endlabel - datastart + dq 0 +datastart: + }