HANDBOOK / GENTLE PRIMER / Optimal Rule Selection /

# Using Output Parameters

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)
          $ 14

Here, 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`.