|
|
@@ -0,0 +1,73 @@ |
|
|
|
# Cross-compilation |
|
|
|
|
|
|
|
When Forth words are compiled, they are compiled for the system |
|
|
|
currently running. Those compiled words are tricky to relocate |
|
|
|
because their wordrefs reference offsets within the running |
|
|
|
system. |
|
|
|
|
|
|
|
If you want to deploy to a new system, you need tricks, and |
|
|
|
those tricks are located at B260, the cross-compilation toolset. |
|
|
|
|
|
|
|
The mechanism is simple: override ":" so that it adds an offset |
|
|
|
to every wordrefs it compiles. |
|
|
|
|
|
|
|
What should that offset be? the beginning of the binary being |
|
|
|
built. That offset if the value in the ORG variable, supplied |
|
|
|
by the assembler. It's logical: every binary begins with a bit |
|
|
|
of assembler, which makes every following Forth word aligned |
|
|
|
with this value. |
|
|
|
|
|
|
|
# Dual-CURRENT |
|
|
|
|
|
|
|
Although the principle behind cross-compilation is simple, the |
|
|
|
devil's in the details. While building our new binary, we still |
|
|
|
need access to a full-fledged Forth interpreter. To allow this, |
|
|
|
we'll maintain two CURRENT: the regular one and XCURRENT, the |
|
|
|
CURRENT value of the cross-compiled binary. |
|
|
|
|
|
|
|
XCURRENT's value is a *host* address, not a cross one. For |
|
|
|
example, if our cross binary begins at offset 0x1000 and the |
|
|
|
last word added to it was at offset 0x234, then XCURRENT is |
|
|
|
0x1234. |
|
|
|
|
|
|
|
During cross compilation, we constantly switch CURRENT (through |
|
|
|
the CURRENT* sysvar, see impl.txt) between the host's and |
|
|
|
XCURRENT. |
|
|
|
|
|
|
|
As a general rule, switching happens this way: When interpret- |
|
|
|
ing, we're in host mode. When compiling, we're in XCURRENT mode. |
|
|
|
|
|
|
|
When we encounter an IMMEDIATE during compilation, we execute |
|
|
|
the *host* version of that word. The reason for this is simple: |
|
|
|
any word freshly cross-compiled is utterly un-runable because |
|
|
|
its wordrefs are misaligned under the current host. |
|
|
|
|
|
|
|
# xcomp unit |
|
|
|
|
|
|
|
Cross-compilation is achieved through the writing of a cross- |
|
|
|
compilation unit of code, xcomp unit for short. |
|
|
|
|
|
|
|
The xcomp toolset at B260 alters core words in a deep way, so |
|
|
|
ordering is important. First, we load our tools. Assembler, |
|
|
|
xcomp toolset, etc. The xcomp toolset is designed to not over- |
|
|
|
shadow core words directly, so initial loading, B262, is harm- |
|
|
|
less. |
|
|
|
|
|
|
|
Now is also the time to define some support words that will not |
|
|
|
be part of our resulting binary, but will be used during xcomp, |
|
|
|
for example, declarations units and macros. |
|
|
|
|
|
|
|
Then, we load B270 to apply xcomp overrides. From this point on. |
|
|
|
every defining word is messed up and will produce offsetted |
|
|
|
binaries. |
|
|
|
|
|
|
|
At this point, it's critical to set ORG before spitting any- |
|
|
|
thing. Boot binaries will usually take care of this, so you |
|
|
|
don't have to do it yourself. You just have to make sure that |
|
|
|
you load the boot binary right after loading B270. |
|
|
|
|
|
|
|
Then, you spit your content following instructions in |
|
|
|
bootstrap.txt. |
|
|
|
|
|
|
|
After you're done, you can run EMPTY to go back to a usable |
|
|
|
system. |