mirror of
https://github.com/pmret/gcc-papermario.git
synced 2024-11-08 20:02:47 +01:00
1054 lines
48 KiB
Plaintext
1054 lines
48 KiB
Plaintext
|
This is Info file gcc.info, produced by Makeinfo version 1.67 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: Insns, Next: Calls, Prev: Assembler, Up: RTL
|
|||
|
|
|||
|
Insns
|
|||
|
=====
|
|||
|
|
|||
|
The RTL representation of the code for a function is a doubly-linked
|
|||
|
chain of objects called "insns". Insns are expressions with special
|
|||
|
codes that are used for no other purpose. Some insns are actual
|
|||
|
instructions; others represent dispatch tables for `switch' statements;
|
|||
|
others represent labels to jump to or various sorts of declarative
|
|||
|
information.
|
|||
|
|
|||
|
In addition to its own specific data, each insn must have a unique
|
|||
|
id-number that distinguishes it from all other insns in the current
|
|||
|
function (after delayed branch scheduling, copies of an insn with the
|
|||
|
same id-number may be present in multiple places in a function, but
|
|||
|
these copies will always be identical and will only appear inside a
|
|||
|
`sequence'), and chain pointers to the preceding and following insns.
|
|||
|
These three fields occupy the same position in every insn, independent
|
|||
|
of the expression code of the insn. They could be accessed with `XEXP'
|
|||
|
and `XINT', but instead three special macros are always used:
|
|||
|
|
|||
|
`INSN_UID (I)'
|
|||
|
Accesses the unique id of insn I.
|
|||
|
|
|||
|
`PREV_INSN (I)'
|
|||
|
Accesses the chain pointer to the insn preceding I. If I is the
|
|||
|
first insn, this is a null pointer.
|
|||
|
|
|||
|
`NEXT_INSN (I)'
|
|||
|
Accesses the chain pointer to the insn following I. If I is the
|
|||
|
last insn, this is a null pointer.
|
|||
|
|
|||
|
The first insn in the chain is obtained by calling `get_insns'; the
|
|||
|
last insn is the result of calling `get_last_insn'. Within the chain
|
|||
|
delimited by these insns, the `NEXT_INSN' and `PREV_INSN' pointers must
|
|||
|
always correspond: if INSN is not the first insn,
|
|||
|
|
|||
|
NEXT_INSN (PREV_INSN (INSN)) == INSN
|
|||
|
|
|||
|
is always true and if INSN is not the last insn,
|
|||
|
|
|||
|
PREV_INSN (NEXT_INSN (INSN)) == INSN
|
|||
|
|
|||
|
is always true.
|
|||
|
|
|||
|
After delay slot scheduling, some of the insns in the chain might be
|
|||
|
`sequence' expressions, which contain a vector of insns. The value of
|
|||
|
`NEXT_INSN' in all but the last of these insns is the next insn in the
|
|||
|
vector; the value of `NEXT_INSN' of the last insn in the vector is the
|
|||
|
same as the value of `NEXT_INSN' for the `sequence' in which it is
|
|||
|
contained. Similar rules apply for `PREV_INSN'.
|
|||
|
|
|||
|
This means that the above invariants are not necessarily true for
|
|||
|
insns inside `sequence' expressions. Specifically, if INSN is the
|
|||
|
first insn in a `sequence', `NEXT_INSN (PREV_INSN (INSN))' is the insn
|
|||
|
containing the `sequence' expression, as is the value of `PREV_INSN
|
|||
|
(NEXT_INSN (INSN))' is INSN is the last insn in the `sequence'
|
|||
|
expression. You can use these expressions to find the containing
|
|||
|
`sequence' expression.
|
|||
|
|
|||
|
Every insn has one of the following six expression codes:
|
|||
|
|
|||
|
`insn'
|
|||
|
The expression code `insn' is used for instructions that do not
|
|||
|
jump and do not do function calls. `sequence' expressions are
|
|||
|
always contained in insns with code `insn' even if one of those
|
|||
|
insns should jump or do function calls.
|
|||
|
|
|||
|
Insns with code `insn' have four additional fields beyond the three
|
|||
|
mandatory ones listed above. These four are described in a table
|
|||
|
below.
|
|||
|
|
|||
|
`jump_insn'
|
|||
|
The expression code `jump_insn' is used for instructions that may
|
|||
|
jump (or, more generally, may contain `label_ref' expressions). If
|
|||
|
there is an instruction to return from the current function, it is
|
|||
|
recorded as a `jump_insn'.
|
|||
|
|
|||
|
`jump_insn' insns have the same extra fields as `insn' insns,
|
|||
|
accessed in the same way and in addition contain a field
|
|||
|
`JUMP_LABEL' which is defined once jump optimization has completed.
|
|||
|
|
|||
|
For simple conditional and unconditional jumps, this field
|
|||
|
contains the `code_label' to which this insn will (possibly
|
|||
|
conditionally) branch. In a more complex jump, `JUMP_LABEL'
|
|||
|
records one of the labels that the insn refers to; the only way to
|
|||
|
find the others is to scan the entire body of the insn.
|
|||
|
|
|||
|
Return insns count as jumps, but since they do not refer to any
|
|||
|
labels, they have zero in the `JUMP_LABEL' field.
|
|||
|
|
|||
|
`call_insn'
|
|||
|
The expression code `call_insn' is used for instructions that may
|
|||
|
do function calls. It is important to distinguish these
|
|||
|
instructions because they imply that certain registers and memory
|
|||
|
locations may be altered unpredictably.
|
|||
|
|
|||
|
`call_insn' insns have the same extra fields as `insn' insns,
|
|||
|
accessed in the same way and in addition contain a field
|
|||
|
`CALL_INSN_FUNCTION_USAGE', which contains a list (chain of
|
|||
|
`expr_list' expressions) containing `use' and `clobber'
|
|||
|
expressions that denote hard registers used or clobbered by the
|
|||
|
called function. A register specified in a `clobber' in this list
|
|||
|
is modified *after* the execution of the `call_insn', while a
|
|||
|
register in a `clobber' in the body of the `call_insn' is
|
|||
|
clobbered before the insn completes execution. `clobber'
|
|||
|
expressions in this list augment registers specified in
|
|||
|
`CALL_USED_REGISTERS' (*note Register Basics::.).
|
|||
|
|
|||
|
`code_label'
|
|||
|
A `code_label' insn represents a label that a jump insn can jump
|
|||
|
to. It contains two special fields of data in addition to the
|
|||
|
three standard ones. `CODE_LABEL_NUMBER' is used to hold the
|
|||
|
"label number", a number that identifies this label uniquely among
|
|||
|
all the labels in the compilation (not just in the current
|
|||
|
function). Ultimately, the label is represented in the assembler
|
|||
|
output as an assembler label, usually of the form `LN' where N is
|
|||
|
the label number.
|
|||
|
|
|||
|
When a `code_label' appears in an RTL expression, it normally
|
|||
|
appears within a `label_ref' which represents the address of the
|
|||
|
label, as a number.
|
|||
|
|
|||
|
The field `LABEL_NUSES' is only defined once the jump optimization
|
|||
|
phase is completed and contains the number of times this label is
|
|||
|
referenced in the current function.
|
|||
|
|
|||
|
`barrier'
|
|||
|
Barriers are placed in the instruction stream when control cannot
|
|||
|
flow past them. They are placed after unconditional jump
|
|||
|
instructions to indicate that the jumps are unconditional and
|
|||
|
after calls to `volatile' functions, which do not return (e.g.,
|
|||
|
`exit'). They contain no information beyond the three standard
|
|||
|
fields.
|
|||
|
|
|||
|
`note'
|
|||
|
`note' insns are used to represent additional debugging and
|
|||
|
declarative information. They contain two nonstandard fields, an
|
|||
|
integer which is accessed with the macro `NOTE_LINE_NUMBER' and a
|
|||
|
string accessed with `NOTE_SOURCE_FILE'.
|
|||
|
|
|||
|
If `NOTE_LINE_NUMBER' is positive, the note represents the
|
|||
|
position of a source line and `NOTE_SOURCE_FILE' is the source
|
|||
|
file name that the line came from. These notes control generation
|
|||
|
of line number data in the assembler output.
|
|||
|
|
|||
|
Otherwise, `NOTE_LINE_NUMBER' is not really a line number but a
|
|||
|
code with one of the following values (and `NOTE_SOURCE_FILE' must
|
|||
|
contain a null pointer):
|
|||
|
|
|||
|
`NOTE_INSN_DELETED'
|
|||
|
Such a note is completely ignorable. Some passes of the
|
|||
|
compiler delete insns by altering them into notes of this
|
|||
|
kind.
|
|||
|
|
|||
|
`NOTE_INSN_BLOCK_BEG'
|
|||
|
`NOTE_INSN_BLOCK_END'
|
|||
|
These types of notes indicate the position of the beginning
|
|||
|
and end of a level of scoping of variable names. They
|
|||
|
control the output of debugging information.
|
|||
|
|
|||
|
`NOTE_INSN_EH_REGION_BEG'
|
|||
|
`NOTE_INSN_EH_REGION_END'
|
|||
|
These types of notes indicate the position of the beginning
|
|||
|
and end of a level of scoping for exception handling.
|
|||
|
`NOTE_BLOCK_NUMBER' identifies which `CODE_LABEL' is
|
|||
|
associated with the given region.
|
|||
|
|
|||
|
`NOTE_INSN_LOOP_BEG'
|
|||
|
`NOTE_INSN_LOOP_END'
|
|||
|
These types of notes indicate the position of the beginning
|
|||
|
and end of a `while' or `for' loop. They enable the loop
|
|||
|
optimizer to find loops quickly.
|
|||
|
|
|||
|
`NOTE_INSN_LOOP_CONT'
|
|||
|
Appears at the place in a loop that `continue' statements
|
|||
|
jump to.
|
|||
|
|
|||
|
`NOTE_INSN_LOOP_VTOP'
|
|||
|
This note indicates the place in a loop where the exit test
|
|||
|
begins for those loops in which the exit test has been
|
|||
|
duplicated. This position becomes another virtual start of
|
|||
|
the loop when considering loop invariants.
|
|||
|
|
|||
|
`NOTE_INSN_FUNCTION_END'
|
|||
|
Appears near the end of the function body, just before the
|
|||
|
label that `return' statements jump to (on machine where a
|
|||
|
single instruction does not suffice for returning). This
|
|||
|
note may be deleted by jump optimization.
|
|||
|
|
|||
|
`NOTE_INSN_SETJMP'
|
|||
|
Appears following each call to `setjmp' or a related function.
|
|||
|
|
|||
|
These codes are printed symbolically when they appear in debugging
|
|||
|
dumps.
|
|||
|
|
|||
|
The machine mode of an insn is normally `VOIDmode', but some phases
|
|||
|
use the mode for various purposes; for example, the reload pass sets it
|
|||
|
to `HImode' if the insn needs reloading but not register elimination
|
|||
|
and `QImode' if both are required. The common subexpression
|
|||
|
elimination pass sets the mode of an insn to `QImode' when it is the
|
|||
|
first insn in a block that has already been processed.
|
|||
|
|
|||
|
Here is a table of the extra fields of `insn', `jump_insn' and
|
|||
|
`call_insn' insns:
|
|||
|
|
|||
|
`PATTERN (I)'
|
|||
|
An expression for the side effect performed by this insn. This
|
|||
|
must be one of the following codes: `set', `call', `use',
|
|||
|
`clobber', `return', `asm_input', `asm_output', `addr_vec',
|
|||
|
`addr_diff_vec', `trap_if', `unspec', `unspec_volatile',
|
|||
|
`parallel', or `sequence'. If it is a `parallel', each element of
|
|||
|
the `parallel' must be one these codes, except that `parallel'
|
|||
|
expressions cannot be nested and `addr_vec' and `addr_diff_vec'
|
|||
|
are not permitted inside a `parallel' expression.
|
|||
|
|
|||
|
`INSN_CODE (I)'
|
|||
|
An integer that says which pattern in the machine description
|
|||
|
matches this insn, or -1 if the matching has not yet been
|
|||
|
attempted.
|
|||
|
|
|||
|
Such matching is never attempted and this field remains -1 on an
|
|||
|
insn whose pattern consists of a single `use', `clobber',
|
|||
|
`asm_input', `addr_vec' or `addr_diff_vec' expression.
|
|||
|
|
|||
|
Matching is also never attempted on insns that result from an `asm'
|
|||
|
statement. These contain at least one `asm_operands' expression.
|
|||
|
The function `asm_noperands' returns a non-negative value for such
|
|||
|
insns.
|
|||
|
|
|||
|
In the debugging output, this field is printed as a number
|
|||
|
followed by a symbolic representation that locates the pattern in
|
|||
|
the `md' file as some small positive or negative offset from a
|
|||
|
named pattern.
|
|||
|
|
|||
|
`LOG_LINKS (I)'
|
|||
|
A list (chain of `insn_list' expressions) giving information about
|
|||
|
dependencies between instructions within a basic block. Neither a
|
|||
|
jump nor a label may come between the related insns.
|
|||
|
|
|||
|
`REG_NOTES (I)'
|
|||
|
A list (chain of `expr_list' and `insn_list' expressions) giving
|
|||
|
miscellaneous information about the insn. It is often information
|
|||
|
pertaining to the registers used in this insn.
|
|||
|
|
|||
|
The `LOG_LINKS' field of an insn is a chain of `insn_list'
|
|||
|
expressions. Each of these has two operands: the first is an insn, and
|
|||
|
the second is another `insn_list' expression (the next one in the
|
|||
|
chain). The last `insn_list' in the chain has a null pointer as second
|
|||
|
operand. The significant thing about the chain is which insns appear
|
|||
|
in it (as first operands of `insn_list' expressions). Their order is
|
|||
|
not significant.
|
|||
|
|
|||
|
This list is originally set up by the flow analysis pass; it is a
|
|||
|
null pointer until then. Flow only adds links for those data
|
|||
|
dependencies which can be used for instruction combination. For each
|
|||
|
insn, the flow analysis pass adds a link to insns which store into
|
|||
|
registers values that are used for the first time in this insn. The
|
|||
|
instruction scheduling pass adds extra links so that every dependence
|
|||
|
will be represented. Links represent data dependencies,
|
|||
|
antidependencies and output dependencies; the machine mode of the link
|
|||
|
distinguishes these three types: antidependencies have mode
|
|||
|
`REG_DEP_ANTI', output dependencies have mode `REG_DEP_OUTPUT', and
|
|||
|
data dependencies have mode `VOIDmode'.
|
|||
|
|
|||
|
The `REG_NOTES' field of an insn is a chain similar to the
|
|||
|
`LOG_LINKS' field but it includes `expr_list' expressions in addition
|
|||
|
to `insn_list' expressions. There are several kinds of register notes,
|
|||
|
which are distinguished by the machine mode, which in a register note
|
|||
|
is really understood as being an `enum reg_note'. The first operand OP
|
|||
|
of the note is data whose meaning depends on the kind of note.
|
|||
|
|
|||
|
The macro `REG_NOTE_KIND (X)' returns the kind of register note.
|
|||
|
Its counterpart, the macro `PUT_REG_NOTE_KIND (X, NEWKIND)' sets the
|
|||
|
register note type of X to be NEWKIND.
|
|||
|
|
|||
|
Register notes are of three classes: They may say something about an
|
|||
|
input to an insn, they may say something about an output of an insn, or
|
|||
|
they may create a linkage between two insns. There are also a set of
|
|||
|
values that are only used in `LOG_LINKS'.
|
|||
|
|
|||
|
These register notes annotate inputs to an insn:
|
|||
|
|
|||
|
`REG_DEAD'
|
|||
|
The value in OP dies in this insn; that is to say, altering the
|
|||
|
value immediately after this insn would not affect the future
|
|||
|
behavior of the program.
|
|||
|
|
|||
|
This does not necessarily mean that the register OP has no useful
|
|||
|
value after this insn since it may also be an output of the insn.
|
|||
|
In such a case, however, a `REG_DEAD' note would be redundant and
|
|||
|
is usually not present until after the reload pass, but no code
|
|||
|
relies on this fact.
|
|||
|
|
|||
|
`REG_INC'
|
|||
|
The register OP is incremented (or decremented; at this level
|
|||
|
there is no distinction) by an embedded side effect inside this
|
|||
|
insn. This means it appears in a `post_inc', `pre_inc',
|
|||
|
`post_dec' or `pre_dec' expression.
|
|||
|
|
|||
|
`REG_NONNEG'
|
|||
|
The register OP is known to have a nonnegative value when this
|
|||
|
insn is reached. This is used so that decrement and branch until
|
|||
|
zero instructions, such as the m68k dbra, can be matched.
|
|||
|
|
|||
|
The `REG_NONNEG' note is added to insns only if the machine
|
|||
|
description has a `decrement_and_branch_until_zero' pattern.
|
|||
|
|
|||
|
`REG_NO_CONFLICT'
|
|||
|
This insn does not cause a conflict between OP and the item being
|
|||
|
set by this insn even though it might appear that it does. In
|
|||
|
other words, if the destination register and OP could otherwise be
|
|||
|
assigned the same register, this insn does not prevent that
|
|||
|
assignment.
|
|||
|
|
|||
|
Insns with this note are usually part of a block that begins with a
|
|||
|
`clobber' insn specifying a multi-word pseudo register (which will
|
|||
|
be the output of the block), a group of insns that each set one
|
|||
|
word of the value and have the `REG_NO_CONFLICT' note attached,
|
|||
|
and a final insn that copies the output to itself with an attached
|
|||
|
`REG_EQUAL' note giving the expression being computed. This block
|
|||
|
is encapsulated with `REG_LIBCALL' and `REG_RETVAL' notes on the
|
|||
|
first and last insns, respectively.
|
|||
|
|
|||
|
`REG_LABEL'
|
|||
|
This insn uses OP, a `code_label', but is not a `jump_insn'. The
|
|||
|
presence of this note allows jump optimization to be aware that OP
|
|||
|
is, in fact, being used.
|
|||
|
|
|||
|
The following notes describe attributes of outputs of an insn:
|
|||
|
|
|||
|
`REG_EQUIV'
|
|||
|
`REG_EQUAL'
|
|||
|
This note is only valid on an insn that sets only one register and
|
|||
|
indicates that that register will be equal to OP at run time; the
|
|||
|
scope of this equivalence differs between the two types of notes.
|
|||
|
The value which the insn explicitly copies into the register may
|
|||
|
look different from OP, but they will be equal at run time. If the
|
|||
|
output of the single `set' is a `strict_low_part' expression, the
|
|||
|
note refers to the register that is contained in `SUBREG_REG' of
|
|||
|
the `subreg' expression.
|
|||
|
|
|||
|
For `REG_EQUIV', the register is equivalent to OP throughout the
|
|||
|
entire function, and could validly be replaced in all its
|
|||
|
occurrences by OP. ("Validly" here refers to the data flow of the
|
|||
|
program; simple replacement may make some insns invalid.) For
|
|||
|
example, when a constant is loaded into a register that is never
|
|||
|
assigned any other value, this kind of note is used.
|
|||
|
|
|||
|
When a parameter is copied into a pseudo-register at entry to a
|
|||
|
function, a note of this kind records that the register is
|
|||
|
equivalent to the stack slot where the parameter was passed.
|
|||
|
Although in this case the register may be set by other insns, it
|
|||
|
is still valid to replace the register by the stack slot
|
|||
|
throughout the function.
|
|||
|
|
|||
|
A `REG_EQUIV' note is also used on an instruction which copies a
|
|||
|
register parameter into a pseudo-register at entry to a function,
|
|||
|
if there is a stack slot where that parameter could be stored.
|
|||
|
Although other insns may set the pseudo-register, it is valid for
|
|||
|
the compiler to replace the pseudo-register by stack slot
|
|||
|
throughout the function, provided the compiler ensures that the
|
|||
|
stack slot is properly initialized by making the replacement in
|
|||
|
the initial copy instruction as well. This is used on machines
|
|||
|
for which the calling convention allocates stack space for
|
|||
|
register parameters. See `REG_PARM_STACK_SPACE' in *Note Stack
|
|||
|
Arguments::.
|
|||
|
|
|||
|
In the case of `REG_EQUAL', the register that is set by this insn
|
|||
|
will be equal to OP at run time at the end of this insn but not
|
|||
|
necessarily elsewhere in the function. In this case, OP is
|
|||
|
typically an arithmetic expression. For example, when a sequence
|
|||
|
of insns such as a library call is used to perform an arithmetic
|
|||
|
operation, this kind of note is attached to the insn that produces
|
|||
|
or copies the final value.
|
|||
|
|
|||
|
These two notes are used in different ways by the compiler passes.
|
|||
|
`REG_EQUAL' is used by passes prior to register allocation (such as
|
|||
|
common subexpression elimination and loop optimization) to tell
|
|||
|
them how to think of that value. `REG_EQUIV' notes are used by
|
|||
|
register allocation to indicate that there is an available
|
|||
|
substitute expression (either a constant or a `mem' expression for
|
|||
|
the location of a parameter on the stack) that may be used in
|
|||
|
place of a register if insufficient registers are available.
|
|||
|
|
|||
|
Except for stack homes for parameters, which are indicated by a
|
|||
|
`REG_EQUIV' note and are not useful to the early optimization
|
|||
|
passes and pseudo registers that are equivalent to a memory
|
|||
|
location throughout there entire life, which is not detected until
|
|||
|
later in the compilation, all equivalences are initially indicated
|
|||
|
by an attached `REG_EQUAL' note. In the early stages of register
|
|||
|
allocation, a `REG_EQUAL' note is changed into a `REG_EQUIV' note
|
|||
|
if OP is a constant and the insn represents the only set of its
|
|||
|
destination register.
|
|||
|
|
|||
|
Thus, compiler passes prior to register allocation need only check
|
|||
|
for `REG_EQUAL' notes and passes subsequent to register allocation
|
|||
|
need only check for `REG_EQUIV' notes.
|
|||
|
|
|||
|
`REG_UNUSED'
|
|||
|
The register OP being set by this insn will not be used in a
|
|||
|
subsequent insn. This differs from a `REG_DEAD' note, which
|
|||
|
indicates that the value in an input will not be used subsequently.
|
|||
|
These two notes are independent; both may be present for the same
|
|||
|
register.
|
|||
|
|
|||
|
`REG_WAS_0'
|
|||
|
The single output of this insn contained zero before this insn.
|
|||
|
OP is the insn that set it to zero. You can rely on this note if
|
|||
|
it is present and OP has not been deleted or turned into a `note';
|
|||
|
its absence implies nothing.
|
|||
|
|
|||
|
These notes describe linkages between insns. They occur in pairs:
|
|||
|
one insn has one of a pair of notes that points to a second insn, which
|
|||
|
has the inverse note pointing back to the first insn.
|
|||
|
|
|||
|
`REG_RETVAL'
|
|||
|
This insn copies the value of a multi-insn sequence (for example, a
|
|||
|
library call), and OP is the first insn of the sequence (for a
|
|||
|
library call, the first insn that was generated to set up the
|
|||
|
arguments for the library call).
|
|||
|
|
|||
|
Loop optimization uses this note to treat such a sequence as a
|
|||
|
single operation for code motion purposes and flow analysis uses
|
|||
|
this note to delete such sequences whose results are dead.
|
|||
|
|
|||
|
A `REG_EQUAL' note will also usually be attached to this insn to
|
|||
|
provide the expression being computed by the sequence.
|
|||
|
|
|||
|
`REG_LIBCALL'
|
|||
|
This is the inverse of `REG_RETVAL': it is placed on the first
|
|||
|
insn of a multi-insn sequence, and it points to the last one.
|
|||
|
|
|||
|
`REG_CC_SETTER'
|
|||
|
`REG_CC_USER'
|
|||
|
On machines that use `cc0', the insns which set and use `cc0' set
|
|||
|
and use `cc0' are adjacent. However, when branch delay slot
|
|||
|
filling is done, this may no longer be true. In this case a
|
|||
|
`REG_CC_USER' note will be placed on the insn setting `cc0' to
|
|||
|
point to the insn using `cc0' and a `REG_CC_SETTER' note will be
|
|||
|
placed on the insn using `cc0' to point to the insn setting `cc0'.
|
|||
|
|
|||
|
These values are only used in the `LOG_LINKS' field, and indicate
|
|||
|
the type of dependency that each link represents. Links which indicate
|
|||
|
a data dependence (a read after write dependence) do not use any code,
|
|||
|
they simply have mode `VOIDmode', and are printed without any
|
|||
|
descriptive text.
|
|||
|
|
|||
|
`REG_DEP_ANTI'
|
|||
|
This indicates an anti dependence (a write after read dependence).
|
|||
|
|
|||
|
`REG_DEP_OUTPUT'
|
|||
|
This indicates an output dependence (a write after write
|
|||
|
dependence).
|
|||
|
|
|||
|
These notes describe information gathered from gcov profile data.
|
|||
|
They are stored in the `REG_NOTES' field of an insn as an `expr_list'.
|
|||
|
|
|||
|
`REG_EXEC_COUNT'
|
|||
|
This is used to indicate the number of times a basic block was
|
|||
|
executed according to the profile data. The note is attached to
|
|||
|
the first insn in the basic block.
|
|||
|
|
|||
|
`REG_BR_PROB'
|
|||
|
This is used to specify the ratio of branches to non-branches of a
|
|||
|
branch insn according to the profile data. The value is stored as
|
|||
|
a value between 0 and REG_BR_PROB_BASE; larger values indicate a
|
|||
|
higher probability that the branch will be taken.
|
|||
|
|
|||
|
For convenience, the machine mode in an `insn_list' or `expr_list'
|
|||
|
is printed using these symbolic codes in debugging dumps.
|
|||
|
|
|||
|
The only difference between the expression codes `insn_list' and
|
|||
|
`expr_list' is that the first operand of an `insn_list' is assumed to
|
|||
|
be an insn and is printed in debugging dumps as the insn's unique id;
|
|||
|
the first operand of an `expr_list' is printed in the ordinary way as
|
|||
|
an expression.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Calls, Next: Sharing, Prev: Insns, Up: RTL
|
|||
|
|
|||
|
RTL Representation of Function-Call Insns
|
|||
|
=========================================
|
|||
|
|
|||
|
Insns that call subroutines have the RTL expression code `call_insn'.
|
|||
|
These insns must satisfy special rules, and their bodies must use a
|
|||
|
special RTL expression code, `call'.
|
|||
|
|
|||
|
A `call' expression has two operands, as follows:
|
|||
|
|
|||
|
(call (mem:FM ADDR) NBYTES)
|
|||
|
|
|||
|
Here NBYTES is an operand that represents the number of bytes of
|
|||
|
argument data being passed to the subroutine, FM is a machine mode
|
|||
|
(which must equal as the definition of the `FUNCTION_MODE' macro in the
|
|||
|
machine description) and ADDR represents the address of the subroutine.
|
|||
|
|
|||
|
For a subroutine that returns no value, the `call' expression as
|
|||
|
shown above is the entire body of the insn, except that the insn might
|
|||
|
also contain `use' or `clobber' expressions.
|
|||
|
|
|||
|
For a subroutine that returns a value whose mode is not `BLKmode',
|
|||
|
the value is returned in a hard register. If this register's number is
|
|||
|
R, then the body of the call insn looks like this:
|
|||
|
|
|||
|
(set (reg:M R)
|
|||
|
(call (mem:FM ADDR) NBYTES))
|
|||
|
|
|||
|
This RTL expression makes it clear (to the optimizer passes) that the
|
|||
|
appropriate register receives a useful value in this insn.
|
|||
|
|
|||
|
When a subroutine returns a `BLKmode' value, it is handled by
|
|||
|
passing to the subroutine the address of a place to store the value.
|
|||
|
So the call insn itself does not "return" any value, and it has the
|
|||
|
same RTL form as a call that returns nothing.
|
|||
|
|
|||
|
On some machines, the call instruction itself clobbers some register,
|
|||
|
for example to contain the return address. `call_insn' insns on these
|
|||
|
machines should have a body which is a `parallel' that contains both
|
|||
|
the `call' expression and `clobber' expressions that indicate which
|
|||
|
registers are destroyed. Similarly, if the call instruction requires
|
|||
|
some register other than the stack pointer that is not explicitly
|
|||
|
mentioned it its RTL, a `use' subexpression should mention that
|
|||
|
register.
|
|||
|
|
|||
|
Functions that are called are assumed to modify all registers listed
|
|||
|
in the configuration macro `CALL_USED_REGISTERS' (*note Register
|
|||
|
Basics::.) and, with the exception of `const' functions and library
|
|||
|
calls, to modify all of memory.
|
|||
|
|
|||
|
Insns containing just `use' expressions directly precede the
|
|||
|
`call_insn' insn to indicate which registers contain inputs to the
|
|||
|
function. Similarly, if registers other than those in
|
|||
|
`CALL_USED_REGISTERS' are clobbered by the called function, insns
|
|||
|
containing a single `clobber' follow immediately after the call to
|
|||
|
indicate which registers.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Sharing, Next: Reading RTL, Prev: Calls, Up: RTL
|
|||
|
|
|||
|
Structure Sharing Assumptions
|
|||
|
=============================
|
|||
|
|
|||
|
The compiler assumes that certain kinds of RTL expressions are
|
|||
|
unique; there do not exist two distinct objects representing the same
|
|||
|
value. In other cases, it makes an opposite assumption: that no RTL
|
|||
|
expression object of a certain kind appears in more than one place in
|
|||
|
the containing structure.
|
|||
|
|
|||
|
These assumptions refer to a single function; except for the RTL
|
|||
|
objects that describe global variables and external functions, and a
|
|||
|
few standard objects such as small integer constants, no RTL objects
|
|||
|
are common to two functions.
|
|||
|
|
|||
|
* Each pseudo-register has only a single `reg' object to represent
|
|||
|
it, and therefore only a single machine mode.
|
|||
|
|
|||
|
* For any symbolic label, there is only one `symbol_ref' object
|
|||
|
referring to it.
|
|||
|
|
|||
|
* There is only one `const_int' expression with value 0, only one
|
|||
|
with value 1, and only one with value -1. Some other integer
|
|||
|
values are also stored uniquely.
|
|||
|
|
|||
|
* There is only one `pc' expression.
|
|||
|
|
|||
|
* There is only one `cc0' expression.
|
|||
|
|
|||
|
* There is only one `const_double' expression with value 0 for each
|
|||
|
floating point mode. Likewise for values 1 and 2.
|
|||
|
|
|||
|
* No `label_ref' or `scratch' appears in more than one place in the
|
|||
|
RTL structure; in other words, it is safe to do a tree-walk of all
|
|||
|
the insns in the function and assume that each time a `label_ref'
|
|||
|
or `scratch' is seen it is distinct from all others that are seen.
|
|||
|
|
|||
|
* Only one `mem' object is normally created for each static variable
|
|||
|
or stack slot, so these objects are frequently shared in all the
|
|||
|
places they appear. However, separate but equal objects for these
|
|||
|
variables are occasionally made.
|
|||
|
|
|||
|
* When a single `asm' statement has multiple output operands, a
|
|||
|
distinct `asm_operands' expression is made for each output operand.
|
|||
|
However, these all share the vector which contains the sequence of
|
|||
|
input operands. This sharing is used later on to test whether two
|
|||
|
`asm_operands' expressions come from the same statement, so all
|
|||
|
optimizations must carefully preserve the sharing if they copy the
|
|||
|
vector at all.
|
|||
|
|
|||
|
* No RTL object appears in more than one place in the RTL structure
|
|||
|
except as described above. Many passes of the compiler rely on
|
|||
|
this by assuming that they can modify RTL objects in place without
|
|||
|
unwanted side-effects on other insns.
|
|||
|
|
|||
|
* During initial RTL generation, shared structure is freely
|
|||
|
introduced. After all the RTL for a function has been generated,
|
|||
|
all shared structure is copied by `unshare_all_rtl' in
|
|||
|
`emit-rtl.c', after which the above rules are guaranteed to be
|
|||
|
followed.
|
|||
|
|
|||
|
* During the combiner pass, shared structure within an insn can exist
|
|||
|
temporarily. However, the shared structure is copied before the
|
|||
|
combiner is finished with the insn. This is done by calling
|
|||
|
`copy_rtx_if_shared', which is a subroutine of `unshare_all_rtl'.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Reading RTL, Prev: Sharing, Up: RTL
|
|||
|
|
|||
|
Reading RTL
|
|||
|
===========
|
|||
|
|
|||
|
To read an RTL object from a file, call `read_rtx'. It takes one
|
|||
|
argument, a stdio stream, and returns a single RTL object.
|
|||
|
|
|||
|
Reading RTL from a file is very slow. This is not currently a
|
|||
|
problem since reading RTL occurs only as part of building the compiler.
|
|||
|
|
|||
|
People frequently have the idea of using RTL stored as text in a
|
|||
|
file as an interface between a language front end and the bulk of GNU
|
|||
|
CC. This idea is not feasible.
|
|||
|
|
|||
|
GNU CC was designed to use RTL internally only. Correct RTL for a
|
|||
|
given program is very dependent on the particular target machine. And
|
|||
|
the RTL does not contain all the information about the program.
|
|||
|
|
|||
|
The proper way to interface GNU CC to a new language front end is
|
|||
|
with the "tree" data structure. There is no manual for this data
|
|||
|
structure, but it is described in the files `tree.h' and `tree.def'.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Machine Desc, Next: Target Macros, Prev: RTL, Up: Top
|
|||
|
|
|||
|
Machine Descriptions
|
|||
|
********************
|
|||
|
|
|||
|
A machine description has two parts: a file of instruction patterns
|
|||
|
(`.md' file) and a C header file of macro definitions.
|
|||
|
|
|||
|
The `.md' file for a target machine contains a pattern for each
|
|||
|
instruction that the target machine supports (or at least each
|
|||
|
instruction that is worth telling the compiler about). It may also
|
|||
|
contain comments. A semicolon causes the rest of the line to be a
|
|||
|
comment, unless the semicolon is inside a quoted string.
|
|||
|
|
|||
|
See the next chapter for information on the C header file.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Patterns:: How to write instruction patterns.
|
|||
|
* Example:: An explained example of a `define_insn' pattern.
|
|||
|
* RTL Template:: The RTL template defines what insns match a pattern.
|
|||
|
* Output Template:: The output template says how to make assembler code
|
|||
|
from such an insn.
|
|||
|
* Output Statement:: For more generality, write C code to output
|
|||
|
the assembler code.
|
|||
|
* Constraints:: When not all operands are general operands.
|
|||
|
* Standard Names:: Names mark patterns to use for code generation.
|
|||
|
* Pattern Ordering:: When the order of patterns makes a difference.
|
|||
|
* Dependent Patterns:: Having one pattern may make you need another.
|
|||
|
* Jump Patterns:: Special considerations for patterns for jump insns.
|
|||
|
* Insn Canonicalizations::Canonicalization of Instructions
|
|||
|
* Peephole Definitions::Defining machine-specific peephole optimizations.
|
|||
|
* Expander Definitions::Generating a sequence of several RTL insns
|
|||
|
for a standard operation.
|
|||
|
* Insn Splitting:: Splitting Instructions into Multiple Instructions
|
|||
|
* Insn Attributes:: Specifying the value of attributes for generated insns.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Patterns, Next: Example, Up: Machine Desc
|
|||
|
|
|||
|
Everything about Instruction Patterns
|
|||
|
=====================================
|
|||
|
|
|||
|
Each instruction pattern contains an incomplete RTL expression, with
|
|||
|
pieces to be filled in later, operand constraints that restrict how the
|
|||
|
pieces can be filled in, and an output pattern or C code to generate
|
|||
|
the assembler output, all wrapped up in a `define_insn' expression.
|
|||
|
|
|||
|
A `define_insn' is an RTL expression containing four or five
|
|||
|
operands:
|
|||
|
|
|||
|
1. An optional name. The presence of a name indicate that this
|
|||
|
instruction pattern can perform a certain standard job for the
|
|||
|
RTL-generation pass of the compiler. This pass knows certain
|
|||
|
names and will use the instruction patterns with those names, if
|
|||
|
the names are defined in the machine description.
|
|||
|
|
|||
|
The absence of a name is indicated by writing an empty string
|
|||
|
where the name should go. Nameless instruction patterns are never
|
|||
|
used for generating RTL code, but they may permit several simpler
|
|||
|
insns to be combined later on.
|
|||
|
|
|||
|
Names that are not thus known and used in RTL-generation have no
|
|||
|
effect; they are equivalent to no name at all.
|
|||
|
|
|||
|
2. The "RTL template" (*note RTL Template::.) is a vector of
|
|||
|
incomplete RTL expressions which show what the instruction should
|
|||
|
look like. It is incomplete because it may contain
|
|||
|
`match_operand', `match_operator', and `match_dup' expressions
|
|||
|
that stand for operands of the instruction.
|
|||
|
|
|||
|
If the vector has only one element, that element is the template
|
|||
|
for the instruction pattern. If the vector has multiple elements,
|
|||
|
then the instruction pattern is a `parallel' expression containing
|
|||
|
the elements described.
|
|||
|
|
|||
|
3. A condition. This is a string which contains a C expression that
|
|||
|
is the final test to decide whether an insn body matches this
|
|||
|
pattern.
|
|||
|
|
|||
|
For a named pattern, 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.
|
|||
|
|
|||
|
For nameless patterns, the condition is applied only when matching
|
|||
|
an individual insn, and only after the insn has matched the
|
|||
|
pattern's recognition template. The insn's operands may be found
|
|||
|
in the vector `operands'.
|
|||
|
|
|||
|
4. The "output template": a string that says how to output matching
|
|||
|
insns as assembler code. `%' in this string specifies where to
|
|||
|
substitute the value of an operand. *Note Output Template::.
|
|||
|
|
|||
|
When simple substitution isn't general enough, you can specify a
|
|||
|
piece of C code to compute the output. *Note Output Statement::.
|
|||
|
|
|||
|
5. Optionally, a vector containing the values of attributes for insns
|
|||
|
matching this pattern. *Note Insn Attributes::.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Example, Next: RTL Template, Prev: Patterns, Up: Machine Desc
|
|||
|
|
|||
|
Example of `define_insn'
|
|||
|
========================
|
|||
|
|
|||
|
Here is an actual example of an instruction pattern, for the
|
|||
|
68000/68020.
|
|||
|
|
|||
|
(define_insn "tstsi"
|
|||
|
[(set (cc0)
|
|||
|
(match_operand:SI 0 "general_operand" "rm"))]
|
|||
|
""
|
|||
|
"*
|
|||
|
{ if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
|
|||
|
return \"tstl %0\";
|
|||
|
return \"cmpl #0,%0\"; }")
|
|||
|
|
|||
|
This is an instruction that sets the condition codes based on the
|
|||
|
value of a general operand. It has no condition, so any insn whose RTL
|
|||
|
description has the form shown may be handled according to this
|
|||
|
pattern. The name `tstsi' means "test a `SImode' value" and tells the
|
|||
|
RTL generation pass that, when it is necessary to test such a value, an
|
|||
|
insn to do so can be constructed using this pattern.
|
|||
|
|
|||
|
The output control string is a piece of C code which chooses which
|
|||
|
output template to return based on the kind of operand and the specific
|
|||
|
type of CPU for which code is being generated.
|
|||
|
|
|||
|
`"rm"' is an operand constraint. Its meaning is explained below.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: RTL Template, Next: Output Template, Prev: Example, Up: Machine Desc
|
|||
|
|
|||
|
RTL Template
|
|||
|
============
|
|||
|
|
|||
|
The RTL template is used to define which insns match the particular
|
|||
|
pattern and how to find their operands. For named patterns, the RTL
|
|||
|
template also says how to construct an insn from specified operands.
|
|||
|
|
|||
|
Construction involves substituting specified operands into a copy of
|
|||
|
the template. Matching involves determining the values that serve as
|
|||
|
the operands in the insn being matched. Both of these activities are
|
|||
|
controlled by special expression types that direct matching and
|
|||
|
substitution of the operands.
|
|||
|
|
|||
|
`(match_operand:M N PREDICATE CONSTRAINT)'
|
|||
|
This expression is a placeholder for operand number N of the insn.
|
|||
|
When constructing an insn, operand number N will be substituted
|
|||
|
at this point. When matching an insn, whatever appears at this
|
|||
|
position in the insn will be taken as operand number N; but it
|
|||
|
must satisfy PREDICATE or this instruction pattern will not match
|
|||
|
at all.
|
|||
|
|
|||
|
Operand numbers must be chosen consecutively counting from zero in
|
|||
|
each instruction pattern. There may be only one `match_operand'
|
|||
|
expression in the pattern for each operand number. Usually
|
|||
|
operands are numbered in the order of appearance in `match_operand'
|
|||
|
expressions. In the case of a `define_expand', any operand numbers
|
|||
|
used only in `match_dup' expressions have higher values than all
|
|||
|
other operand numbers.
|
|||
|
|
|||
|
PREDICATE is a string that is the name of a C function that
|
|||
|
accepts two arguments, an expression and a machine mode. During
|
|||
|
matching, the function will be called with the putative operand as
|
|||
|
the expression and M as the mode argument (if M is not specified,
|
|||
|
`VOIDmode' will be used, which normally causes PREDICATE to accept
|
|||
|
any mode). If it returns zero, this instruction pattern fails to
|
|||
|
match. PREDICATE may be an empty string; then it means no test is
|
|||
|
to be done on the operand, so anything which occurs in this
|
|||
|
position is valid.
|
|||
|
|
|||
|
Most of the time, PREDICATE will reject modes other than M--but
|
|||
|
not always. For example, the predicate `address_operand' uses M
|
|||
|
as the mode of memory ref that the address should be valid for.
|
|||
|
Many predicates accept `const_int' nodes even though their mode is
|
|||
|
`VOIDmode'.
|
|||
|
|
|||
|
CONSTRAINT controls reloading and the choice of the best register
|
|||
|
class to use for a value, as explained later (*note
|
|||
|
Constraints::.).
|
|||
|
|
|||
|
People are often unclear on the difference between the constraint
|
|||
|
and the predicate. The predicate helps decide whether a given
|
|||
|
insn matches the pattern. The constraint plays no role in this
|
|||
|
decision; instead, it controls various decisions in the case of an
|
|||
|
insn which does match.
|
|||
|
|
|||
|
On CISC machines, the most common PREDICATE is
|
|||
|
`"general_operand"'. This function checks that the putative
|
|||
|
operand is either a constant, a register or a memory reference,
|
|||
|
and that it is valid for mode M.
|
|||
|
|
|||
|
For an operand that must be a register, PREDICATE should be
|
|||
|
`"register_operand"'. Using `"general_operand"' would be valid,
|
|||
|
since the reload pass would copy any non-register operands through
|
|||
|
registers, but this would make GNU CC do extra work, it would
|
|||
|
prevent invariant operands (such as constant) from being removed
|
|||
|
from loops, and it would prevent the register allocator from doing
|
|||
|
the best possible job. On RISC machines, it is usually most
|
|||
|
efficient to allow PREDICATE to accept only objects that the
|
|||
|
constraints allow.
|
|||
|
|
|||
|
For an operand that must be a constant, you must be sure to either
|
|||
|
use `"immediate_operand"' for PREDICATE, or make the instruction
|
|||
|
pattern's extra condition require a constant, or both. You cannot
|
|||
|
expect the constraints to do this work! If the constraints allow
|
|||
|
only constants, but the predicate allows something else, the
|
|||
|
compiler will crash when that case arises.
|
|||
|
|
|||
|
`(match_scratch:M N CONSTRAINT)'
|
|||
|
This expression is also a placeholder for operand number N and
|
|||
|
indicates that operand must be a `scratch' or `reg' expression.
|
|||
|
|
|||
|
When matching patterns, this is equivalent to
|
|||
|
|
|||
|
(match_operand:M N "scratch_operand" PRED)
|
|||
|
|
|||
|
but, when generating RTL, it produces a (`scratch':M) expression.
|
|||
|
|
|||
|
If the last few expressions in a `parallel' are `clobber'
|
|||
|
expressions whose operands are either a hard register or
|
|||
|
`match_scratch', the combiner can add or delete them when
|
|||
|
necessary. *Note Side Effects::.
|
|||
|
|
|||
|
`(match_dup N)'
|
|||
|
This expression is also a placeholder for operand number N. It is
|
|||
|
used when the operand needs to appear more than once in the insn.
|
|||
|
|
|||
|
In construction, `match_dup' acts just like `match_operand': the
|
|||
|
operand is substituted into the insn being constructed. But in
|
|||
|
matching, `match_dup' behaves differently. It assumes that operand
|
|||
|
number N has already been determined by a `match_operand'
|
|||
|
appearing earlier in the recognition template, and it matches only
|
|||
|
an identical-looking expression.
|
|||
|
|
|||
|
`(match_operator:M N PREDICATE [OPERANDS...])'
|
|||
|
This pattern is a kind of placeholder for a variable RTL expression
|
|||
|
code.
|
|||
|
|
|||
|
When constructing an insn, it stands for an RTL expression whose
|
|||
|
expression code is taken from that of operand N, and whose
|
|||
|
operands are constructed from the patterns OPERANDS.
|
|||
|
|
|||
|
When matching an expression, it matches an expression if the
|
|||
|
function PREDICATE returns nonzero on that expression *and* the
|
|||
|
patterns OPERANDS match the operands of the expression.
|
|||
|
|
|||
|
Suppose that the function `commutative_operator' is defined as
|
|||
|
follows, to match any expression whose operator is one of the
|
|||
|
commutative arithmetic operators of RTL and whose mode is MODE:
|
|||
|
|
|||
|
int
|
|||
|
commutative_operator (x, mode)
|
|||
|
rtx x;
|
|||
|
enum machine_mode mode;
|
|||
|
{
|
|||
|
enum rtx_code code = GET_CODE (x);
|
|||
|
if (GET_MODE (x) != mode)
|
|||
|
return 0;
|
|||
|
return (GET_RTX_CLASS (code) == 'c'
|
|||
|
|| code == EQ || code == NE);
|
|||
|
}
|
|||
|
|
|||
|
Then the following pattern will match any RTL expression consisting
|
|||
|
of a commutative operator applied to two general operands:
|
|||
|
|
|||
|
(match_operator:SI 3 "commutative_operator"
|
|||
|
[(match_operand:SI 1 "general_operand" "g")
|
|||
|
(match_operand:SI 2 "general_operand" "g")])
|
|||
|
|
|||
|
Here the vector `[OPERANDS...]' contains two patterns because the
|
|||
|
expressions to be matched all contain two operands.
|
|||
|
|
|||
|
When this pattern does match, the two operands of the commutative
|
|||
|
operator are recorded as operands 1 and 2 of the insn. (This is
|
|||
|
done by the two instances of `match_operand'.) Operand 3 of the
|
|||
|
insn will be the entire commutative expression: use `GET_CODE
|
|||
|
(operands[3])' to see which commutative operator was used.
|
|||
|
|
|||
|
The machine mode M of `match_operator' works like that of
|
|||
|
`match_operand': it is passed as the second argument to the
|
|||
|
predicate function, and that function is solely responsible for
|
|||
|
deciding whether the expression to be matched "has" that mode.
|
|||
|
|
|||
|
When constructing an insn, argument 3 of the gen-function will
|
|||
|
specify the operation (i.e. the expression code) for the
|
|||
|
expression to be made. It should be an RTL expression, whose
|
|||
|
expression code is copied into a new expression whose operands are
|
|||
|
arguments 1 and 2 of the gen-function. The subexpressions of
|
|||
|
argument 3 are not used; only its expression code matters.
|
|||
|
|
|||
|
When `match_operator' is used in a pattern for matching an insn,
|
|||
|
it usually best if the operand number of the `match_operator' is
|
|||
|
higher than that of the actual operands of the insn. This improves
|
|||
|
register allocation because the register allocator often looks at
|
|||
|
operands 1 and 2 of insns to see if it can do register tying.
|
|||
|
|
|||
|
There is no way to specify constraints in `match_operator'. The
|
|||
|
operand of the insn which corresponds to the `match_operator'
|
|||
|
never has any constraints because it is never reloaded as a whole.
|
|||
|
However, if parts of its OPERANDS are matched by `match_operand'
|
|||
|
patterns, those parts may have constraints of their own.
|
|||
|
|
|||
|
`(match_op_dup:M N[OPERANDS...])'
|
|||
|
Like `match_dup', except that it applies to operators instead of
|
|||
|
operands. When constructing an insn, operand number N will be
|
|||
|
substituted at this point. But in matching, `match_op_dup' behaves
|
|||
|
differently. It assumes that operand number N has already been
|
|||
|
determined by a `match_operator' appearing earlier in the
|
|||
|
recognition template, and it matches only an identical-looking
|
|||
|
expression.
|
|||
|
|
|||
|
`(match_parallel N PREDICATE [SUBPAT...])'
|
|||
|
This pattern is a placeholder for an insn that consists of a
|
|||
|
`parallel' expression with a variable number of elements. This
|
|||
|
expression should only appear at the top level of an insn pattern.
|
|||
|
|
|||
|
When constructing an insn, operand number N will be substituted at
|
|||
|
this point. When matching an insn, it matches if the body of the
|
|||
|
insn is a `parallel' expression with at least as many elements as
|
|||
|
the vector of SUBPAT expressions in the `match_parallel', if each
|
|||
|
SUBPAT matches the corresponding element of the `parallel', *and*
|
|||
|
the function PREDICATE returns nonzero on the `parallel' that is
|
|||
|
the body of the insn. It is the responsibility of the predicate
|
|||
|
to validate elements of the `parallel' beyond those listed in the
|
|||
|
`match_parallel'.
|
|||
|
|
|||
|
A typical use of `match_parallel' is to match load and store
|
|||
|
multiple expressions, which can contain a variable number of
|
|||
|
elements in a `parallel'. For example,
|
|||
|
|
|||
|
(define_insn ""
|
|||
|
[(match_parallel 0 "load_multiple_operation"
|
|||
|
[(set (match_operand:SI 1 "gpc_reg_operand" "=r")
|
|||
|
(match_operand:SI 2 "memory_operand" "m"))
|
|||
|
(use (reg:SI 179))
|
|||
|
(clobber (reg:SI 179))])]
|
|||
|
""
|
|||
|
"loadm 0,0,%1,%2")
|
|||
|
|
|||
|
This example comes from `a29k.md'. The function
|
|||
|
`load_multiple_operations' is defined in `a29k.c' and checks that
|
|||
|
subsequent elements in the `parallel' are the same as the `set' in
|
|||
|
the pattern, except that they are referencing subsequent registers
|
|||
|
and memory locations.
|
|||
|
|
|||
|
An insn that matches this pattern might look like:
|
|||
|
|
|||
|
(parallel
|
|||
|
[(set (reg:SI 20) (mem:SI (reg:SI 100)))
|
|||
|
(use (reg:SI 179))
|
|||
|
(clobber (reg:SI 179))
|
|||
|
(set (reg:SI 21)
|
|||
|
(mem:SI (plus:SI (reg:SI 100)
|
|||
|
(const_int 4))))
|
|||
|
(set (reg:SI 22)
|
|||
|
(mem:SI (plus:SI (reg:SI 100)
|
|||
|
(const_int 8))))])
|
|||
|
|
|||
|
`(match_par_dup N [SUBPAT...])'
|
|||
|
Like `match_op_dup', but for `match_parallel' instead of
|
|||
|
`match_operator'.
|
|||
|
|
|||
|
`(address (match_operand:M N "address_operand" ""))'
|
|||
|
This complex of expressions is a placeholder for an operand number
|
|||
|
N in a "load address" instruction: an operand which specifies a
|
|||
|
memory location in the usual way, but for which the actual operand
|
|||
|
value used is the address of the location, not the contents of the
|
|||
|
location.
|
|||
|
|
|||
|
`address' expressions never appear in RTL code, only in machine
|
|||
|
descriptions. And they are used only in machine descriptions that
|
|||
|
do not use the operand constraint feature. When operand
|
|||
|
constraints are in use, the letter `p' in the constraint serves
|
|||
|
this purpose.
|
|||
|
|
|||
|
M is the machine mode of the *memory location being addressed*,
|
|||
|
not the machine mode of the address itself. That mode is always
|
|||
|
the same on a given target machine (it is `Pmode', which normally
|
|||
|
is `SImode'), so there is no point in mentioning it; thus, no
|
|||
|
machine mode is written in the `address' expression. If some day
|
|||
|
support is added for machines in which addresses of different
|
|||
|
kinds of objects appear differently or are used differently (such
|
|||
|
as the PDP-10), different formats would perhaps need different
|
|||
|
machine modes and these modes might be written in the `address'
|
|||
|
expression.
|
|||
|
|