version 1.214, 2010/03/08 11:23:22
|
version 1.215, 2010/04/10 14:36:34
|
Line 12572 machine code), and for defining the mach
|
Line 12572 machine code), and for defining the mach
|
@code{DOES>}-based defining words. However, the machine-independent |
@code{DOES>}-based defining words. However, the machine-independent |
nature of Gforth poses a few problems: First of all, Gforth runs on |
nature of Gforth poses a few problems: First of all, Gforth runs on |
several architectures, so it can provide no standard assembler. What's |
several architectures, so it can provide no standard assembler. What's |
worse is that the register allocation not only depends on the processor, |
worse is that the register allocation not only depends on the |
but also on the @code{gcc} version and options used. |
processor, but also on the @code{gcc} version and options used (still |
|
this problem can be worked around by using @code{ABI-CODE}). |
|
|
The words that Gforth offers encapsulate some system dependences (e.g., |
The words that Gforth offers encapsulate some system dependences (e.g., |
the header structure), so a system-independent assembler may be used in |
the header structure), so a system-independent assembler may be used in |
Line 12587 portable anyway.}.
|
Line 12588 portable anyway.}.
|
doc-assembler |
doc-assembler |
doc-init-asm |
doc-init-asm |
doc-code |
doc-code |
|
doc-abi-code |
doc-end-code |
doc-end-code |
doc-;code |
doc-;code |
doc-flush-icache |
doc-flush-icache |
Line 12628 or different installations; so for doing
|
Line 12630 or different installations; so for doing
|
jumping to @code{' noop >code-address}, which contains nothing but a |
jumping to @code{' noop >code-address}, which contains nothing but a |
@code{NEXT}. |
@code{NEXT}. |
|
|
|
@cindex code words, using platform's ABI |
|
If you do not want to bother with the complexities of the |
|
interpreter's registers, you may use @code{ABI-CODE} for defining |
|
native code instead. @code{ABI-CODE} definitions are called with the |
|
C-Language's application binary interface (ABI) conventions of the |
|
platform, passing the Forth virtual machine's SP and FP as arguments, |
|
While this approach involves some (minor) overhead, it allows you to |
|
write code that is portable across different versions of GForth. |
|
|
For general accesses to the inner interpreter's registers, the easiest |
For general accesses to the inner interpreter's registers, the easiest |
solution is to use explicit register declarations (@pxref{Explicit Reg |
solution is to use explicit register declarations (@pxref{Explicit Reg |
Vars, , Variables in Specified Registers, gcc.info, GNU C Manual}) for |
Vars, , Variables in Specified Registers, gcc.info, GNU C Manual}) for |
Line 12691 conditions are specified in a way specif
|
Line 12702 conditions are specified in a way specif
|
|
|
Note that the register assignments of the Gforth engine can change |
Note that the register assignments of the Gforth engine can change |
between Gforth versions, or even between different compilations of the |
between Gforth versions, or even between different compilations of the |
same Gforth version (e.g., if you use a different GCC version). So if |
same Gforth version (e.g., if you use a different GCC version). If |
you want to refer to Gforth's registers (e.g., the stack pointer or |
you are using @code{CODE} instead of @code{ABI-CODE}, and you want to |
TOS), I recommend defining your own words for refering to these |
refer to Gforth's registers (e.g., the stack pointer or TOS), I |
registers, and using them later on; then you can easily adapt to a |
recommend defining your own words for refering to these registers, and |
changed register assignment. The stability of the register assignment |
using them later on; then you can easily adapt to a changed register |
is usually better if you build Gforth with @code{--enable-force-reg}. |
assignment. The stability of the register assignment is usually |
|
better if you build Gforth with @code{--enable-force-reg}. |
|
|
The most common use of these registers is to dispatch to the next word |
The most common use of these registers is to dispatch to the next word |
(the @code{next} routine). A portable way to do this is to jump to |
(the @code{next} routine). A portable way to do this is to jump to |
@code{' noop >code-address} (of course, this is less efficient than |
@code{' noop >code-address} (of course, this is less efficient than |
integrating the @code{next} code and scheduling it well). |
integrating the @code{next} code and scheduling it well). When using |
|
@code{ABI-CODE}, you can just assemble a normal subroutine return (but |
|
make sure you return SP and FP back to the caller). |
|
|
Another difference between Gforth version is that the top of stack is |
Another difference between Gforth version is that the top of stack is |
kept in memory in @code{gforth} and, on most platforms, in a register in |
kept in memory in @code{gforth} and, on most platforms, in a register |
@code{gforth-fast}. |
in @code{gforth-fast}. For @code{ABI-CODE} definitions, any stack |
|
caching registers are guaranteed to be flushed to the stack, allowing |
|
you to reliably access the top of stack as @code{sp[0]}. |
|
|
@node Common Disassembler, 386 Assembler, Common Assembler, Assembler and Code Words |
@node Common Disassembler, 386 Assembler, Common Assembler, Assembler and Code Words |
@subsection Common Disassembler |
@subsection Common Disassembler |
Line 12960 branches).
|
Line 12976 branches).
|
@node ARM Assembler, Other assemblers, PowerPC assembler, Assembler and Code Words |
@node ARM Assembler, Other assemblers, PowerPC assembler, Assembler and Code Words |
@subsection ARM Assembler |
@subsection ARM Assembler |
|
|
The ARM assembler included in Gforth was written from scratch by David |
The ARM assembler includes all instruction of ARM architecture version |
Kuehling. |
4, and the BLX instruction from architecture 5. It does not (yet) |
|
have support for Thumb instructions. It also lacks support for any |
The assembler includes all instruction of ARM architecture version 4, |
co-processors. |
but does not (yet) have support for Thumb instructions. It also lacks |
|
support for any co-processors. |
The assembler uses a postfix syntax with the same operand order as |
|
used in the ARM Architecture Reference Manual. Mnemonics are suffixed |
The assembler uses a postfix syntax with the target operand specified |
by a comma. |
last. For load/store instructions the last operand will be the |
|
register(s) to be loaded from/stored to. |
|
|
|
Registers are specified by their names @code{r0} through @code{r15}, |
Registers are specified by their names @code{r0} through @code{r15}, |
with the aliases @code{pc}, @code{lr}, @code{sp}, @code{ip} and |
with the aliases @code{pc}, @code{lr}, @code{sp}, @code{ip} and |
@code{fp} provided for convenience. Note that @code{ip} means intra |
@code{fp} provided for convenience. Note that @code{ip} refers to |
procedure call scratch register (@code{r12}) and does not refer to the |
the``intra procedure call scratch register'' (@code{r12}) and does not |
instruction pointer. |
refer to an instruction pointer. @code{sp} refers to the ARM ABI |
|
stack pointer (@code{r13}) and not the Forth stack pointer. |
|
|
Condition codes can be specified anywhere in the instruction, but will |
Condition codes can be specified anywhere in the instruction, but will |
be most readable if specified just in front of the mnemonic. The 'S' |
be most readable if specified just in front of the mnemonic. The 'S' |
Line 13023 r4 r1 2 #LSL ]- [r4], -r1, LSL #2
|
Line 13038 r4 r1 2 #LSL ]- [r4], -r1, LSL #2
|
@end example |
@end example |
|
|
Register lists for load/store multiple instructions are started and |
Register lists for load/store multiple instructions are started and |
terminated by using the words @code{@{} and @code{@}} |
terminated by using the words @code{@{} and @code{@}} respectivly. |
respectivly. Between braces, register names can be listed one by one, |
Between braces, register names can be listed one by one or register |
or register ranges can be formed by using the postfix operator |
ranges can be formed by using the postfix operator @code{r-r}. The |
@code{r-r}. The @code{^} flag is not encoded in the register list |
@code{^} flag is not encoded in the register list operand, but instead |
operand, but instead directly encoded into the instruction mnemonic, |
directly encoded into the instruction mnemonic, ie. use @code{^ldm,} |
ie. use @code{^ldm,} and @code{^stm,}. |
and @code{^stm,}. |
|
|
Addressing modes for load/store multiple are not encoded as |
Addressing modes for load/store multiple are not encoded as |
instruction suffixes, but instead specified after the register that |
instruction suffixes, but instead specified after the register that |
Line 13039 The following table gives some examples:
|
Line 13054 The following table gives some examples:
|
|
|
@example |
@example |
Gforth normal assembler |
Gforth normal assembler |
@{ r0 r7 r8 @} r4 ia stm, stmia @{r0,r7,r8@}, r4 |
r4 @{ r0 r7 r8 @} ia stm, stmia r4, @{r0,r7,r8@} |
@{ r0 r7 r8 @} r4 db! ldm, ldmdb @{r0,r7,r8@}, r4! |
r4 @{ r0 r7 r8 @} db! ldm, ldmdb r4!, @{r0,r7,r8@} |
@{ r0 r15 r-r @} sp ia! ^ldm, ldmfd @{r0-r15@}^, sp! |
sp @{ r0 r15 r-r @} ia! ^ldm, ldmfd sp!, @{r0-r15@}^ |
@end example |
@end example |
|
|
Conditions for control structure words are specified in front of a |
Control structure words typical for Forth assemblers are available: |
word: |
@code{if,} @code{ahead,} @code{then,} @code{else,} @code{begin,} |
|
@code{until,} @code{again,} @code{while,} @code{repeat,} |
|
@code{repeat-until,}. Conditions are specified in front of these words: |
|
|
@example |
@example |
r1 r2 cmp, \ compare r1 and r2 |
r1 r2 cmp, \ compare r1 and r2 |
Line 13054 eq if, \ equal?
|
Line 13071 eq if, \ equal?
|
then, |
then, |
@end example |
@end example |
|
|
Here is an example of a @code{code} word (assumes that the stack |
Example of a definition using the ARM assembler: |
pointer is in @code{r9}, and that @code{r2} and @code{r3} can be |
|
clobbered): |
|
|
|
@example |
@example |
code my+ ( n1 n2 -- n3 ) |
abi-code my+ ( n1 n2 -- n3 ) |
r9 IA! @{ r2 r3 @} ldm, \ pop r2 = n2, r3 = n1 |
\ arm abi: r0=sp, r1=fp, r2, r3 saved by caller |
r2 r3 r3 add, \ r3 = n2+n1 |
r0 @{ r2 r3 @} IA! ldm, \ pop r2 = n2, r3 = n1 |
r9 -4 #]! r3 str, \ push r3 |
r3 r2 r3 add, \ r3 = n2+n1 |
next, |
r3 r0 -4 #]! str, \ push r3 |
|
pc lr mov, \ return (r0=sp, r1=fp) to caller |
end-code |
end-code |
@end example |
@end example |
|
|
Look at @file{arch/arm/asm-example.fs} for more examples. |
|
|
|
@node Other assemblers, , ARM Assembler, Assembler and Code Words |
@node Other assemblers, , ARM Assembler, Assembler and Code Words |
@subsection Other assemblers |
@subsection Other assemblers |
|
|