--- gforth/cross.fs 1998/05/02 21:28:41 1.54 +++ gforth/cross.fs 1999/05/05 18:07:51 1.74 @@ -1,7 +1,7 @@ \ CROSS.FS The Cross-Compiler 06oct92py \ Idea and implementation: Bernd Paysan (py) -\ Copyright (C) 1995 Free Software Foundation, Inc. +\ Copyright (C) 1995,1996,1997,1998,1999 Free Software Foundation, Inc. \ This file is part of Gforth. @@ -19,32 +19,17 @@ \ along with this program; if not, write to the Free Software \ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -\ Log: -\ changed in ; [ to state off 12may93jaw -\ included place +place 12may93jaw -\ for a created word (variable, constant...) -\ is now an alias in the target voabulary. -\ this means it is no longer necessary to -\ switch between vocabularies for variable -\ initialization 12may93jaw -\ discovered error in DOES> -\ replaced !does with (;code) 16may93jaw -\ made complete redesign and -\ introduced two vocs method -\ to be asure that the right words -\ are found 08jun93jaw -\ btw: ! works not with 16 bit -\ targets 09jun93jaw -\ added: 2user and value 11jun93jaw - -\ needed? works better now!!! 01mar97jaw -\ mach file is only loaded into target -\ cell corrected -\ romable extansions 27apr97-5jun97jaw -\ environmental query support 01sep97jaw -\ added own [IF] ... [ELSE] ... [THEN] 14sep97jaw -\ extra resolver for doers 20sep97jaw -\ added killref for DOES> 20sep97jaw +0 +[IF] + +ToDo: +Crossdoc destination ./doc/crossdoc.fd makes no sense when +cross.fs is uses seperately. jaw +Do we need this char translation with >address and in branchoffset? +(>body also affected) jaw +Clean up mark> and >resolve stuff jaw + +[THEN] hex \ the defualt base for the cross-compiler is hex !! @@ -52,6 +37,7 @@ Warnings off \ words that are generaly useful +: KB 400 * ; : >wordlist ( vocabulary-xt -- wordlist-struct ) also execute get-order swap >r 1- set-order r> ; @@ -66,16 +52,21 @@ Warnings off \G Same behaviour as "Value" if the is not defined \G Same behaviour as "to" if is defined \G SetValue searches in the current vocabulary - save-input bl word >r restore-input throw r> count - get-current search-wordlist - IF bl word drop >body ! ELSE Value THEN ; + save-input bl word >r restore-input throw r> count + get-current search-wordlist + IF drop >r + \ we have to set current to be topmost context wordlist + get-order get-order get-current swap 1+ set-order + r> ['] to execute + set-order + ELSE Value THEN ; : DefaultValue ( n -- ) \G Same behaviour as "Value" if the is not defined \G DefaultValue searches in the current vocabulary save-input bl word >r restore-input throw r> count get-current search-wordlist - IF bl word drop drop drop ELSE Value THEN ; + IF bl word drop 2drop ELSE Value THEN ; hex @@ -127,8 +118,9 @@ also forth definitions \ these values m false DefaultValue stack-warn \ check on empty stack at any definition false DefaultValue create-forward-warn \ warn on forward declaration of created words -[IFUNDEF] DebugMaskSrouce Variable DebugMaskSource 0 DebugMaskSource ! [THEN] -[IFUNDEF] DebugMaskCross Variable DebugMaskCross 0 DebugMaskCross ! [THEN] + + + previous >CROSS @@ -152,7 +144,46 @@ stack-warn [IF] : defempty? ; immediate [THEN] +\ debugging +0 [IF] + +This implements debugflags for the cross compiler and the compiled +images. It works identical to the has-flags in the environment. +The debugflags are defined in a vocabluary. If the word exists and +its value is true, the flag is switched on. + +[THEN] + +Vocabulary debugflags \ debug flags for cross +also debugflags get-order over +Constant debugflags-wl +set-order previous + +: DebugFlag + get-current >r debugflags-wl set-current + SetValue + r> set-current ; + +: Debug? ( adr u -- flag ) +\G return true if debug flag is defined or switched on + debugflags-wl search-wordlist + IF EXECUTE + ELSE false THEN ; + +: D? ( -- flag ) +\G return true if debug flag is defined or switched on +\G while compiling we do not return the current value but + bl word count debug? ; + +: [d?] +\G compile the value-xt so the debug flag can be switched +\G the flag must exist! + bl word count debugflags-wl search-wordlist + IF compile, + ELSE -1 ABORT" unknown debug flag" + \ POSTPONE false + THEN ; immediate \ \ GhostNames Ghosts 9may93jaw @@ -281,13 +312,13 @@ VARIABLE env-current \ save information >TARGET -: environment? +: environment? ( adr len -- [ x ] true | false ) target-environment search-wordlist IF execute true ELSE false THEN ; -: e? name T environment? H 0= ABORT" environment variable not defined!" ; +: e? bl word count T environment? H 0= ABORT" environment variable not defined!" ; -: has? name T environment? H +: has? bl word count T environment? H IF \ environment variable is present, return its value ELSE \ environment variable is not present, return false \ !! JAW abort is just for testing @@ -302,6 +333,7 @@ true SetValue cross true SetValue standard-threading >TARGET previous + mach-file count included hex >ENVIRON @@ -323,6 +355,7 @@ false DefaultValue header true DefaultValue interpreter true DefaultValue ITC false DefaultValue rom +true DefaultValue standardthreading >TARGET s" relocate" T environment? H @@ -334,15 +367,43 @@ s" relocate" T environment? H \ \ Create additional parameters 19jan95py +\ currently cross only works for host machines with address-unit-bits +\ eual to 8 because of s! and sc! +\ but I start to query the environment just to modularize a little bit + +: check-address-unit-bits ( -- ) +\ s" ADDRESS-UNIT-BITS" environment? +\ IF 8 <> ELSE true THEN +\ ABORT" ADDRESS-UNIT-BITS unknown or not equal to 8!" + +\ shit, this doesn't work because environment? is only defined for +\ gforth.fi and not kernl???.fi + ; + +check-address-unit-bits +8 Constant bits/byte \ we define: byte is address-unit + +1 bits/byte lshift Constant maxbyte +\ this sets byte size for the target machine, an (probably right guess) jaw + T -NIL Constant TNIL -cell Constant tcell -cell<< Constant tcell<< -cell>bit Constant tcell>bit -bits/byte Constant tbits/byte -float Constant tfloat -1 bits/byte lshift Constant maxbyte +NIL Constant TNIL +cell Constant tcell +cell<< Constant tcell<< +cell>bit Constant tcell>bit +bits/char Constant tbits/char +bits/char H bits/byte T / + Constant tchar +float Constant tfloat +1 bits/char lshift Constant tmaxchar +[IFUNDEF] bits/byte +8 Constant tbits/byte +[ELSE] +bits/byte Constant tbits/byte +[THEN] H +tbits/byte bits/byte / Constant tbyte + \ Variables 06oct92py @@ -357,31 +418,12 @@ Variable bit$ Variable headers-named 0 headers-named ! Variable user-vars 0 user-vars ! -\ Memory initialisation 05dec92py - -[IFDEF] Memory \ Memory is a bigFORTH feature - also Memory - : initmem ( var len -- ) - 2dup swap handle! >r @ r> erase ; - toss -[ELSE] - : initmem ( var len -- ) - tuck allocate abort" CROSS: No memory for target" - ( len var adr ) dup rot ! - ( len adr ) swap erase ; -[THEN] - -\ MakeKernal 12dec92py - -: makekernel ( targetsize -- targetsize ) - bit$ over 1- tcell>bit rshift 1+ initmem - image over initmem ; +: target>bitmask-size ( u1 -- u2 ) + 1- tcell>bit rshift 1+ ; ->MINIMAL -: makekernel makekernel ; - - ->CROSS +: allocatetarget ( size --- adr ) + dup allocate ABORT" CROSS: No memory for target" + swap over swap erase ; \ \ memregion.fs @@ -392,6 +434,10 @@ Variable mirrored-link \ linked 0 dup mirrored-link ! region-link ! +: >rname 6 cells + ; +: >rbm 5 cells + ; +: >rmem 4 cells + ; +: >rlink 3 cells + ; : >rdp 2 cells + ; : >rlen cell+ ; : >rstart ; @@ -405,27 +451,28 @@ Variable mirrored-link \ linked save-input create restore-input throw here last-defined-region ! over ( startaddr ) , ( length ) , ( dp ) , - region-link linked name string, + region-link linked 0 , 0 , bl word count string, ELSE \ store new parameters in region bl word drop >body >r r@ last-defined-region ! - r@ cell+ ! dup r@ ! r> 2 cells + ! + r@ >rlen ! dup r@ >rstart ! r> >rdp ! THEN ; : borders ( region -- startaddr endaddr ) \G returns lower and upper region border - dup @ swap cell+ @ over + ; + dup >rstart @ swap >rlen @ over + ; : extent ( region -- startaddr len ) \G returns the really used area - dup @ swap 2 cells + @ over - ; + dup >rstart @ swap >rdp @ over - ; : area ( region -- startaddr totallen ) \G returns the total area - dup @ swap cell+ @ ; + dup >rstart swap >rlen @ ; : mirrored \G mark a region as mirrored mirrored-link - linked last-defined-region @ , ; + align linked last-defined-region @ , ; -: .addr +: .addr ( u -- ) +\G prints a 16 or 32 Bit nice hex value base @ >r hex tcell 2 u> IF s>d <# # # # # '. hold # # # # #> type @@ -439,18 +486,19 @@ Variable mirrored-link \ linked 0 region-link @ BEGIN dup WHILE dup @ REPEAT drop BEGIN dup - WHILE cr 3 cells - >r - r@ 4 cells + count tuck type + WHILE cr + 0 >rlink - >r + r@ >rname count tuck type 12 swap - 0 max spaces space - ." Start: " r@ @ dup .addr space - ." End: " r@ 1 cells + @ + .addr space - ." DP: " r> 2 cells + @ .addr + ." Start: " r@ >rstart @ dup .addr space + ." End: " r@ >rlen @ + .addr space + ." DP: " r> >rdp @ .addr REPEAT drop s" rom" T $has? H 0= ?EXIT cr ." Mirrored:" mirrored-link @ BEGIN dup - WHILE space dup cell+ @ 4 cells + count type @ + WHILE space dup cell+ @ >rname count type @ REPEAT drop cr ; @@ -482,10 +530,10 @@ T has? rom H : setup-target ( -- ) \G initialize targets memory space s" rom" T $has? H IF \ check for ram and rom... - address-space area nip - ram-dictionary area nip - rom-dictionary area nip - and and 0= + \ address-space area nip 0<> + ram-dictionary area nip 0<> + rom-dictionary area nip 0<> + and 0= ABORT" CROSS: define address-space, rom- , ram-dictionary, with rom-support!" THEN address-space area nip @@ -494,9 +542,36 @@ T has? rom H ELSE dictionary area THEN - dup 0= + nip 0= ABORT" CROSS: define at least address-space or dictionary!!" - + makekernel drop ; + + \ allocate target for each region + region-link + BEGIN @ dup + WHILE dup + 0 >rlink - >r + r@ >rlen @ + IF \ allocate mem + r@ >rlen @ dup + + allocatetarget dup image ! + r@ >rmem ! + + target>bitmask-size allocatetarget + dup bit$ ! + r> >rbm ! + + ELSE r> drop THEN + REPEAT drop ; + +\ MakeKernal 22feb99jaw + +: makekernel ( targetsize -- targetsize ) + dup dictionary >rlen ! setup-target ; + +>MINIMAL +: makekernel makekernel ; +>CROSS \ \ switched tdp for rom support 03jun97jaw @@ -532,16 +607,20 @@ variable fixed \ flag: true: no automat variable constflag constflag off +: activate ( region -- ) +\G next code goes to this region + >rdp to tdp ; + : (switchram) fixed @ ?EXIT s" rom" T $has? H 0= ?EXIT - ram-dictionary >rdp to tdp ; + ram-dictionary activate ; : switchram constflag @ IF constflag off ELSE (switchram) THEN ; : switchrom - fixed @ ?EXIT rom-dictionary >rdp to tdp ; + fixed @ ?EXIT rom-dictionary activate ; : >tempdp ( addr -- ) tdp tempdp-save ! tempdp to tdp tdp ! ; @@ -557,7 +636,7 @@ variable constflag constflag off \ : romstart dup sromdp ! romdp ! ; \ : ramstart dup sramdp ! ramdp ! ; -\ default compilation goed to rom +\ default compilation goes to rom \ when romable support is off, only the rom switch is used (!!) >auto @@ -571,8 +650,8 @@ variable constflag constflag off : cell+ tcell + ; : cells tcell<< lshift ; -: chars ; -: char+ 1 + ; +: chars tchar * ; +: char+ tchar + ; : floats tfloat * ; >CROSS @@ -589,14 +668,47 @@ bigendian DO maxbyte ud/mod rot I c! -1 +LOOP 2drop ; : S@ ( addr -- n ) >r 0 0 r> tcell bounds DO maxbyte * swap maxbyte um* rot + swap I c@ + swap LOOP d>s ; + : Sc! ( n addr -- ) >r s>d r> tchar bounds swap 1- + DO maxbyte ud/mod rot I c! -1 +LOOP 2drop ; + : Sc@ ( addr -- n ) >r 0 0 r> tchar bounds + DO maxbyte * swap maxbyte um* rot + swap I c@ + swap LOOP d>s ; [ELSE] : S! ( n addr -- ) >r s>d r> tcell bounds DO maxbyte ud/mod rot I c! LOOP 2drop ; : S@ ( addr -- n ) >r 0 0 r> tcell bounds swap 1- DO maxbyte * swap maxbyte um* rot + swap I c@ + swap -1 +LOOP d>s ; + : Sc! ( n addr -- ) >r s>d r> tchar bounds + DO maxbyte ud/mod rot I c! LOOP 2drop ; + : Sc@ ( addr -- n ) >r 0 0 r> tchar bounds swap 1- + DO maxbyte * swap maxbyte um* rot + swap I c@ + swap -1 +LOOP d>s ; [THEN] ->CROSS +: taddr>region ( taddr -- region | 0 ) +\G finds for a target-address the correct region +\G returns 0 if taddr is not in range of a target memory region + region-link + BEGIN @ dup + WHILE dup >r + 0 >rlink - >r + r@ >rlen @ + IF dup r@ borders within + IF r> r> drop nip EXIT THEN + THEN + r> drop + r> + REPEAT + 2drop 0 ; + +: (>regionimage) ( taddr -- 'taddr ) + dup + \ find region we want to address + taddr>region dup 0= ABORT" Address out of range!" + >r + \ calculate offset in region + r@ >rstart @ - + \ add regions real address in our memory + r> >rmem @ + ; + \ Bit string manipulation 06oct92py \ 9may93jaw CREATE Bittable 80 c, 40 c, 20 c, 10 c, 8 c, 4 c, 2 c, 1 c, @@ -605,8 +717,27 @@ CREATE Bittable 80 c, 40 c, 20 c, 10 c, : >bit ( addr n -- c-addr mask ) 8 /mod rot + swap bits ; : +bit ( addr n -- ) >bit over c@ or swap c! ; : -bit ( addr n -- ) >bit invert over c@ and swap c! ; -: relon ( taddr -- ) bit$ @ swap cell/ +bit ; -: reloff ( taddr -- ) bit$ @ swap cell/ -bit ; + +: (relon) ( taddr -- ) bit$ @ swap cell/ +bit ; +: (reloff) ( taddr -- ) bit$ @ swap cell/ -bit ; + +: (>image) ( taddr -- absaddr ) image @ + ; + +DEFER >image +DEFER relon +DEFER reloff +DEFER correcter + +T has? relocate H +[IF] +' (relon) IS relon +' (reloff) IS reloff +' (>image) IS >image +[ELSE] +' drop IS relon +' drop IS reloff +' (>regionimage) IS >image +[THEN] \ Target memory access 06oct92py @@ -624,13 +755,10 @@ CREATE Bittable 80 c, 40 c, 20 c, 10 c, \ see kernel.fs dup cfalign+ + ; ->CROSS -: >image ( taddr -- absaddr ) image @ + ; ->TARGET : @ ( taddr -- w ) >image S@ ; : ! ( w taddr -- ) >image S! ; -: c@ ( taddr -- char ) >image c@ ; -: c! ( char taddr -- ) >image c! ; +: c@ ( taddr -- char ) >image Sc@ ; +: c! ( char taddr -- ) >image Sc! ; : 2@ ( taddr -- x1 x2 ) T dup cell+ @ swap @ H ; : 2! ( x1 x2 taddr -- ) T swap over ! cell+ ! H ; @@ -640,24 +768,27 @@ CREATE Bittable 80 c, 40 c, 20 c, 10 c, : here ( -- there ) there ; : allot ( n -- ) tdp +! ; : , ( w -- ) T here H tcell T allot ! H T here drop H ; -: c, ( char -- ) T here 1 allot c! H ; -: align ( -- ) T here H align+ 0 ?DO bl T c, H LOOP ; +: c, ( char -- ) T here tchar allot c! H ; +: align ( -- ) T here H align+ 0 ?DO bl T c, tchar H +LOOP ; : cfalign ( -- ) - T here H cfalign+ 0 ?DO bl T c, H LOOP ; + T here H cfalign+ 0 ?DO bl T c, tchar H +LOOP ; -: A! dup relon T ! H ; -: A, ( w -- ) T here H relon T , H ; +: >address dup 0>= IF tbyte / THEN ; \ ?? jaw +: A! swap >address swap dup relon T ! H ; +: A, ( w -- ) >address T here H relon T , H ; >CROSS : tcmove ( source dest len -- ) \G cmove in target memory - bounds + tchar * bounds ?DO dup T c@ H I T c! H 1+ - LOOP drop ; + tchar +LOOP drop ; + +\ \ Load Assembler >TARGET -H also Forth definitions \ ." asm: " order +H also Forth definitions : X also target bl word find IF state @ IF compile, @@ -753,8 +884,9 @@ DEFER comp[ \ ends compilation : >fl-name 2 cells + ; Variable filelist 0 filelist ! +Create NoFile ," #load-file#" 0 Value filemem -: loadfile filemem >fl-name ; +: loadfile FileMem ?dup IF >fl-name ELSE NoFile THEN ; 1 [IF] \ !! JAW WIP @@ -774,8 +906,11 @@ Variable filelist 0 filelist ! REPEAT 2drop drop false ; +false DebugFlag showincludedfiles + : included -\ cr ." Including: " 2dup type ." ..." + [d?] showincludedfiles + IF cr ." Including: " 2dup type ." ..." THEN FileMem >r 2dup add-included-file included r> to FileMem ; @@ -992,7 +1127,7 @@ VARIABLE ^imm \ Target Document Creation (goes to crossdoc.fd) 05jul95py -s" doc/crossdoc.fd" r/w create-file throw value doc-file-id +s" ./doc/crossdoc.fd" r/w create-file throw value doc-file-id \ contains the file-id of the documentation file : T-\G ( -- ) @@ -1105,7 +1240,7 @@ NoHeaderFlag off IF NoHeaderFlag off ELSE T align H view, - tlast @ dup 0> IF T 1 cells - THEN A, H there tlast ! + tlast @ dup 0> IF T 1 cells - H THEN T A, H there tlast ! 1 headers-named +! \ Statistic >in @ T name, H >in ! THEN @@ -1151,6 +1286,11 @@ VARIABLE ;Resolve 1 cells allot .sourcepos ." needs doer: " >in @ bl word count type >in ! cr THEN ghost tuck swap resolve swap >magic ! ; + +Variable prim# +: first-primitive ( n -- ) prim# ! ; +: Primitive ( -- ) \ name + prim# @ T Alias H -1 prim# +! ; >CROSS \ Conditionals and Comments 11may93jaw @@ -1213,7 +1353,7 @@ Cond: ['] T ' H alit, ;Cond \ modularized 14jun97jaw : fillcfa ( usedcells -- ) - T cells H xt>body swap - 0 ?DO 0 T c, H LOOP ; + T cells H xt>body swap - 0 ?DO 0 T c, tchar H +LOOP ; : (>body) ( cfa -- pfa ) xt>body + ; ' (>body) T IS >body H @@ -1234,7 +1374,13 @@ Cond: ['] T ' H alit, ;Cond : (lit,) ( n -- ) compile lit T , H ; ' (lit,) IS lit, -: (alit,) ( n -- ) lit, T here cell - H relon ; ' (alit,) IS alit, +\ if we dont produce relocatable code alit, defaults to lit, jaw +has? relocate +[IF] +: (alit,) ( n -- ) compile lit T a, H ; ' (alit,) IS alit, +[ELSE] +: (alit,) ( n -- ) lit, ; ' (alit,) IS alit, +[THEN] : (fini,) compile ;s ; ' (fini,) IS fini, @@ -1263,7 +1409,7 @@ Defer (end-code) ELSE true ABORT" CROSS: Stack empty" THEN ; -Cond: chars ;Cond +( Cond ) : chars tchar * ; ( Cond ) >CROSS @@ -1621,7 +1767,7 @@ Builder Field : sys? ( sys -- sys ) dup 0= ?struc ; : >mark ( -- sys ) T here ( dup ." M" hex. ) 0 , H ; -: branchoffset ( src dest -- ) - ; +: branchoffset ( src dest -- ) - tchar / ; \ ?? jaw : >resolve ( sys -- ) T here ( dup ." >" hex. ) over branchoffset swap ! H ; @@ -1745,7 +1891,7 @@ Cond: ENDCASE restrict? compile drop 0 \ Structural Conditionals 12dec92py -:noname +:noname \ ?? i think 0 is too much! jaw 0 compile (do) branchtomark, 2 to1 ; IS do, ( -- target-addr ) @@ -1786,7 +1932,7 @@ Cond: S" restrict? compile (S") Cond: ABORT" restrict? compile (ABORT") T ," H ;Cond Cond: IS T ' >body H compile ALiteral compile ! ;Cond -: IS T ' >body ! H ; +: IS T >address ' >body ! H ; Cond: TO T ' >body H compile ALiteral compile ! ;Cond : TO T ' >body ! H ; @@ -1917,8 +2063,10 @@ Cond: [IFUNDEF] postpone [IFUNDEF] ;Cond also minimal -\G doesn't skip line when bit is set in debugmask -: \D name evaluate debugmasksource @ and 0= IF postpone \ THEN ; +: d? d? ; + +\G doesn't skip line when debug switch is on +: \D D? 0= IF postpone \ THEN ; \G interprets the line if word is not defined : \- defined? IF postpone \ THEN ; @@ -1941,9 +2089,18 @@ previous \ save-cross 17mar93py >CROSS -Create magic s" Gforth10" here over allot swap move +Create magic s" Gforth2x" here over allot swap move -char 1 bigendian + tcell + magic 7 + c! +bigendian 1+ \ strangely, in magic big=0, little=1 +tcell 1 = 0 and or +tcell 2 = 2 and or +tcell 4 = 4 and or +tcell 8 = 6 and or +tchar 1 = $00 and or +tchar 2 = $28 and or +tchar 4 = $50 and or +tchar 8 = $78 and or +magic 7 + c! : save-cross ( "image-name" "binary-name" -- ) bl parse ." Saving to " 2dup type cr @@ -1972,7 +2129,7 @@ char 1 bigendian + tcell + magic 7 + c! : save-region ( addr len -- ) bl parse w/o bin create-file throw >r - swap image @ + swap r@ write-file throw + swap >image swap r@ write-file throw r> close-file throw ; \ words that should be in minimal @@ -1984,6 +2141,8 @@ also minimal bigendian Constant bigendian : here there ; +: equ constant ; +: mark there constant ; \ compiler directives : >ram >ram ; @@ -1993,7 +2152,8 @@ bigendian Constant bigendian : tempdp> tempdp> ; : const constflag on ; : warnings name 3 = 0= twarnings ! drop ; -: | NoHeaderFlag on ; +: | ; +\ : | NoHeaderFlag on ; \ This is broken (damages the last word) : save-cross save-cross ; : save-region save-region ; @@ -2076,7 +2236,7 @@ minimal \ these ones are pefered: : lock turnkey ; -: unlock forth also cross ; +: unlock previous forth also cross ; : [[ also unlock ; : ]] previous previous ;