In the above example, we used predicates such as PLUS to write the generated code to the target file. It can also be returned as an output parameter of the predicate.
In many specifications, both methods are used. For example, an invocation
Register(X -> R)emits code for the term X such that the result is stored in a register. The output parameter R states which register is used.
Often, these output parameters are then used to construct a more complex result in the rule heading. This result can specify a computation for which no instructions have to be emitted, but which can be performed ``via an addressing mode''.
By way of an example, consider a rule from a code-generator specification for the MC68020:
'rule' EffectiveAddress ( addrplus(Array, intmult(Index, intconst(Size))) -> ax(AR, 0, DR, Size) ) : IsSuitableScaleFactor (Size) AddressRegister (Array -> AR) DataRegister (Index -> DR) $ 14Here, the choice predicates EffectiveAddress, AddressRegister, and DataRegister translate their input argument such that the result is given as an ``effective address'', an address register, or a data register. The rule states that the term
addrplus(Array, intmult(Index, intconst(Size)))(which is the translation of an array subscription) may be mapped to
ax(AR, 0, DR, Size)(the ``address register with index'' addressing mode) when the value of Array is computed in AR and the value of Index is computed in DR. To be a suitable operand for the ax mode, Size must fulfill the condition IsSuitableScaleFactor.