This is Info file gcc.info, produced by Makeinfo version 1.68 from the
input file gcc.texi.

   This file documents the use and the internals of the GNU compiler.

   Published by the Free Software Foundation 59 Temple Place - Suite 330
Boston, MA 02111-1307 USA

   Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
Free Software Foundation, Inc.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the sections entitled "GNU General Public License," "Funding for
Free Software," and "Protect Your Freedom--Fight `Look And Feel'" are
included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that the sections entitled "GNU General Public
License," "Funding for Free Software," and "Protect Your Freedom--Fight
`Look And Feel'", and this permission notice, may be included in
translations approved by the Free Software Foundation instead of in the
original English.


File: gcc.info,  Node: Peephole Definitions,  Next: Expander Definitions,  Prev: Insn Canonicalizations,  Up: Machine Desc

Machine-Specific Peephole Optimizers
====================================

   In addition to instruction patterns the `md' file may contain
definitions of machine-specific peephole optimizations.

   The combiner does not notice certain peephole optimizations when the
data flow in the program does not suggest that it should try them.  For
example, sometimes two consecutive insns related in purpose can be
combined even though the second one does not appear to use a register
computed in the first one.  A machine-specific peephole optimizer can
detect such opportunities.

   A definition looks like this:

     (define_peephole
       [INSN-PATTERN-1
        INSN-PATTERN-2
        ...]
       "CONDITION"
       "TEMPLATE"
       "OPTIONAL INSN-ATTRIBUTES")

The last string operand may be omitted if you are not using any
machine-specific information in this machine description.  If present,
it must obey the same rules as in a `define_insn'.

   In this skeleton, INSN-PATTERN-1 and so on are patterns to match
consecutive insns.  The optimization applies to a sequence of insns when
INSN-PATTERN-1 matches the first one, INSN-PATTERN-2 matches the next,
and so on.

   Each of the insns matched by a peephole must also match a
`define_insn'.  Peepholes are checked only at the last stage just
before code generation, and only optionally.  Therefore, any insn which
would match a peephole but no `define_insn' will cause a crash in code
generation in an unoptimized compilation, or at various optimization
stages.

   The operands of the insns are matched with `match_operands',
`match_operator', and `match_dup', as usual.  What is not usual is that
the operand numbers apply to all the insn patterns in the definition.
So, you can check for identical operands in two insns by using
`match_operand' in one insn and `match_dup' in the other.

   The operand constraints used in `match_operand' patterns do not have
any direct effect on the applicability of the peephole, but they will
be validated afterward, so make sure your constraints are general enough
to apply whenever the peephole matches.  If the peephole matches but
the constraints are not satisfied, the compiler will crash.

   It is safe to omit constraints in all the operands of the peephole;
or you can write constraints which serve as a double-check on the
criteria previously tested.

   Once a sequence of insns matches the patterns, the CONDITION is
checked.  This is a C expression which makes the final decision whether
to perform the optimization (we do so if the expression is nonzero).  If
CONDITION is omitted (in other words, the string is empty) then the
optimization is applied to every sequence of insns that matches the
patterns.

   The defined peephole optimizations are applied after register
allocation is complete.  Therefore, the peephole definition can check
which operands have ended up in which kinds of registers, just by
looking at the operands.

   The way to refer to the operands in CONDITION is to write
`operands[I]' for operand number I (as matched by `(match_operand I
...)').  Use the variable `insn' to refer to the last of the insns
being matched; use `prev_active_insn' to find the preceding insns.

   When optimizing computations with intermediate results, you can use
CONDITION to match only when the intermediate results are not used
elsewhere.  Use the C expression `dead_or_set_p (INSN, OP)', where INSN
is the insn in which you expect the value to be used for the last time
(from the value of `insn', together with use of `prev_nonnote_insn'),
and OP is the intermediate value (from `operands[I]').

   Applying the optimization means replacing the sequence of insns with
one new insn.  The TEMPLATE controls ultimate output of assembler code
for this combined insn.  It works exactly like the template of a
`define_insn'.  Operand numbers in this template are the same ones used
in matching the original sequence of insns.

   The result of a defined peephole optimizer does not need to match
any of the insn patterns in the machine description; it does not even
have an opportunity to match them.  The peephole optimizer definition
itself serves as the insn pattern to control how the insn is output.

   Defined peephole optimizers are run as assembler code is being
output, so the insns they produce are never combined or rearranged in
any way.

   Here is an example, taken from the 68000 machine description:

     (define_peephole
       [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
        (set (match_operand:DF 0 "register_operand" "=f")
             (match_operand:DF 1 "register_operand" "ad"))]
       "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
       "*
     {
       rtx xoperands[2];
       xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
     #ifdef MOTOROLA
       output_asm_insn (\"move.l %1,(sp)\", xoperands);
       output_asm_insn (\"move.l %1,-(sp)\", operands);
       return \"fmove.d (sp)+,%0\";
     #else
       output_asm_insn (\"movel %1,sp@\", xoperands);
       output_asm_insn (\"movel %1,sp@-\", operands);
       return \"fmoved sp@+,%0\";
     #endif
     }
     ")

   The effect of this optimization is to change

     jbsr _foobar
     addql #4,sp
     movel d1,sp@-
     movel d0,sp@-
     fmoved sp@+,fp0

into

     jbsr _foobar
     movel d1,sp@
     movel d0,sp@-
     fmoved sp@+,fp0

   INSN-PATTERN-1 and so on look *almost* like the second operand of
`define_insn'.  There is one important difference: the second operand
of `define_insn' consists of one or more RTX's enclosed in square
brackets.  Usually, there is only one: then the same action can be
written as an element of a `define_peephole'.  But when there are
multiple actions in a `define_insn', they are implicitly enclosed in a
`parallel'.  Then you must explicitly write the `parallel', and the
square brackets within it, in the `define_peephole'.  Thus, if an insn
pattern looks like this,

     (define_insn "divmodsi4"
       [(set (match_operand:SI 0 "general_operand" "=d")
             (div:SI (match_operand:SI 1 "general_operand" "0")
                     (match_operand:SI 2 "general_operand" "dmsK")))
        (set (match_operand:SI 3 "general_operand" "=d")
             (mod:SI (match_dup 1) (match_dup 2)))]
       "TARGET_68020"
       "divsl%.l %2,%3:%0")

then the way to mention this insn in a peephole is as follows:

     (define_peephole
       [...
        (parallel
         [(set (match_operand:SI 0 "general_operand" "=d")
               (div:SI (match_operand:SI 1 "general_operand" "0")
                       (match_operand:SI 2 "general_operand" "dmsK")))
          (set (match_operand:SI 3 "general_operand" "=d")
               (mod:SI (match_dup 1) (match_dup 2)))])
        ...]
       ...)


File: gcc.info,  Node: Expander Definitions,  Next: Insn Splitting,  Prev: Peephole Definitions,  Up: Machine Desc

Defining RTL Sequences for Code Generation
==========================================

   On some target machines, some standard pattern names for RTL
generation cannot be handled with single insn, but a sequence of RTL
insns can represent them.  For these target machines, you can write a
`define_expand' to specify how to generate the sequence of RTL.

   A `define_expand' is an RTL expression that looks almost like a
`define_insn'; but, unlike the latter, a `define_expand' is used only
for RTL generation and it can produce more than one RTL insn.

   A `define_expand' RTX has four operands:

   * The name.  Each `define_expand' must have a name, since the only
     use for it is to refer to it by name.

   * The RTL template.  This is just like the RTL template for a
     `define_peephole' in that it is a vector of RTL expressions each
     being one insn.

   * The condition, a string containing a C expression.  This
     expression is used to express how the availability of this pattern
     depends on subclasses of target machine, selected by command-line
     options when GNU CC is run.  This is just like the condition of a
     `define_insn' that has a standard name.  Therefore, the condition
     (if present) may not depend on the data in the insn being matched,
     but only the target-machine-type flags.  The compiler needs to
     test these conditions during initialization in order to learn
     exactly which named instructions are available in a particular run.

   * The preparation statements, a string containing zero or more C
     statements which are to be executed before RTL code is generated
     from the RTL template.

     Usually these statements prepare temporary registers for use as
     internal operands in the RTL template, but they can also generate
     RTL insns directly by calling routines such as `emit_insn', etc.
     Any such insns precede the ones that come from the RTL template.

   Every RTL insn emitted by a `define_expand' must match some
`define_insn' in the machine description.  Otherwise, the compiler will
crash when trying to generate code for the insn or trying to optimize
it.

   The RTL template, in addition to controlling generation of RTL insns,
also describes the operands that need to be specified when this pattern
is used.  In particular, it gives a predicate for each operand.

   A true operand, which needs to be specified in order to generate RTL
from the pattern, should be described with a `match_operand' in its
first occurrence in the RTL template.  This enters information on the
operand's predicate into the tables that record such things.  GNU CC
uses the information to preload the operand into a register if that is
required for valid RTL code.  If the operand is referred to more than
once, subsequent references should use `match_dup'.

   The RTL template may also refer to internal "operands" which are
temporary registers or labels used only within the sequence made by the
`define_expand'.  Internal operands are substituted into the RTL
template with `match_dup', never with `match_operand'.  The values of
the internal operands are not passed in as arguments by the compiler
when it requests use of this pattern.  Instead, they are computed
within the pattern, in the preparation statements.  These statements
compute the values and store them into the appropriate elements of
`operands' so that `match_dup' can find them.

   There are two special macros defined for use in the preparation
statements: `DONE' and `FAIL'.  Use them with a following semicolon, as
a statement.

`DONE'
     Use the `DONE' macro to end RTL generation for the pattern.  The
     only RTL insns resulting from the pattern on this occasion will be
     those already emitted by explicit calls to `emit_insn' within the
     preparation statements; the RTL template will not be generated.

`FAIL'
     Make the pattern fail on this occasion.  When a pattern fails, it
     means that the pattern was not truly available.  The calling
     routines in the compiler will try other strategies for code
     generation using other patterns.

     Failure is currently supported only for binary (addition,
     multiplication, shifting, etc.) and bitfield (`extv', `extzv', and
     `insv') operations.

   Here is an example, the definition of left-shift for the SPUR chip:

     (define_expand "ashlsi3"
       [(set (match_operand:SI 0 "register_operand" "")
             (ashift:SI

     (match_operand:SI 1 "register_operand" "")
               (match_operand:SI 2 "nonmemory_operand" "")))]
       ""
       "

     {
       if (GET_CODE (operands[2]) != CONST_INT
           || (unsigned) INTVAL (operands[2]) > 3)
         FAIL;
     }")

This example uses `define_expand' so that it can generate an RTL insn
for shifting when the shift-count is in the supported range of 0 to 3
but fail in other cases where machine insns aren't available.  When it
fails, the compiler tries another strategy using different patterns
(such as, a library call).

   If the compiler were able to handle nontrivial condition-strings in
patterns with names, then it would be possible to use a `define_insn'
in that case.  Here is another case (zero-extension on the 68000) which
makes more use of the power of `define_expand':

     (define_expand "zero_extendhisi2"
       [(set (match_operand:SI 0 "general_operand" "")
             (const_int 0))
        (set (strict_low_part
               (subreg:HI
                 (match_dup 0)
                 0))
             (match_operand:HI 1 "general_operand" ""))]
       ""
       "operands[1] = make_safe_from (operands[1], operands[0]);")

Here two RTL insns are generated, one to clear the entire output operand
and the other to copy the input operand into its low half.  This
sequence is incorrect if the input operand refers to [the old value of]
the output operand, so the preparation statement makes sure this isn't
so.  The function `make_safe_from' copies the `operands[1]' into a
temporary register if it refers to `operands[0]'.  It does this by
emitting another RTL insn.

   Finally, a third example shows the use of an internal operand.
Zero-extension on the SPUR chip is done by `and'-ing the result against
a halfword mask.  But this mask cannot be represented by a `const_int'
because the constant value is too large to be legitimate on this
machine.  So it must be copied into a register with `force_reg' and
then the register used in the `and'.

     (define_expand "zero_extendhisi2"
       [(set (match_operand:SI 0 "register_operand" "")
             (and:SI (subreg:SI
                       (match_operand:HI 1 "register_operand" "")
                       0)
                     (match_dup 2)))]
       ""
       "operands[2]
          = force_reg (SImode, gen_rtx (CONST_INT,
                                        VOIDmode, 65535)); ")

   *Note:* If the `define_expand' is used to serve a standard binary or
unary arithmetic operation or a bitfield operation, then the last insn
it generates must not be a `code_label', `barrier' or `note'.  It must
be an `insn', `jump_insn' or `call_insn'.  If you don't need a real insn
at the end, emit an insn to copy the result of the operation into
itself.  Such an insn will generate no code, but it can avoid problems
in the compiler.


File: gcc.info,  Node: Insn Splitting,  Next: Insn Attributes,  Prev: Expander Definitions,  Up: Machine Desc

Defining How to Split Instructions
==================================

   There are two cases where you should specify how to split a pattern
into multiple insns.  On machines that have instructions requiring delay
slots (*note Delay Slots::.) or that have instructions whose output is
not available for multiple cycles (*note Function Units::.), the
compiler phases that optimize these cases need to be able to move insns
into one-instruction delay slots.  However, some insns may generate
more than one machine instruction.  These insns cannot be placed into a
delay slot.

   Often you can rewrite the single insn as a list of individual insns,
each corresponding to one machine instruction.  The disadvantage of
doing so is that it will cause the compilation to be slower and require
more space.  If the resulting insns are too complex, it may also
suppress some optimizations.  The compiler splits the insn if there is a
reason to believe that it might improve instruction or delay slot
scheduling.

   The insn combiner phase also splits putative insns.  If three insns
are merged into one insn with a complex expression that cannot be
matched by some `define_insn' pattern, the combiner phase attempts to
split the complex pattern into two insns that are recognized.  Usually
it can break the complex pattern into two patterns by splitting out some
subexpression.  However, in some other cases, such as performing an
addition of a large constant in two insns on a RISC machine, the way to
split the addition into two insns is machine-dependent.

   The `define_split' definition tells the compiler how to split a
complex insn into several simpler insns.  It looks like this:

     (define_split
       [INSN-PATTERN]
       "CONDITION"
       [NEW-INSN-PATTERN-1
        NEW-INSN-PATTERN-2
        ...]
       "PREPARATION STATEMENTS")

   INSN-PATTERN is a pattern that needs to be split and CONDITION is
the final condition to be tested, as in a `define_insn'.  When an insn
matching INSN-PATTERN and satisfying CONDITION is found, it is replaced
in the insn list with the insns given by NEW-INSN-PATTERN-1,
NEW-INSN-PATTERN-2, etc.

   The PREPARATION STATEMENTS are similar to those statements that are
specified for `define_expand' (*note Expander Definitions::.)  and are
executed before the new RTL is generated to prepare for the generated
code or emit some insns whose pattern is not fixed.  Unlike those in
`define_expand', however, these statements must not generate any new
pseudo-registers.  Once reload has completed, they also must not
allocate any space in the stack frame.

   Patterns are matched against INSN-PATTERN in two different
circumstances.  If an insn needs to be split for delay slot scheduling
or insn scheduling, the insn is already known to be valid, which means
that it must have been matched by some `define_insn' and, if
`reload_completed' is non-zero, is known to satisfy the constraints of
that `define_insn'.  In that case, the new insn patterns must also be
insns that are matched by some `define_insn' and, if `reload_completed'
is non-zero, must also satisfy the constraints of those definitions.

   As an example of this usage of `define_split', consider the following
example from `a29k.md', which splits a `sign_extend' from `HImode' to
`SImode' into a pair of shift insns:

     (define_split
       [(set (match_operand:SI 0 "gen_reg_operand" "")
             (sign_extend:SI (match_operand:HI 1 "gen_reg_operand" "")))]
       ""
       [(set (match_dup 0)
             (ashift:SI (match_dup 1)
                        (const_int 16)))
        (set (match_dup 0)
             (ashiftrt:SI (match_dup 0)
                          (const_int 16)))]
       "
     { operands[1] = gen_lowpart (SImode, operands[1]); }")

   When the combiner phase tries to split an insn pattern, it is always
the case that the pattern is *not* matched by any `define_insn'.  The
combiner pass first tries to split a single `set' expression and then
the same `set' expression inside a `parallel', but followed by a
`clobber' of a pseudo-reg to use as a scratch register.  In these
cases, the combiner expects exactly two new insn patterns to be
generated.  It will verify that these patterns match some `define_insn'
definitions, so you need not do this test in the `define_split' (of
course, there is no point in writing a `define_split' that will never
produce insns that match).

   Here is an example of this use of `define_split', taken from
`rs6000.md':

     (define_split
       [(set (match_operand:SI 0 "gen_reg_operand" "")
             (plus:SI (match_operand:SI 1 "gen_reg_operand" "")
                      (match_operand:SI 2 "non_add_cint_operand" "")))]
       ""
       [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
        (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
     "
     {
       int low = INTVAL (operands[2]) & 0xffff;
       int high = (unsigned) INTVAL (operands[2]) >> 16;
     
       if (low & 0x8000)
         high++, low |= 0xffff0000;
     
       operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16);
       operands[4] = gen_rtx (CONST_INT, VOIDmode, low);
     }")

   Here the predicate `non_add_cint_operand' matches any `const_int'
that is *not* a valid operand of a single add insn.  The add with the
smaller displacement is written so that it can be substituted into the
address of a subsequent operation.

   An example that uses a scratch register, from the same file,
generates an equality comparison of a register and a large constant:

     (define_split
       [(set (match_operand:CC 0 "cc_reg_operand" "")
             (compare:CC (match_operand:SI 1 "gen_reg_operand" "")
                         (match_operand:SI 2 "non_short_cint_operand" "")))
        (clobber (match_operand:SI 3 "gen_reg_operand" ""))]
       "find_single_use (operands[0], insn, 0)
        && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
            || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
       [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
        (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
       "
     {
       /* Get the constant we are comparing against, C, and see what it
          looks like sign-extended to 16 bits.  Then see what constant
          could be XOR'ed with C to get the sign-extended value.  */
     
       int c = INTVAL (operands[2]);
       int sextc = (c << 16) >> 16;
       int xorv = c ^ sextc;
     
       operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
       operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
     }")

   To avoid confusion, don't write a single `define_split' that accepts
some insns that match some `define_insn' as well as some insns that
don't.  Instead, write two separate `define_split' definitions, one for
the insns that are valid and one for the insns that are not valid.


File: gcc.info,  Node: Insn Attributes,  Prev: Insn Splitting,  Up: Machine Desc

Instruction Attributes
======================

   In addition to describing the instruction supported by the target
machine, the `md' file also defines a group of "attributes" and a set of
values for each.  Every generated insn is assigned a value for each
attribute.  One possible attribute would be the effect that the insn
has on the machine's condition code.  This attribute can then be used
by `NOTICE_UPDATE_CC' to track the condition codes.

* Menu:

* Defining Attributes:: Specifying attributes and their values.
* Expressions::         Valid expressions for attribute values.
* Tagging Insns::       Assigning attribute values to insns.
* Attr Example::        An example of assigning attributes.
* Insn Lengths::        Computing the length of insns.
* Constant Attributes:: Defining attributes that are constant.
* Delay Slots::         Defining delay slots required for a machine.
* Function Units::      Specifying information for insn scheduling.


File: gcc.info,  Node: Defining Attributes,  Next: Expressions,  Up: Insn Attributes

Defining Attributes and their Values
------------------------------------

   The `define_attr' expression is used to define each attribute
required by the target machine.  It looks like:

     (define_attr NAME LIST-OF-VALUES DEFAULT)

   NAME is a string specifying the name of the attribute being defined.

   LIST-OF-VALUES is either a string that specifies a comma-separated
list of values that can be assigned to the attribute, or a null string
to indicate that the attribute takes numeric values.

   DEFAULT is an attribute expression that gives the value of this
attribute for insns that match patterns whose definition does not
include an explicit value for this attribute.  *Note Attr Example::,
for more information on the handling of defaults.  *Note Constant
Attributes::, for information on attributes that do not depend on any
particular insn.

   For each defined attribute, a number of definitions are written to
the `insn-attr.h' file.  For cases where an explicit set of values is
specified for an attribute, the following are defined:

   * A `#define' is written for the symbol `HAVE_ATTR_NAME'.

   * An enumeral class is defined for `attr_NAME' with elements of the
     form `UPPER-NAME_UPPER-VALUE' where the attribute name and value
     are first converted to upper case.

   * A function `get_attr_NAME' is defined that is passed an insn and
     returns the attribute value for that insn.

   For example, if the following is present in the `md' file:

     (define_attr "type" "branch,fp,load,store,arith" ...)

the following lines will be written to the file `insn-attr.h'.

     #define HAVE_ATTR_type
     enum attr_type {TYPE_BRANCH, TYPE_FP, TYPE_LOAD,
                      TYPE_STORE, TYPE_ARITH};
     extern enum attr_type get_attr_type ();

   If the attribute takes numeric values, no `enum' type will be
defined and the function to obtain the attribute's value will return
`int'.


File: gcc.info,  Node: Expressions,  Next: Tagging Insns,  Prev: Defining Attributes,  Up: Insn Attributes

Attribute Expressions
---------------------

   RTL expressions used to define attributes use the codes described
above plus a few specific to attribute definitions, to be discussed
below.  Attribute value expressions must have one of the following
forms:

`(const_int I)'
     The integer I specifies the value of a numeric attribute.  I must
     be non-negative.

     The value of a numeric attribute can be specified either with a
     `const_int' or as an integer represented as a string in
     `const_string', `eq_attr' (see below), and `set_attr' (*note
     Tagging Insns::.) expressions.

`(const_string VALUE)'
     The string VALUE specifies a constant attribute value.  If VALUE
     is specified as `"*"', it means that the default value of the
     attribute is to be used for the insn containing this expression.
     `"*"' obviously cannot be used in the DEFAULT expression of a
     `define_attr'.

     If the attribute whose value is being specified is numeric, VALUE
     must be a string containing a non-negative integer (normally
     `const_int' would be used in this case).  Otherwise, it must
     contain one of the valid values for the attribute.

`(if_then_else TEST TRUE-VALUE FALSE-VALUE)'
     TEST specifies an attribute test, whose format is defined below.
     The value of this expression is TRUE-VALUE if TEST is true,
     otherwise it is FALSE-VALUE.

`(cond [TEST1 VALUE1 ...] DEFAULT)'
     The first operand of this expression is a vector containing an even
     number of expressions and consisting of pairs of TEST and VALUE
     expressions.  The value of the `cond' expression is that of the
     VALUE corresponding to the first true TEST expression.  If none of
     the TEST expressions are true, the value of the `cond' expression
     is that of the DEFAULT expression.

   TEST expressions can have one of the following forms:

`(const_int I)'
     This test is true if I is non-zero and false otherwise.

`(not TEST)'
`(ior TEST1 TEST2)'
`(and TEST1 TEST2)'
     These tests are true if the indicated logical function is true.

`(match_operand:M N PRED CONSTRAINTS)'
     This test is true if operand N of the insn whose attribute value
     is being determined has mode M (this part of the test is ignored
     if M is `VOIDmode') and the function specified by the string PRED
     returns a non-zero value when passed operand N and mode M (this
     part of the test is ignored if PRED is the null string).

     The CONSTRAINTS operand is ignored and should be the null string.

`(le ARITH1 ARITH2)'
`(leu ARITH1 ARITH2)'
`(lt ARITH1 ARITH2)'
`(ltu ARITH1 ARITH2)'
`(gt ARITH1 ARITH2)'
`(gtu ARITH1 ARITH2)'
`(ge ARITH1 ARITH2)'
`(geu ARITH1 ARITH2)'
`(ne ARITH1 ARITH2)'
`(eq ARITH1 ARITH2)'
     These tests are true if the indicated comparison of the two
     arithmetic expressions is true.  Arithmetic expressions are formed
     with `plus', `minus', `mult', `div', `mod', `abs', `neg', `and',
     `ior', `xor', `not', `ashift', `lshiftrt', and `ashiftrt'
     expressions.

     `const_int' and `symbol_ref' are always valid terms (*note Insn
     Lengths::.,for additional forms).  `symbol_ref' is a string
     denoting a C expression that yields an `int' when evaluated by the
     `get_attr_...' routine.  It should normally be a global variable.

`(eq_attr NAME VALUE)'
     NAME is a string specifying the name of an attribute.

     VALUE is a string that is either a valid value for attribute NAME,
     a comma-separated list of values, or `!' followed by a value or
     list.  If VALUE does not begin with a `!', this test is true if
     the value of the NAME attribute of the current insn is in the list
     specified by VALUE.  If VALUE begins with a `!', this test is true
     if the attribute's value is *not* in the specified list.

     For example,

          (eq_attr "type" "load,store")

     is equivalent to

          (ior (eq_attr "type" "load") (eq_attr "type" "store"))

     If NAME specifies an attribute of `alternative', it refers to the
     value of the compiler variable `which_alternative' (*note Output
     Statement::.) and the values must be small integers.  For example,

          (eq_attr "alternative" "2,3")

     is equivalent to

          (ior (eq (symbol_ref "which_alternative") (const_int 2))
               (eq (symbol_ref "which_alternative") (const_int 3)))

     Note that, for most attributes, an `eq_attr' test is simplified in
     cases where the value of the attribute being tested is known for
     all insns matching a particular pattern.  This is by far the most
     common case.

`(attr_flag NAME)'
     The value of an `attr_flag' expression is true if the flag
     specified by NAME is true for the `insn' currently being scheduled.

     NAME is a string specifying one of a fixed set of flags to test.
     Test the flags `forward' and `backward' to determine the direction
     of a conditional branch.  Test the flags `very_likely', `likely',
     `very_unlikely', and `unlikely' to determine if a conditional
     branch is expected to be taken.

     If the `very_likely' flag is true, then the `likely' flag is also
     true.  Likewise for the `very_unlikely' and `unlikely' flags.

     This example describes a conditional branch delay slot which can
     be nullified for forward branches that are taken (annul-true) or
     for backward branches which are not taken (annul-false).

          (define_delay (eq_attr "type" "cbranch")
            [(eq_attr "in_branch_delay" "true")
             (and (eq_attr "in_branch_delay" "true")
                  (attr_flag "forward"))
             (and (eq_attr "in_branch_delay" "true")
                  (attr_flag "backward"))])

     The `forward' and `backward' flags are false if the current `insn'
     being scheduled is not a conditional branch.

     The `very_likely' and `likely' flags are true if the `insn' being
     scheduled is not a conditional branch.  The `very_unlikely' and
     `unlikely' flags are false if the `insn' being scheduled is not a
     conditional branch.

     `attr_flag' is only used during delay slot scheduling and has no
     meaning to other passes of the compiler.


File: gcc.info,  Node: Tagging Insns,  Next: Attr Example,  Prev: Expressions,  Up: Insn Attributes

Assigning Attribute Values to Insns
-----------------------------------

   The value assigned to an attribute of an insn is primarily
determined by which pattern is matched by that insn (or which
`define_peephole' generated it).  Every `define_insn' and
`define_peephole' can have an optional last argument to specify the
values of attributes for matching insns.  The value of any attribute
not specified in a particular insn is set to the default value for that
attribute, as specified in its `define_attr'.  Extensive use of default
values for attributes permits the specification of the values for only
one or two attributes in the definition of most insn patterns, as seen
in the example in the next section.

   The optional last argument of `define_insn' and `define_peephole' is
a vector of expressions, each of which defines the value for a single
attribute.  The most general way of assigning an attribute's value is
to use a `set' expression whose first operand is an `attr' expression
giving the name of the attribute being set.  The second operand of the
`set' is an attribute expression (*note Expressions::.) giving the
value of the attribute.

   When the attribute value depends on the `alternative' attribute
(i.e., which is the applicable alternative in the constraint of the
insn), the `set_attr_alternative' expression can be used.  It allows
the specification of a vector of attribute expressions, one for each
alternative.

   When the generality of arbitrary attribute expressions is not
required, the simpler `set_attr' expression can be used, which allows
specifying a string giving either a single attribute value or a list of
attribute values, one for each alternative.

   The form of each of the above specifications is shown below.  In
each case, NAME is a string specifying the attribute to be set.

`(set_attr NAME VALUE-STRING)'
     VALUE-STRING is either a string giving the desired attribute value,
     or a string containing a comma-separated list giving the values for
     succeeding alternatives.  The number of elements must match the
     number of alternatives in the constraint of the insn pattern.

     Note that it may be useful to specify `*' for some alternative, in
     which case the attribute will assume its default value for insns
     matching that alternative.

`(set_attr_alternative NAME [VALUE1 VALUE2 ...])'
     Depending on the alternative of the insn, the value will be one of
     the specified values.  This is a shorthand for using a `cond' with
     tests on the `alternative' attribute.

`(set (attr NAME) VALUE)'
     The first operand of this `set' must be the special RTL expression
     `attr', whose sole operand is a string giving the name of the
     attribute being set.  VALUE is the value of the attribute.

   The following shows three different ways of representing the same
attribute value specification:

     (set_attr "type" "load,store,arith")
     
     (set_attr_alternative "type"
                           [(const_string "load") (const_string "store")
                            (const_string "arith")])
     
     (set (attr "type")
          (cond [(eq_attr "alternative" "1") (const_string "load")
                 (eq_attr "alternative" "2") (const_string "store")]
                (const_string "arith")))

   The `define_asm_attributes' expression provides a mechanism to
specify the attributes assigned to insns produced from an `asm'
statement.  It has the form:

     (define_asm_attributes [ATTR-SETS])

where ATTR-SETS is specified the same as for both the `define_insn' and
the `define_peephole' expressions.

   These values will typically be the "worst case" attribute values.
For example, they might indicate that the condition code will be
clobbered.

   A specification for a `length' attribute is handled specially.  The
way to compute the length of an `asm' insn is to multiply the length
specified in the expression `define_asm_attributes' by the number of
machine instructions specified in the `asm' statement, determined by
counting the number of semicolons and newlines in the string.
Therefore, the value of the `length' attribute specified in a
`define_asm_attributes' should be the maximum possible length of a
single machine instruction.


File: gcc.info,  Node: Attr Example,  Next: Insn Lengths,  Prev: Tagging Insns,  Up: Insn Attributes

Example of Attribute Specifications
-----------------------------------

   The judicious use of defaulting is important in the efficient use of
insn attributes.  Typically, insns are divided into "types" and an
attribute, customarily called `type', is used to represent this value.
This attribute is normally used only to define the default value for
other attributes.  An example will clarify this usage.

   Assume we have a RISC machine with a condition code and in which only
full-word operations are performed in registers.  Let us assume that we
can divide all insns into loads, stores, (integer) arithmetic
operations, floating point operations, and branches.

   Here we will concern ourselves with determining the effect of an
insn on the condition code and will limit ourselves to the following
possible effects:  The condition code can be set unpredictably
(clobbered), not be changed, be set to agree with the results of the
operation, or only changed if the item previously set into the
condition code has been modified.

   Here is part of a sample `md' file for such a machine:

     (define_attr "type" "load,store,arith,fp,branch" (const_string "arith"))
     
     (define_attr "cc" "clobber,unchanged,set,change0"
                  (cond [(eq_attr "type" "load")
                             (const_string "change0")
                         (eq_attr "type" "store,branch")
                             (const_string "unchanged")
                         (eq_attr "type" "arith")
                             (if_then_else (match_operand:SI 0 "" "")
                                           (const_string "set")
                                           (const_string "clobber"))]
                        (const_string "clobber")))
     
     (define_insn ""
       [(set (match_operand:SI 0 "general_operand" "=r,r,m")
             (match_operand:SI 1 "general_operand" "r,m,r"))]
       ""
       "@
        move %0,%1
        load %0,%1
        store %0,%1"
       [(set_attr "type" "arith,load,store")])

   Note that we assume in the above example that arithmetic operations
performed on quantities smaller than a machine word clobber the
condition code since they will set the condition code to a value
corresponding to the full-word result.


File: gcc.info,  Node: Insn Lengths,  Next: Constant Attributes,  Prev: Attr Example,  Up: Insn Attributes

Computing the Length of an Insn
-------------------------------

   For many machines, multiple types of branch instructions are
provided, each for different length branch displacements.  In most
cases, the assembler will choose the correct instruction to use.
However, when the assembler cannot do so, GCC can when a special
attribute, the `length' attribute, is defined.  This attribute must be
defined to have numeric values by specifying a null string in its
`define_attr'.

   In the case of the `length' attribute, two additional forms of
arithmetic terms are allowed in test expressions:

`(match_dup N)'
     This refers to the address of operand N of the current insn, which
     must be a `label_ref'.

`(pc)'
     This refers to the address of the *current* insn.  It might have
     been more consistent with other usage to make this the address of
     the *next* insn but this would be confusing because the length of
     the current insn is to be computed.

   For normal insns, the length will be determined by value of the
`length' attribute.  In the case of `addr_vec' and `addr_diff_vec' insn
patterns, the length is computed as the number of vectors multiplied by
the size of each vector.

   Lengths are measured in addressable storage units (bytes).

   The following macros can be used to refine the length computation:

`FIRST_INSN_ADDRESS'
     When the `length' insn attribute is used, this macro specifies the
     value to be assigned to the address of the first insn in a
     function.  If not specified, 0 is used.

`ADJUST_INSN_LENGTH (INSN, LENGTH)'
     If defined, modifies the length assigned to instruction INSN as a
     function of the context in which it is used.  LENGTH is an lvalue
     that contains the initially computed length of the insn and should
     be updated with the correct length of the insn.  If updating is
     required, INSN must not be a varying-length insn.

     This macro will normally not be required.  A case in which it is
     required is the ROMP.  On this machine, the size of an `addr_vec'
     insn must be increased by two to compensate for the fact that
     alignment may be required.

   The routine that returns `get_attr_length' (the value of the
`length' attribute) can be used by the output routine to determine the
form of the branch instruction to be written, as the example below
illustrates.

   As an example of the specification of variable-length branches,
consider the IBM 360.  If we adopt the convention that a register will
be set to the starting address of a function, we can jump to labels
within 4k of the start using a four-byte instruction.  Otherwise, we
need a six-byte sequence to load the address from memory and then
branch to it.

   On such a machine, a pattern for a branch instruction might be
specified as follows:

     (define_insn "jump"
       [(set (pc)
             (label_ref (match_operand 0 "" "")))]
       ""
       "*
     {
        return (get_attr_length (insn) == 4
                ? \"b %l0\" : \"l r15,=a(%l0); br r15\");
     }"
       [(set (attr "length") (if_then_else (lt (match_dup 0) (const_int 4096))
                                           (const_int 4)
                                           (const_int 6)))])


File: gcc.info,  Node: Constant Attributes,  Next: Delay Slots,  Prev: Insn Lengths,  Up: Insn Attributes

Constant Attributes
-------------------

   A special form of `define_attr', where the expression for the
default value is a `const' expression, indicates an attribute that is
constant for a given run of the compiler.  Constant attributes may be
used to specify which variety of processor is used.  For example,

     (define_attr "cpu" "m88100,m88110,m88000"
      (const
       (cond [(symbol_ref "TARGET_88100") (const_string "m88100")
              (symbol_ref "TARGET_88110") (const_string "m88110")]
             (const_string "m88000"))))
     
     (define_attr "memory" "fast,slow"
      (const
       (if_then_else (symbol_ref "TARGET_FAST_MEM")
                     (const_string "fast")
                     (const_string "slow"))))

   The routine generated for constant attributes has no parameters as it
does not depend on any particular insn.  RTL expressions used to define
the value of a constant attribute may use the `symbol_ref' form, but
may not use either the `match_operand' form or `eq_attr' forms
involving insn attributes.


File: gcc.info,  Node: Delay Slots,  Next: Function Units,  Prev: Constant Attributes,  Up: Insn Attributes

Delay Slot Scheduling
---------------------

   The insn attribute mechanism can be used to specify the requirements
for delay slots, if any, on a target machine.  An instruction is said to
require a "delay slot" if some instructions that are physically after
the instruction are executed as if they were located before it.
Classic examples are branch and call instructions, which often execute
the following instruction before the branch or call is performed.

   On some machines, conditional branch instructions can optionally
"annul" instructions in the delay slot.  This means that the
instruction will not be executed for certain branch outcomes.  Both
instructions that annul if the branch is true and instructions that
annul if the branch is false are supported.

   Delay slot scheduling differs from instruction scheduling in that
determining whether an instruction needs a delay slot is dependent only
on the type of instruction being generated, not on data flow between the
instructions.  See the next section for a discussion of data-dependent
instruction scheduling.

   The requirement of an insn needing one or more delay slots is
indicated via the `define_delay' expression.  It has the following form:

     (define_delay TEST
                   [DELAY-1 ANNUL-TRUE-1 ANNUL-FALSE-1
                    DELAY-2 ANNUL-TRUE-2 ANNUL-FALSE-2
                    ...])

   TEST is an attribute test that indicates whether this `define_delay'
applies to a particular insn.  If so, the number of required delay
slots is determined by the length of the vector specified as the second
argument.  An insn placed in delay slot N must satisfy attribute test
DELAY-N.  ANNUL-TRUE-N is an attribute test that specifies which insns
may be annulled if the branch is true.  Similarly, ANNUL-FALSE-N
specifies which insns in the delay slot may be annulled if the branch
is false.  If annulling is not supported for that delay slot, `(nil)'
should be coded.

   For example, in the common case where branch and call insns require
a single delay slot, which may contain any insn other than a branch or
call, the following would be placed in the `md' file:

     (define_delay (eq_attr "type" "branch,call")
                   [(eq_attr "type" "!branch,call") (nil) (nil)])

   Multiple `define_delay' expressions may be specified.  In this case,
each such expression specifies different delay slot requirements and
there must be no insn for which tests in two `define_delay' expressions
are both true.

   For example, if we have a machine that requires one delay slot for
branches but two for calls,  no delay slot can contain a branch or call
insn, and any valid insn in the delay slot for the branch can be
annulled if the branch is true, we might represent this as follows:

     (define_delay (eq_attr "type" "branch")
        [(eq_attr "type" "!branch,call")
         (eq_attr "type" "!branch,call")
         (nil)])
     
     (define_delay (eq_attr "type" "call")
                   [(eq_attr "type" "!branch,call") (nil) (nil)
                    (eq_attr "type" "!branch,call") (nil) (nil)])

