16.6 C Statements for Assembler Output

Often a single fixed template string cannot produce correct and efficient
assembler code for all the cases that are recognized by a single
instruction pattern. For example, the opcodes may depend on the kinds of
operands; or some unfortunate combinations of operands may require extra
machine instructions.

If the output control string starts with a ‘@’, then it is actually
a series of templates, each on a separate line. (Blank lines and
leading spaces and tabs are ignored.) The templates correspond to the
pattern's constraint alternatives (see Multi-Alternative). For example,
if a target machine has a two-address add instruction ‘addr’ to add
into a register and another ‘addm’ to add a register to memory, you
might write this pattern:

If the output control string starts with a ‘*’, then it is not an
output template but rather a piece of C program that should compute a
template. It should execute a return statement to return the
template-string you want. Most such templates use C string literals, which
require doublequote characters to delimit them. To include these
doublequote characters in the string, prefix each one with ‘\’.

If the output control string is written as a brace block instead of a
double-quoted string, it is automatically assumed to be C code. In that
case, it is not necessary to put in a leading asterisk, or to escape the
doublequotes surrounding C string literals.

The operands may be found in the array operands, whose C data type
is rtx [].

It is very common to select different ways of generating assembler code
based on whether an immediate operand is within a certain range. Be
careful when doing this, because the result of INTVAL is an
integer on the host machine. If the host machine has more bits in an
int than the target machine has in the mode in which the constant
will be used, then some of the bits you get from INTVAL will be
superfluous. For proper results, you must carefully disregard the
values of those bits.

It is possible to output an assembler instruction and then go on to output
or compute more of them, using the subroutine output_asm_insn. This
receives two arguments: a template-string and a vector of operands. The
vector may be operands, or it may be another array of rtx
that you declare locally and initialize yourself.

When an insn pattern has multiple alternatives in its constraints, often
the appearance of the assembler code is determined mostly by which alternative
was matched. When this is so, the C code can test the variable
which_alternative, which is the ordinal number of the alternative
that was actually satisfied (0 for the first, 1 for the second alternative,
etc.).

For example, suppose there are two opcodes for storing zero, ‘clrreg’
for registers and ‘clrmem’ for memory locations. Here is how
a pattern could use which_alternative to choose between them: