Compiler Magic: What Happens To Your Source Code ?

Mecrisp-Across is compiling interactively with constant folding and inlining into an intermediate format with a lot of fields and flags and bits that help with crosscompilation. There is a “threaded inner interpreter” which allows to run this intermediate format for testing.

The vector definitions do a recursive scan and increment usage counters of definitions which can be reached, allowing the ones that are not reachable from the vectors to be left out. The crosscompiler finally checks for definitions that are used one time only, and inserts them inline. After that, constant folding leading to additional possibilities for dead code elimination and register allocation of both stacks get to work. The most complicated piece is control flow joints with two different register sets from two different branches of execution.

What does Mecrip-Across do to make your source code work ?

To enable the user code run properly on the Target, Mecrisp-Across does some compiler pre and post target code additions

“NOTHING” Example Source Code

new
+jtag
target

: NOTHING ;

host
$FFFE vector NOTHING crosscompile t-listing disimage
t-listing

“NOTHING” Example Compiler Output

\ This shows the compiler init and exit code  ok.
 ok.
new  ok.
+jtag Chip erkannt: 2452  ok.
target
ok.
: NOTHING ; ok.
 ok.
host
$FFFE vector NOTHING crosscompile t-listing disimage
*** exit status: 0 ***

Speicherbedarf Flash ohne Vektortabelle 16 Bytes.
Speicherbedarf RAM ohne Stacks 0 Bytes.
Zahl der benötigten Pässe: 1


: NOTHING
00008AEC : F80E : ;

: irq-$FFFE
00008B38 : F80E : NOTHING
00008B44 : F80E : ;


F800: 40B2  mov.w #5A80h, &120h
F802: 5A80
F804: 0120
F806: 4031  mov.w #280h, r1
F808: 0280
F80A: 4034  mov.w #260h, r4
F80C: 0260
F80E: 3FFF  jmp F80E

Speicherbedarf Flash ohne Vektortabelle 16 Bytes.
Speicherbedarf RAM ohne Stacks 0 Bytes.
 ok.

Pre User Code Additions: Default Initialisation Sequence

A default initialisation sequence is inserted by the compiler. All compilers insert a init sequence at the start of the executable like this, and come can be very complex, i.e. C compilers.

Stop watchdog, set both stack pointers into RAM

F800: 40B2  mov.w #5A80h, &120h
F802: 5A80
F804: 0120
F806: 4031  mov.w #280h, r1
F808: 0280
F80A: 4034  mov.w #260h, r4
F80C: 0260

Your Compiled Forth Source Code Goes Here

After the following cross-compiler operations have turned it into target machine code:

* Constant folding
* Register allocation for both data and return stack
* Dead code elimination (imagine a constant feed into case)
* Register allocation across control structures
* Determination which definitions are in use,just as Freepascals Smartlinking (fpc -XX)
* Automatic inlining of definitions used one time only
* Interrupt handler framing depending on register usage
@ ----------------------------------------------------------------------------- @**

Nothing here as this example has no Forth Code to compile!

@ ----------------------------------------------------------------------------- @**

Post User Code Addition: User Code Vector

To your compiled Forth source code

F80E: 3FFF  jmp F80E