home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
forth
/
compiler
/
fpc
/
source
/
optimiz.seq
< prev
next >
Wrap
Text File
|
1991-03-13
|
24KB
|
542 lines
\ OPTIMIZ.SEQ Library Optimizers for Target Compiler
ONLY FORTH ALSO COMPILER ALSO DEFINITIONS TARGET ALSO
>FORTH
FORTH
: TVER ." 8086 Version 2.06 " ;
' TVER IS TVERSION \ install startup message
WARNING OFF \ NO REDEFINITION WARNING IN LIBRARY
FORTH \ we want a Forth NOT a target variable
VARIABLE IMM-HERE \ Most recent place where immediate move
\ to BX was compiled
\ ***************************************************************************
\ New function for END-CODE, needs to not use REVEAL
assembler also forth also
: CEND-CODE ( -- )
ll-global? 0=
if ll-errs? \ check for local label errors
then
ARUNSAVE IS RUN
PREVIOUS A; ;
previous previous target
: %END-MACRO ( -- ) \ complete assembly of a MACRO
?reopt
[assembler]
compile a; \ make sure assembler is done
compile cend-code \ pop assembler vocabulary
[compile] FOR; ; \ complete colon def
' %END-MACRO IS END-MACRO \ install in END-MACRO
: %END-LCODE ( -- ) \ complete assembly of a LCODE
?reopt
[assembler]
compile a; \ make sure assembler is done
compile cend-code \ pop assembler vocabulary
[compile] FOR; ; \ complete colon def
' %END-LCODE IS END-LCODE \ install in END-LCODE
: %END-L: ( -- ) \ complete a library CALL definition
[assembler]
compile setassem
compile ret
compile a; \ make sure assembler is done
compile cend-code \ pop assembler vocabulary
compile unnest ; \ complete colon def
' %END-L: IS END-L:
: %END-LM: ( -- ) \ complete a library MACRO : definition
[assembler]
compile setassem
compile cend-code
compile unnest ; \ complete colon def
' %END-LM: IS END-LM:
: %END-T: ( -- ) \ complete a target CALL definition
[assembler]
setassem \ do assembler setup
ret a; \ terminate with a RET instruction
fend-code ; \ do assembler finishup
' %END-T: IS END-T:
' NOOP IS START-T: \ no start needed in CALL threaded system
: %COMP_CALL ( a1 -- ) \ a1 = CFA of symbol
232 C,-T \ compile CALL
dup >resaddr @ dup -1 <> \ if resolved already
if here-t 2+ - ,-T \ resolve this call
>count incr \ bump use count
\ ELSE, add it to the chain of
else drop \ discard the "-1"
\ references to be resolved.
dup >chain @ ,-T \ link chain @ to here
here-t 2- over >chain ! \ link here into chain
>res \ add to resolution stack
then ;
' %COMP_CALL IS COMP_CALL
: %COMP_JMP_IMM ( a1 -- ) \ a1 = actual address
233 C,-T HERE-T 2+ - ,-T ;
' %COMP_JMP_IMM IS COMP_JMP_IMM
: %SUB_RET ( -- )
-1 ALLOT-T ; \ remove a one byte RET instruction
\ preceeding us in memory
' %SUB_RET IS SUB_RET
: %TCODE-START ( -- )
setassem
init_labels ; \ ********* 01/29/91
' %TCODE-START IS TCODE-START
: %LCODE-START ( -- )
compile tcode-start \ initialize the assembler
assembler ; \ and select assembler vocabulary now!
' %LCODE-START IS LCODE-START
: %MACRO-START ( -- )
compile setassem \ initialize the assembler
assembler ; \ and select assembler vocabulary now!
' %MACRO-START IS MACRO-START
\ ***************************************************************************
\ Start of the set of functions supported in the target compiler.
\ These are mostely macros which will compile in-line assembly code.
\ Colon definitions are compiled as routines when defined, and are
\ accessed by a CALL when referenced.
ONLY FORTH ALSO COMPILER ALSO HTARGET ALSO TARGET ALSO DEFINITIONS
ASSEMBLER ALSO
>LIBRARY \ Select the Library versions of
\ defining words.
\ ***************************************************************************
\ DONOT CHANGE the first three instructions of SYSINIT. The ADD instruction
\ must be HOT patched by the image save routine so DS will be set properly
\ when the image loads in. The $E4F6 value is verified by the patch routine
\ to make sure the code has not changed. It is then replaced with the proper
\ value to add to AX so DS will be correct.
VARIABLE DP \ DP is really a variable that always exists,
\ and is always at address DATA-START.
DP [FORTH] DROP [TARGET] \ allocate it NOW to assure it's at
\ the beginning.
VARIABLE RP0
VARIABLE SP0
VARIABLE 'TIB
MACRO IMAGE-INIT ( -- ) \ Target compiler runtime initialization
[ASSEMBLER]
\ ********** DON'T CHANGE THE NEXT EIGHT LINES **********
MOV AX, CS \ get a copy of the CODE segment
ADD AX, # $E4F6 a; \ patched later to adjust for
\ where the data really is.
here-t 2- =: data-seg+ \ set patch pointer
MOV DS, AX a; \ Set the data segment
\ down 256 bytes from call stack
\ **********************************************************
[FORTH]
ram-seg -1 <> \ is this a romable system
IF \ if it is, include the code to
\ move rom data into ram
[ASSEMBLER]
MOV CX, DATA-START \ DATA-START = HERE
MOV AX, # RAM-SEG
MOV ES, AX \ ES = RAM-SEG
SUB SI, SI
SUB DI, DI \ clear DI, and SI
MOVSB REP \ move ROM into RAM
MOV AX, ES
MOV DS, AX \ reset DS to ES=RAM
[FORTH]
THEN
[ASSEMBLER]
MOV SS, AX \ set hardware stack segment to DS
MOV AX, # RPTOP
MOV SP, AX \ set hardware stack register
MOV RP0 AX \ set Forth return stack top variable
MOV AX, # RPTOP RPSIZE -
MOV SI, AX \ set data stack
MOV 'TIB AX \ init 'TIB to two bytes above SP0
MOV 0 [SI], # 0 WORD \ Initialize data stack with a zero
SUB AX, # 2
MOV SP0 AX \ set Forth data stack top variable
MOV BX, # 0 \ and top of stack register with zero
MOV BP, BX \ !!!!!BP WILL ALWAYS BE ZERO!!!!!
CALL L$ \ CALL default initialization program
CALL L$ \ CALL real program (gets patched)
here-t 2- =: cold_start \ set patch pointer
SUB AX, AX
MOV DX, AX
INT $21 \ terminate back to DOS
L$: L$: END-MACRO
FORTH DEFINITIONS >FORTH
DEFER DEF-INIT \ default target initialization
DEFER NO-INIT \ default NO initialization
: TARGET-INIT ( -- ) \ initialize the terget compiler
?LIB ABORT" Cant use TARGET-INIT in a library routine"
ONLY FORTH ALSO COMPILER ALSO
TARGET ALSO DEFINITIONS ASSEMBLER ALSO
\ ************ 01/29/91
$100 org \ 8086 code starts at $0100 in code segment
$02 dorg \ 8086 data starts at $0000 in data segment
\ but DP is there, and more are at $0002
tseg_init \ Initialize the target compile buffer
>target \ select target defining words
target \ Select the target vocabulary
F['] IMAGE-INIT \ address of init routine
DUP >COUNT INCR \ mark it used and
>EXECUTE EXECUTE \ compile it
?DEFINIT
IF DEF-INIT
ELSE NO-INIT
THEN ; IMMEDIATE
' TARGET-INIT IS TARGET-INITIALIZE
ASSEMBLER DEFINITIONS FORTH >LIBRARY
\ ***************************************************************************
\ OPTIMIZERS !!
\ ***************************************************************************
\ Optimizer for the ! (store) MACRO. Looks for the following instruction
\ sequence:
\ DEC SI
\ DEC SI
\ MOV 0 [SI], BX
\ MOV BX, # xxxx
\ LODSW
\ MOV 0 [BX], AX
\
\ When these instructions are found preceeding a store instruction, they
\ are changed to:
\ MOV AX, BX
\ MOV xxxx ax
\
\ This provides a substantial savings in both space and time.
FORTH >FORTH
: STORE_OPT ( -- ) \ The ! MACRO
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 7 - @-T $4E4E = \ DEC SI DEC SI
HERE-T 5 - @-T $1C89 = AND \ MOV 0 [SI], BX
HERE-T 3 - C@-T $BB = AND \ MOV BX, # xxxx
OPT_LIMIT HERE-T 7 - U< AND
IF HERE-T 2- @-T \ get the address xxxx
-7 ALLOT-T \ if it matches, discard
\ previously compiled 7 bytes
LIHERE =: LINESTRT
[ASSEMBLER]
MOV ( xxxx ) BX A; \ uses xxxx from above
[FORTH]
ELSE \ cant optimize, so
[ASSEMBLER] \ just compile the
LODSW A; \ original code
MOV 0 [BX], AX A;
[FORTH]
THEN
ELSE ?REOPT
[ASSEMBLER]
LODSW A;
MOV 0 [BX], AX A;
[FORTH]
THEN
[TARGET]
;
: CSTORE_OPT ( -- ) \ The C! MACRO
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 7 - @-T $4E4E = \ DEC SI DEC SI
HERE-T 5 - @-T $1C89 = AND \ MOV 0 [SI], BX
HERE-T 3 - C@-T $BB = AND \ MOV BX, # xxxx
OPT_LIMIT HERE-T 7 - U< AND
IF HERE-T 2- @-T \ get the address xxxx
-7 ALLOT-T \ if it matches, discard
\ previously compiled 7 bytes
LIHERE =: LINESTRT
[ASSEMBLER]
MOV ( xxxx ) BL A; \ uses xxxx from above
[FORTH]
ELSE \ cant optimize, so
[ASSEMBLER] \ just compile the
LODSW A; \ original code
MOV 0 [BX], AL A;
[FORTH]
THEN
ELSE ?REOPT
[ASSEMBLER]
LODSW A;
MOV 0 [BX], AL A;
[FORTH]
THEN
[TARGET]
;
\ ***************************************************************************
\ A second optimizer for the ! (store) MACRO. Looks for the following
\ instruction sequence:
\
\ DEC SI 3 cycles
\ DEC SI 3 cycles
\ MOV 0 [SI], BX \ save BX 14 cycles
\ MOV BX, # xxxx \ LIT xxxx 4 cycles
\ MOV yyyy BX \ memory yyyy store 9 cycles
\ LODSW \ load BX 12 cycles
\ MOV BX, AX 2 cycles
\
\ When these instructions are found preceeding a store instruction, they
\ are changed to:
\
\ MOV yyyy # xxxx WORD 10 cycles
\
\ This provides a savings of 8 bytes and 37 cycles per occurance.
: STORE_OPT2 ( -- ) \ double optimize store immediates
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 14 - @-T $4E4E = \ DEC SI DEC SI
HERE-T 12 - @-T $1C89 = AND \ MOV 0 [SI], BX
HERE-T 10 - C@-T $BB = AND \ MOV BX, # xxxx
HERE-T 7 - @-T $1E89 = AND \ MOV yyyy BX
OPT_LIMIT HERE-T 14 - U< AND
IF HERE-T 5 - @-T \ get the address yyyy
HERE-T 9 - @-T \ get the value xxxx
-14 ALLOT-T \ if it matches, discard
\ previously compiled 14 bytes
LIHERE =: LINESTRT
[ASSEMBLER]
MOV # WORD A; \ MOV yyyy # xxxx WORD
[FORTH]
THEN
THEN
[TARGET]
;
: STORE_OPT3 ( -- ) \ triple optimize store fetch combos
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 15 - @-T $4E4E = \ DEC SI DEC SI
HERE-T 13 - @-T $1C89 = AND \ MOV 0 [SI], BX
HERE-T 11 - @-T $1E8B = AND \ MOV BX, xxxx
HERE-T 7 - @-T $1E89 = AND \ MOV yyyy BX
OPT_LIMIT HERE-T 15 - U< AND
IF HERE-T 5 - @-T \ get the address yyyy
HERE-T 9 - @-T \ get the value xxxx
-15 ALLOT-T \ if it matches, discard
\ previously compiled 14 bytes
LIHERE =: LINESTRT
[ASSEMBLER]
MOV CX, ( xxxx) A;
MOV ( yyyy) CX A;
[FORTH]
THEN
THEN
[TARGET]
;
: IMM/ABS_OPT ( -- <xxxx> f1 ) \ Immediate optimize
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 7 - @-T $4E4E = \ DEC SI DEC SI
HERE-T 5 - @-T $1C89 = AND \ MOV 0 [SI], BX
HERE-T 3 - C@-T $BB = AND \ MOV BX, # xxxx
OPT_LIMIT HERE-T 7 - U< AND
IF HERE-T 2 - @-T \ get the address xxxx
-7 ALLOT-T \ if it matches, discard
\ previously compiled 7 bytes
LIHERE =: LINESTRT \ and return value for BX
\ on stack with TRUE
-1 \ return -1 for immediate
ELSE
HERE-T 8 - @-T $4E4E = \ DEC SI DEC SI
HERE-T 6 - @-T $1C89 = AND \ MOV 0 [SI], BX
HERE-T 4 - @-T $1E8B = AND \ MOV BX, xxxx
IF HERE-T 2 - @-T \ get the address xxxx
-8 ALLOT-T \ if it matches, discard
\ 8 bytes
LIHERE =: LINESTRT \ return value for BX
1 \ return 1 for absolute
ELSE 0 \ else return 0
THEN
THEN
ELSE 0
THEN
[TARGET]
;
: IMM_BEFORE ( -- <xxxx> f1 ) \ Immediate optimize
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 3 - C@-T $BB = \ MOV BX, # xxxx
HERE-T 3 - IMM-HERE @ = AND \ matches our info
OPT_LIMIT HERE-T 3 - U< AND
IF HERE-T 2 - @-T \ get the address xxxx
-3 ALLOT-T \ if it matches, discard
\ previously compiled 3 bytes
LIHERE =: LINESTRT \ and return value for BX
\ on stack with TRUE
TRUE
ELSE FALSE
THEN
ELSE FALSE
THEN
[TARGET]
;
>LIBRARY
\ ***************************************************************************
\ Optimizer for the @ (fetch) MACRO. Looks for this instruction sequence
\ to preceed it:
\ MOV BX, # xxxx
\
\ When these instructions are found preceeding a store instruction, they
\ are changed to:
\ MOV bx, xxxx
\
\ This provides a savings in both space and time.
FORTH >FORTH
: AT_OPT ( -- ) \ The @ MACRO
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 3 - C@-T $BB = \ MOV BX, # xxxx
OPT_LIMIT HERE-T 3 - U< AND
IF HERE-T 2- @-T \ get the address xxxx
-3 ALLOT-T \ if it matches, discard
\ previously compiled 3 bytes
LIHERE =: LINESTRT
[ASSEMBLER]
MOV BX, ( xxxx ) A; \ uses xxxx from above
[FORTH]
ELSE \ cant optimize, so
[ASSEMBLER] \ just compile the
MOV BX, 0 [BX] A;
[FORTH]
THEN
ELSE ?REOPT
[ASSEMBLER]
MOV BX, 0 [BX] A;
[FORTH]
THEN
[TARGET]
;
: CAT_OPT ( -- ) \ The @ MACRO
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 3 - C@-T $BB = \ MOV BX, # xxxx
OPT_LIMIT HERE-T 3 - U< AND
IF HERE-T 2- @-T \ get the address xxxx
-3 ALLOT-T \ if it matches, discard
\ previously compiled 3 bytes
LIHERE =: LINESTRT
[ASSEMBLER]
MOV BL, ( xxxx ) A; \ uses xxxx from above
[FORTH]
ELSE \ cant optimize, so
[ASSEMBLER] \ just compile the
MOV BL, 0 [BX] A;
[FORTH]
THEN
ELSE ?REOPT
[ASSEMBLER]
MOV BL, 0 [BX] A;
[FORTH]
THEN
[TARGET]
;
>LIBRARY
\ ***************************************************************************
\ MACRO to move BX to the stack
\ ***************************************************************************
FORTH >FORTH
: SAVE_BX ( -- ) \ macro to SAVE BX
A; [FORTH]
?OPT \ Are we optimizing?
IF \ instructions before ?
HERE-T 3 - C@-T $AD = \ LODSW
HERE-T 2 - @-T $D88B = AND \ MOV BX, AX
OPT_LIMIT HERE-T 3 - U< AND
IF -3 ALLOT-T \ if it matches, discard
\ previously compiled 3 bytes
LIHERE =: LINESTRT
\ discards any previously compiled
\ LODSW and MOV BX, AX pair
\ of instructions, since we were
\ about to push BX back on the
\ stack anyway
[FORTH]
ELSE \ Instruction before ?
[ASSEMBLER] \ just compile the
DEC SI A;
DEC SI A;
MOV 0 [SI], BX A;
[FORTH]
THEN
ELSE ?REOPT
[ASSEMBLER]
DEC SI A;
DEC SI A;
MOV 0 [SI], BX A;
[FORTH]
THEN
[TARGET]
;
: LOAD_BX ( -- ) \ macro to LOAD BX, not an optimizer
A;
[ASSEMBLER]
LODSW A;
MOV BX, AX A;
[TARGET]
;
>LIBRARY