1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; UrForth level
1: self
-hosting
32-bit Forth compiler
3 ;; Natural
-syntax x86 assembler
4 ;; Modelled after SMAL32 built
-in assembler
5 ;; Copyright
(C
) 2020 Ketmar Dark
// Invisible Vector
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12 also asm
-labman definitions
14 true constant lman
-use
-hash
-table immediate
16 false value lman
-debug immediate
17 false value lman
-fixup
-debug immediate
18 false value lman
-debug
-forth immediate
20 true value lman
-allow
-forth
-implicit
23 we
'll BRK all the needed memory, and will never free it
24 this is totally unacceptable in long-running system, but
25 ok for metacompiler and for systems that will be SAVEd.
27 sadly, we can't store address label links in the code itself
28 (due
to short jumps
), so don
't bother at all.
30 so, we have two linked lists: label names and flags, and fixups.
33 cell next-in-bucket ( or 0 )
34 cell flags ( see below )
36 cell fixuphead ( or 0 )
37 cell introline# ( tib-line# at the time this label was first introduced)
38 c4str name ( uppercased )
42 bit 1: forward reference
43 bit 2: set for forth word reference (i.e. not a code label)
45 bit 31: hidden (so it can be checked with 0<) -- NOT YET
51 cell introline# ( generally, should be the same data structure as in nfo)
54 0: direct code address (4 bytes)
55 1: long displacement (4 bytes)
56 2: short displacement (1 byte)
58 @@ labels are done this way:
59 when we see @@, we're going
to resolve all @f
, and remove it
60 when we access @f
, we
're always remember it as a fixup
61 when we access @b, we're adding it as @@
(so it will be automatically resolved
)
64 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65 5 constant nfo
-size
-cells
;; w
/o name
68 0x01 constant flag
-undefined
69 0x02 constant flag
-forward
70 0x04 constant flag
-forth
71 0x08 constant flag
-constant
73 0 constant fxtype
-direct
74 1 constant fxtype
-disp32
75 2 constant fxtype
-disp8
77 ;; usually
, "@" is removed from label name
(due
to "@name" labels being
"global-non-reseting")
78 ;; this is not necessary
(and basically destructive
) for Forth labels
80 true value
do-fix
-label
-name?
83 ;; use
256 buckets
, because it is the easiest way
84 lman
-use
-hash
-table
[IF]
85 0 value info
-hash
-buckets
86 0 value info
-hash
-buckets
-dirty
87 \
256 cells brk
-buffer
: info
-hash
-buckets
88 \ info
-hash
-buckets
256 cells erase
95 lman
-use
-hash
-table
[IF]
96 info
-hash
-buckets ifnot
256 cells brk
-alloc
to info
-hash
-buckets
endif
97 info
-hash
-buckets
-dirty ifnot
256 cells brk
-alloc
to info
-hash
-buckets
-dirty
endif
98 info
-hash
-buckets
256 cells erase
99 info
-hash
-buckets
-dirty
256 cells erase
103 \ endcr
." LABELMAN: reinited!\n"
106 [IFDEF
] forth
:startup
-chain
-add
107 ' Reinit startup-chain-add
110 [IFDEF] forth:(startup-init)
111 ..: forth:(startup-init) Reinit ;..
114 : xalloc ( size -- addr )
115 dup (mem-allocated) +!
120 \ error if flag is non-zero
121 : ?lbl-error ( addr count somevalue flag code -- addr count somevalue )
124 endcr ." <" type ." >"
131 \ error if flag is zero
132 : not-?lbl-error ( addr count somevalue flag code -- addr count somevalue )
133 swap not swap ?lbl-error
136 : ?lbl-error-nx ( addr count flag code -- addr count )
137 0 nrot ?lbl-error drop
140 : not-?lbl-error-nx ( addr count flag code -- addr count )
141 swap not swap ?lbl-error-nx
145 lman-debug lman-fixup-debug or lman-debug-forth or [IF]
146 : lbl-debug-msg ( lbladdr lblcount msgaddr msgcount -- lbladdr lblcount )
147 endcr ." LMAN: " type ." <" 2dup type ." >" cr
152 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
153 : nfo->nfa ( addr -- addr ) 5 +cells ; \ to name area
154 : nfo->ffa ( addr -- addr ) 1 +cells ; \ to flags area
155 : nfo->pfa ( addr -- addr ) 2 +cells ; \ to value area
156 : nfo->xfa ( addr -- addr ) 3 +cells ; \ to fixup ptr area
157 : nfo->dfa ( addr -- addr ) 4 +cells ; \ to "first defined" area
159 4 constant fix-item-cells
160 : fix->addr ( addr -- addr ) 1 +cells ;
161 : fix-addr@ ( addr -- fxaddr ) fix->addr @ ;
162 : fix->type ( addr -- addr ) 2 +cells ;
163 : fix-type@ ( addr -- type ) fix->type @ ;
164 : fix->dfa ( addr -- addr ) 3 +cells ;
165 : fix-dfa@ ( addr -- addr ) fix->dfa @ ;
168 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
171 ;; DO NOT REORDER! some code checks for `@fb-@ >`, for example
176 ;; remove "@" from global label
177 : is-@fb? ( addr count -- flag )
178 dup 2 = ifnot 2drop false exit endif
179 drop dup c@ [char] @ = ifnot drop false exit endif
182 [char] @ of @fb-@ endof
183 [char] B of @fb-b endof
184 [char] F of @fb-f endof
189 : fix-@b ( addr count -- addr count )
190 ;; "@b" should resolve to the last "@@", so simply replace the name
191 2dup is-@fb? @fb-b = if 2drop " @@" endif
194 : is-local? ( addr count -- flag )
198 : nfo-is-local? ( nfo -- flag )
199 ?dup ifnot false exit endif
200 dup nfo->ffa @ flag-forth and if drop false exit endif
201 nfo->nfa count is-local?
204 : fix-label-name ( addr count -- addr count )
205 do-fix-label-name? ifnot exit endif
206 over c@ [char] @ = if
209 1- dup asmx86:ERRID_ASM_INVALID_LABEL_NAME not-?lbl-error-nx
211 over c@ [char] @ = asmx86:ERRID_ASM_INVALID_LABEL_NAME ?lbl-error-nx
217 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
218 ;; create DFA info and write it into the label
219 ;; for now, we simply store the line number, but we should store
221 : create-dfa ( -- addr )
222 asmx86:lexer:first-line# ?dup ifnot tib-line# @ endif
224 2 cells xalloc ;; for line # and file name
235 : dfa-@line ( dfa -- linenum )
236 ?dup if @ else 0 endif
239 : dfa-@fname ( dfa -- addr count )
240 ?dup if cell+ @ ?dup if count exit endif endif
244 : type-dfa ( dfa -- )
246 dup dfa-@line ?dup if
247 ." around line #" base @ >r decimal 0 .r r> base !
250 ." of file \`" type ." \`"
257 : type-dfa-msg-cr ( dfa addr count -- )
260 nrot endcr type type-dfa cr
270 : create-label-dfa ( nfo -- )
271 nfo->dfa create-dfa swap !
275 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
276 : lman-name-hash-folded ( addr count -- u8 )
277 str-name-hash uhash32->8
281 : find-label ( addr count -- nfo-block-addr 1 // 0 )
283 lman-use-hash-table [IF]
284 2dup lman-name-hash-folded info-hash-buckets cells^
290 \ 2dup type space r@ .hex8 space r@ nfo->nfa count type cr
291 2dup r@ nfo->nfa count s=ci if 2drop r> true exit endif
292 r> repeat 2drop false
296 : create-label ( addr count -- nfo-block-addr )
298 dup 1 < asmx86:ERRID_ASM_INTERNAL_ERROR asmx86:?asm-error
299 dup nfo-size-cells 1+ +cells xalloc ;; name bytes, header, count
302 lman-use-hash-table [IF]
303 2dup lman-name-hash-folded info-hash-buckets cells^
307 info-list-head @ r@ !
310 ;; clear other fields
311 r@ cell+ nfo-size-cells 1- cells erase
313 r@ nfo->nfa c4s:copy-counted
314 ;; upcase label name here, because why not?
315 \ r@ nfo->nfa count upcase-str
316 ;; create "definition info"
318 ;; done, return new info address
323 : hide-label ( nfo -- )
324 ;; simply set name length to zero
326 lman-use-hash-table [IF]
328 dup @ if dup count lman-name-hash-folded info-hash-buckets-dirty cells^ 1! endif
334 : nfo-is-hidden? ( nfo -- flag )
339 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
340 : (nfo-xdump-name) ( nfo -- )
342 nfo->nfa cell+ ;; assume that the counter is dead
343 begin dup c@ dup 32 127 within while emit 1+ repeat 2drop
347 ;; remove all hidden labels from the list
348 : compress-labels ( -- )
349 lman-use-hash-table [IFNOT]
351 begin dup @ ?dup while ( ptr-to-prev-link curr-nfo )
352 dup nfo-is-hidden? if
353 \ dup endcr ." removing: " (nfo-xdump-name) cr
354 ;; put out next link to prev link
356 ;; the code will move to the next one by itself
359 ;; drop prev, and let the code continue from the current one
364 256 for ;; for each bucket
365 info-hash-buckets-dirty i +cells @ if ;; dirty bucket
366 \ endcr ." *** bucket " i . ." is dirty!\n"
367 0 info-hash-buckets-dirty i +cells !
368 0 info-hash-buckets i +cells
369 begin @ dup while ( prev curr )
370 dup nfo-is-hidden? if
371 \ endcr ." dropped label in bucket " i . cr
372 over if 2dup @ swap !
373 else dup @ i info-hash-buckets cells^ ! endif
382 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
383 ;; calls cfa: ( nfo -- ... stopflag )
384 ;; returns when the list is done, or when cfa returned non-zero
385 ;; the result is cfa result or zero if the list is done
386 ;; cfa can push any number of data before stopflag if stopflag is non-zero
387 : foreach-label ( cfa -- ... flag )
388 lman-use-hash-table [IF]
389 256 for ;; for each bucket
390 info-hash-buckets i +cells
391 swap >r ;; move cfa to rstack
393 ;; skip hidden labels
394 dup nfo-is-hidden? ifnot
396 r@ over >r execute ?dup if 2rdrop unloop exit endif
402 >r info-list-head begin @ dup while
403 ;; skip hidden labels
404 dup nfo-is-hidden? ifnot
406 r@ over >r execute ?dup if 2rdrop exit endif
415 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
416 : dump-label ( nfo -- )
418 dup nfo->nfa count type ." : 0x"
420 dup nfo->pfa @ dup .hex8 ." (" 0 .r ." ) ["
423 dup flag-undefined and if ." U" endif
424 dup flag-forward and if ." F" endif
425 dup flag-forth and ifnot ." A" endif
426 dup flag-constant and if ." C" endif
427 drop ." ]" dup nfo->dfa @ type-dfa cr
433 endcr ." 0x" dup cell+ @ .hex8
434 ." (" dup 2 +cells @ 0 .r ." )"
435 dup fix-dfa@ type-dfa
441 endcr ." === LABELS ===\n"
445 ;] foreach-label drop
450 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
452 ;; note that the parser always uppercases the labels, so
453 ;; you don't need
to worry about that
455 ;; also note that
'@' is a valid identifier
character
458 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
459 : Do-Fixups
( addr count nfo value
-- )
460 over
>r
>r
;; ( addr count nfo | nfo value
)
465 ;; ( addr count fixupitem | nfo value
)
467 ;; fixup address contains an offset
, so we need
to add it
to the value
470 ;; ( addr count fixupitem | nfo value
)
472 lman
-fixup
-debug
[IF]
473 ." FXOFS-DIRECT: " 1 rpick nfo
->nfa count type
474 ." fixaddr: 0x" dup
.hex8
475 ." [fixaddr]: 0x" dup asmx86
:asm
-d@
.hex8
476 ." value: 0x" r@
.hex8
479 ;; ( addr count fixupitem fixaddr | nfo value
)
480 dup asmx86
:asm
-d@ r@
+
481 ;; ( addr count fixupitem fixaddr
[fixaddr
]+value | nfo value
)
485 ;; ( addr count fixupitem | nfo value
)
487 lman
-fixup
-debug
[IF]
488 ." FXOFS-DISP32: " 1 rpick nfo
->nfa count type
489 ." fixaddr: 0x" dup
.hex8
490 ." [fixaddr]: " dup asmx86
:asm
-d@
0 .r
491 ." value: 0x" r@
.hex8
494 ;; ( addr count fixupitem fixaddr | nfo value
)
495 dup asmx86
:asm
-d@ r@
+
496 ;; ( addr count fixupitem fixaddr
[fixaddr
]+value | nfo value
)
497 over
4+ - ;; calc displacement
499 ;; warn
if could be short
500 over
-128 128 within
if
501 dup
1- asmx86
:asm
-c@
0xe8 <> if
503 2>r dup fix
-dfa@
" WARNING: jump range could be short" type
-dfa
-msg
-cr
510 ;; ( addr count fixupitem | nfo value
)
512 ;; ( addr count fixupitem fxaddr | nfo value
)
513 lman
-fixup
-debug
[IF]
514 ." FXOFS-DISP8: " 1 rpick nfo
->nfa count type
515 ." fixaddr: 0x" dup
.hex8
516 ." [fixaddr]: " dup asmx86
:asm
-c@ c
>s
0 .r
517 ." value: 0x" r@
.hex8
520 ;; ( addr count fixupitem fixaddr | nfo value
)
521 dup asmx86
:asm
-c@ c
>s r@
+
522 ;; ( addr count fixupitem fixaddr
[fixaddr
]+value | nfo value
)
524 over
1+ - ;; calc displacement
525 ;; ( addr count fixupitem fixaddr disp | nfo value
)
526 dup
-128 128 within ifnot
527 2drop dup fix
-dfa@
" ERROR: invalid jump range" type
-dfa
-msg
-cr
528 true asmx86
:ERRID_ASM_JUMP_OUT_OF_RANGE ?lbl
-error
533 true asmx86
:ERRID_ASM_INTERNAL_ERROR ?lbl
-error
536 ;; ( addr count | nfo value
)
540 ;; reset undefined and forward flags
541 flag
-undefined flag
-forward or r
> nfo
->ffa ~and
!
545 : Add
-Fixup
( nfo addr type
-- )
546 rot
>r
;; ( addr type | nfo
)
547 ;; allocate new fixup record
548 fix
-item
-cells cells xalloc
549 ;; ( addr type fxit | nfo
)
554 dup fix
->type rot swap
!
555 ;; create definition info
556 create
-dfa over fix
->dfa
!
562 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
563 ;; this is called by main driver
564 ;; you can throw error here
565 : MakeConstant
( addr count value
-- )
568 " MakeConstant" lbl
-debug
-msg
571 ;; no
"@@", "@f", "@b"
572 2dup is
-@fb? asmx86
:ERRID_ASM_INVALID_LABEL_NAME ?lbl
-error
-nx
574 2dup find
-label asmx86
:ERRID_ASM_DUPLICATE_CONSTANT ?lbl
-error
577 dup nfo
->pfa r
> swap
!
579 dup nfo
->ffa flag
-constant swap
!
585 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
586 : Check
-Locals
-Resolved
( -- )
588 [: ( errflag nfo
-- errflag
0 )
591 \ nfo
->nfa count true asmx86
:ERRID_ASM_UNRESOLVED_LABEL ?lbl
-error
-nx
592 over ifnot endcr
." unresolved local label(s):\n" endif
593 dup nfo
->nfa count
2 spaces type
594 dup nfo
->dfa @ type
-dfa cr
600 ;] foreach
-label drop
601 asmx86
:ERRID_ASM_UNRESOLVED_LABEL asmx86
:?asm
-error
604 : Clear
-Locals
( -- )
611 ;] foreach
-label drop
615 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
616 : Check
-@@
-Resolved
( -- )
618 dup nfo
->nfa count is
-@fb?
if
620 nfo
->nfa count true asmx86
:ERRID_ASM_UNRESOLVED_LABEL ?lbl
-error
-nx
625 ;] foreach
-label drop
630 dup nfo
->nfa count is
-@fb?
if
635 ;] foreach
-label drop
639 ;; resolve
"@f" to asm
-PC
, remove any existing
"@@" label
640 : Resolve
-@f
-And
-Remove
-@@
( -- )
642 dup nfo
->nfa count is
-@fb?
645 ;; resolve and remove
646 dup
" @f" rot asmx86
:asm
-PC
Do-Fixups
650 ;; simply remove
(code cannot access
"@@" directly
, so no need
to resolve it
)
656 ;] foreach
-label drop
660 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
661 : Clear
-Unresolved
( -- )
663 ;; do not clear forwards
664 dup nfo
->ffa @ flag
-undefined flag
-forward or and flag
-undefined
=
670 ;] foreach
-label drop
674 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
675 : Check
-Unresolved
( -- )
677 [: ( errflag nfo
-- errflag
0 )
678 ;; do not report forwards
679 dup nfo
->ffa @ flag
-undefined flag
-forward or and flag
-undefined
=
681 \ nfo
->nfa count true asmx86
:ERRID_ASM_UNRESOLVED_LABEL ?lbl
-error
-nx
682 over ifnot endcr
." unresolved label(s):\n" endif
683 dup nfo
->nfa count
2 spaces type
684 dup nfo
->dfa @ type
-dfa cr
689 ;] foreach
-label drop
690 asmx86
:ERRID_ASM_UNRESOLVED_LABEL asmx86
:?asm
-error
694 : Check
-Unresolved
-Forwards
( -- )
696 [: ( errflag nfo
-- errflag
0 )
697 ;; do not report forwards
698 dup nfo
->ffa @ flag
-undefined flag
-forward or and flag
-undefined flag
-forward or
=
700 \ nfo
->nfa count true asmx86
:ERRID_ASM_UNRESOLVED_LABEL ?lbl
-error
-nx
701 over ifnot endcr
." unresolved forward(s):\n" endif
702 dup nfo
->nfa count
2 spaces type
703 dup nfo
->dfa @ type
-dfa cr
708 ;] foreach
-label drop
709 asmx86
:ERRID_ASM_UNRESOLVED_LABEL asmx86
:?asm
-error
712 : Count
-Live
-Labels
( -- n
)
713 0 [: ( count nfo
-- count
0 )
716 ;] foreach
-label drop
720 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
721 ;; this is called by main driver
722 ;; you can throw error here
723 : MakeLabel
( addr count value
-- )
726 " MakeLabel" lbl
-debug
-msg
729 ;; check
for special labels
730 over c@
[char
] @
= if
732 2dup is
-@fb? @fb
-@
> asmx86
:ERRID_ASM_INVALID_LABEL_NAME ?lbl
-error
-nx
734 2dup is
-@fb? @fb
-@
= if Resolve
-@f
-And
-Remove
-@@
endif
736 ;; non
-local label should clear all locals
738 Check
-Locals
-Resolved
744 ;; existing label
, check type
745 dup nfo
->ffa @ flag
-undefined flag
-forward or bitnot and asmx86
:ERRID_ASM_DUPLICATE_LABEL ?lbl
-error
746 dup nfo
->ffa @ flag
-undefined and asmx86
:ERRID_ASM_DUPLICATE_LABEL not
-?lbl
-error
748 ;; ( addr count nfo | value
)
751 ;; endcr dup dump
-label
757 dup nfo
->pfa r
> swap
!
764 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
766 : MakeForthLabel
( addr count value forward
-- )
767 do-fix
-label
-name?
>r
0 to do-fix
-label
-name?
768 >r
>r
;; ( addr count | forward value
)
769 dup asmx86
:ERRID_ASM_INVALID_LABEL_NAME not
-?lbl
-error
-nx
771 ;; existing label
, check type
772 dup nfo
->ffa @ flag
-undefined and asmx86
:ERRID_ASM_DUPLICATE_LABEL not
-?lbl
-error
773 dup nfo
->ffa @ flag
-forth and asmx86
:ERRID_ASM_DUPLICATE_LABEL not
-?lbl
-error
774 nrot
2drop
;; drop label name
, we don
't need it anymore
778 ;; mark it as Forth label
779 dup nfo->ffa flag-forth swap or!
781 ;; ( nfo | forward value )
783 dup nfo->pfa r> swap !
788 dup nfo->ffa flag-undefined flag-forward or swap ~and!
789 dup nfo->nfa count rot
790 ;; ( addr count nfo )
791 dup nfo->pfa @ Do-Fixups
793 dup nfo->ffa flag-undefined flag-forward or swap or!
796 r> to do-fix-label-name?
800 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
802 ;; "-1" means that the label is not defined yet, and the value is a random prediction
803 : GetForthLabel ( addr count type -- value 1 // value -1 // false )
806 asmx86:LABEL-TYPE-CFA of forth:noop endof
807 asmx86:LABEL-TYPE-PFA of forth:cfa->pfa endof
808 \ asmx86:LABEL-TYPE-NFA of forth:cfa->nfa endof
809 \ asmx86:LABEL-TYPE-LFA of forth:cfa->nfa forth:nfa->lfa endof
810 \ asmx86:LABEL-TYPE-BFA of forth:cfa->nfa forth:nfa->bfa endof
811 \ asmx86:LABEL-TYPE-SFA of forth:cfa->nfa forth:nfa->sfa endof
812 \ asmx86:LABEL-TYPE-DFA of forth:cfa->nfa forth:nfa->dfa endof
813 \ asmx86:LABEL-TYPE-HFA of forth:cfa->nfa forth:nfa->hfa endof
814 asmx86:ERRID_ASM_INTERNAL_ERROR asmx86:asm-error
824 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
826 : GetConstant ( addr count -- value true // false )
828 " GetConstant(00)" lbl-debug-msg
830 ;; no "@@", "@f", "@b"
831 2dup is-@fb? if 2drop false exit endif
833 " GetConstant(01)" lbl-debug-msg
836 2dup find-label ifnot 2drop false exit endif
837 dup nfo->ffa @ flag-constant and if
840 endcr ." GetConstant: <" 2dup type ." :" r@ nfo->pfa @ 0 .r ." >" cr
852 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
854 ;; "-1" means that the label is not defined yet, and the value is a random prediction
855 : GetLabel ( addr count -- value 1 // value -1 // false )
857 " GetLabel(00)" lbl-debug-msg
860 2dup is-@fb? @fb-@ = asmx86:ERRID_ASM_INVALID_LABEL_NAME ?lbl-error-nx
861 ;; "@b" should resolve to the last "@@", so simply replace the name
864 " GetLabel(01)" lbl-debug-msg
866 ;; check if such label exists
867 2dup find-label ifnot
868 ;; "@b" without "@@" should not be allowed
869 2dup is-@fb? @fb-b = asmx86:ERRID_ASM_INVALID_BACKWARD_REF ?lbl-error-nx
873 dup nfo->ffa flag-undefined
874 asmx86:asm-Labman-Unresolved-As-Forwards? if flag-forward or endif
876 ;; predict value (our predictor is highly sophisticated!)
877 asmx86:asm-$ dup rot nfo->pfa !
878 -1 ;; random predition
881 dup nfo->ffa @ flag-constant and asmx86:ERRID_ASM_TYPE_MISMATCH ?lbl-error
887 swap nfo->ffa @ flag-undefined and if -1 else 1 endif
892 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
894 : LabelDefined? ( addr count -- flag )
896 " LabelDefined?(00)" lbl-debug-msg
898 ;; "@f" is never defined
899 2dup is-@fb? @fb-f = if 2drop false exit endif
900 ;; "@b" is defined if "@@" is defined, so simply replace the name
903 " LabelDefined?(01)" lbl-debug-msg
905 ;; check if such label exists
906 find-label ifnot false exit endif
908 nfo->ffa @ flag-undefined and not
912 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
913 : JxxFixupLabel ( addr count disp32flag -- )
914 >r ;; move that flag away, we'll use it later
915 ;; "@b" should resolve
to the last
"@@", so simply replace the name
917 lman
-fixup
-debug
[IF]
918 " JxxFixupLabel" lbl
-debug
-msg
920 ;; the label must be already created here
921 \
2dup find
-label asmx86
:ERRID_ASM_UNRESOLVED_LABEL not
-?lbl
-error
-nx
922 2dup find
-label ifnot
923 lman
-allow
-forth
-implicit if
924 2dup wfind asmx86
:ERRID_ASM_UNRESOLVED_LABEL not
-?lbl
-error
-nx
927 else false asmx86
:ERRID_ASM_UNRESOLVED_LABEL not
-?lbl
-error
-nx
930 ;; and it must be a code label
931 dup nfo
->ffa @ flag
-constant and asmx86
:ERRID_ASM_TYPE_MISMATCH ?lbl
-error
-nx
932 ;; check
if we have
to add the asm
-PC
to the fixup list
933 dup nfo
->ffa @ flag
-undefined and
if
935 dup asmx86
:asm
-PC r@
if fxtype
-disp32
else fxtype
-disp8
endif Add
-Fixup
944 : FixupJmpLabel
( addr count type
-- )
945 ;; ignore label type
(for now
)
946 ;; label creation code should make sure that the Forth fixup add
(in memory
) is right
for CFA
/PFA
/ETC
948 lman
-fixup
-debug
[IF]
949 " FixupJmpLabel" lbl
-debug
-msg
956 : FixupJRLabel
( addr count type
-- )
957 ;; ignore label type
(for now
)
958 ;; label creation code should make sure that the Forth fixup add
(in memory
) is right
for CFA
/PFA
/ETC
960 lman
-fixup
-debug
[IF]
961 " FixupJRLabel" lbl
-debug
-msg
967 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
969 : LabelFixup
( addr count size type
-- )
970 ;; ignore label type
(for now
)
971 ;; label creation code should make sure that the Forth fixup add
(in memory
) is right
for CFA
/PFA
/ETC
973 4 = asmx86
:ERRID_ASM_INVALID_FORWARD_REF asmx86
:not
-?asm
-error
974 lman
-fixup
-debug
[IF]
975 " LabelFixup" lbl
-debug
-msg
977 ;; the label must be already created here
979 lman
-allow
-forth
-implicit if
981 2dup wfind
if drop
2drop exit
endif
982 false asmx86
:ERRID_ASM_UNRESOLVED_LABEL not
-?lbl
-error
-nx
985 asmx86
:ERRID_ASM_UNRESOLVED_LABEL not
-?lbl
-error
-nx
987 ;; and it must not be a constant
988 dup nfo
->ffa @ flag
-constant and asmx86
:ERRID_ASM_TYPE_MISMATCH ?lbl
-error
-nx
989 ;; check
if we have
to add the asm
-PC
to the fixup list
990 dup nfo
->ffa @ flag
-undefined and
if
992 lman
-fixup
-debug
[IF]
993 ." LabelFixup NEW: " dup nfo
->nfa count type
994 ." fixaddr: 0x" asmx86
:asm
-PC
.hex8
995 ." [fixaddr]: 0x" asmx86
:asm
-PC asmx86
:asm
-d@
.hex8
998 dup asmx86
:asm
-PC fxtype
-direct Add
-Fixup
1000 ;; and drop all crap
1005 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1006 ;; called by
"CODE:" compiler
1007 : CheckUndefLabels
( -- )
1011 Check
-Locals
-Resolved
1018 \ Count
-Live
-Labels ifnot Reinit
endif
1022 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1023 ;; used by metacompiler
1024 ;; called before metacompiler is going
to generate the binary
1025 : FinalCheckUndefLabels
( -- )
1027 Check
-Unresolved
-Forwards
1030 \ Count
-Live
-Labels ifnot Reinit
endif
1034 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1035 ;; called by `asm
-error`
1042 \ Count
-Live
-Labels ifnot Reinit
endif
1046 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1050 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1051 previous definitions
1053 ;; plug in our label manager
1055 ' asm-labman:ErrorReset to asmx86:asm-Labman-Error-Reset
1056 ' asm
-labman
:Reinit
to asmx86
:asm
-Labman
-Reinit
1057 ' asm-labman:MakeConstant to asmx86:asm-Make-Constant
1058 ' asm
-labman
:MakeLabel
to asmx86
:asm
-Make
-Label
1059 ' asm-labman:MakeForthLabel to asmx86:asm-Make-Forth-Label
1060 ' asm
-labman
:GetForthLabel
to asmx86
:asm
-Get
-Forth
-Word
1061 ' asm-labman:GetLabel to asmx86:asm-Get-Label
1062 ' asm
-labman
:GetConstant
to asmx86
:asm
-Get
-Constant
1063 ' asm-labman:LabelDefined? to asmx86:asm-Label-Defined?
1064 ' asm
-labman
:FixupJmpLabel
to asmx86
:asm
-Jmp
-Label
-Fixup
1065 ' asm-labman:FixupJRLabel to asmx86:asm-JR-Label-Fixup
1066 ' asm
-labman
:LabelFixup
to asmx86
:asm
-Label
-Fixup
1067 ' asm-labman:CheckUndefLabels to asmx86:asm-Check-Undef-Labels
1068 ' asm
-labman
:FinalCheckUndefLabels
to asmx86
:asm
-Check
-Undef
-Labels
-Final
1069 ' asm-labman:dump-labels to asmx86:asm-Dump-Labels