Assembler templates
Monday, May 1, 2006
I’ve finished updating the PowerPC and x86 backends for the new compiler design, and new boot images are up. AMD64 will have to wait a few days.
If you study the compiler source, you will find many calls to the words
with-template
and define-intrinsic
; the former is called during code
generation time to load inputs from the stack to registers, and store
registers back to the stack. The latter associates a word with a
compiler intrinsic quotation which passes the specified arguments to
with-template
.
Here is a typical definition:
: generate-fixnum-mod
#! PowerPC doesn't have a MOD instruction; so we compute
#! x-(x/y)*y. Puts the result in "s" operand.
"s" operand "r" operand "y" operand MULLW
"s" operand "s" operand "x" operand SUBF ;
\ fixnum-mod [
! divide x by y, store result in x
"r" operand "x" operand "y" operand DIVW
generate-fixnum-mod
] H{
{ +input { { f "x" } { f "y" } } }
{ +scratch { { f "r" } { f "s" } } }
{ +output { "s" } }
} define-intrinsic
This looks like a macro assembler; the operands “x”, “y”, “r” and “s”
are assigned at compile time, and used to generate an assembly segment
involving various instructions, such as MULLW
and SUBF
.
The complete list of specifiers which can be passed as keys in the hashtable there is as follows:
+input
- an array of pairs, where each pair is of the form{ vreg string }
; the string is an operand name, and the vreg is either an integer or f (meaning any free register can be assigned). Thewith-template
form compiles code to load objects from the stack into the input registers+scratch
- this specifier is of the same format as+input
, except here the registers are untouched. The body of the template can use them for any purpose, including outputs.+output
- a list of previously-assigned operand names holding values which should be moved to the stack. Registers allocated by+input
and+scratch
can be listed here.+scratch
- a list of previously-assigned operand names whose contents should not be assumed to have remained constant after the template finishes executing. Usually a template does not modify its inputs; however if it does, they must be listed here to avoid miscompiling code.
I’m going to implement a few assorted cleanups and optimizations now, and then move on to floating point intrinsics, which should provide a nice performance boost.