In the GAMA, new assembler instructions for an arbitrary abstract machine are defined with definstr. definstr expects a COMMON LISP argument list, a type specification for these arguments, and the COMMON LISP code defining the instruction.
The following example shows the definition of the GWAM instruction
(definstr put_constant (C Ai) (CONST NAT) :standard (gwam.put_constant (set-argument-reg Ai (constant C))))
gwam.put_constant is the name of the COMMON LISP function corresponding to the put_constant instruction. The keyword :standard declares put_constant to be a simple instruction. The next example shows a non-standard instruction for which more than one COMMON LISP definition is needed:
(definstr call (proc k) (LABEL NAT) :static (gwam.call/st (set-reg CP (reg P)) (set-reg CUTP (reg B)) (if (ref-lessp (reg B) (reg E)) (set-reg A (ref-plus (reg E) (offset Y) k))) (set-reg P proc)) :dynamic (gwam.call/dy (set-reg CP (reg P)) (set-reg CUTP (reg B)) (if (ref-lessp (reg B) (reg E)) (set-reg A (ref-plus (reg E) (offset Y) k))) (set-reg P (gmem.get proc))))
All instructions expecting a label can be used in two different ways: statically and dynamically. In the dynamic version, the address corresponding to the label is an entry in a jump table: an additional gmem.get is needed to dereference it. The static version does not use a jump table entry but directly uses the real address: dereferencing is not needed. It is used for procedures which will not be changed (like those in the prelude).