Category : C Source Code
Archive   : GCCTXT.ZIP
Filename : RTL.TXT

 
Output of file : RTL.TXT contained in archive : GCCTXT.ZIP







INTERNALS

































































1. RTL Representation

Most of the work of the compiler is done on an inter-
mediate representation called register transfer language.
In this language, the instructions to be output are
described, pretty much one by one, in an algebraic form that
describes what the instruction does.

RTL is inspired by Lisp lists. It has both an internal
form, made up of structures that point at other structures,
and a textual form that is used in the machine description
and in printed debugging dumps. The textual form uses
nested parentheses to indicate the pointers in the internal
form.



1.1. RTL Object Types

RTL uses four kinds of objects: expressions, integers,
strings and vectors. Expressions are the most important
ones. An RTL expression (``RTX'', for short) is a C struc-
ture, but it is usually referred to with a pointer; a type
that is given the typedef name rtx.

An integer is simply an int; their written form uses
decimal digits.

A string is a sequence of characters. In core it is
represented as a char * in usual C fashion, and it is writ-
ten in C syntax as well. However, strings in RTL may never
be null. If you write an empty string in a machine descrip-
tion, it is represented in core as a null pointer rather
than as a pointer to a null character. In certain contexts,
these null pointers instead of strings are valid. Within
RTL code, strings are most commonly found inside symbol_ref
expressions, but they appear in other contexts in the RTL
expressions that make up machine descriptions.

A vector contains an arbitrary number of pointers to
expressions. The number of elements in the vector is expli-
citly present in the vector. The written form of a vector
consists of square brackets (`[...]') surrounding the ele-
ments, in sequence and with whitespace separating them.
Vectors of length zero are not created; null pointers are
used instead.

Expressions are classified by expression codes (also
called RTX codes). The expression code is a name defined in
`rtl.def', which is also (in upper case) a C enumeration
constant. The possible expression codes and their meanings
are machine-independent. The code of an RTX can be
extracted with the macro GET_CODE (x) and altered with













PUT_CODE (x, newcode).

The expression code determines how many operands the
expression contains, and what kinds of objects they are. In
RTL, unlike Lisp, you cannot tell by looking at an operand
what kind of object it is. Instead, you must know from its
context---from the expression code of the containing expres-
sion. For example, in an expression of code subreg, the
first operand is to be regarded as an expression and the
second operand as an integer. In an expression of code
plus, there are two operands, both of which are to be
regarded as expressions. In a symbol_ref expression, there
is one operand, which is to be regarded as a string.

Expressions are written as parentheses containing the
name of the expression type, its flags and machine mode if
any, and then the operands of the expression (separated by
spaces).

Expression code names in the `md' file are written in
lower case, but when they appear in C code they are written
in upper case. In this manual, they are shown as follows:
const_int.

In a few contexts a null pointer is valid where an
expression is normally wanted. The written form of this is
(nil).

1.2. Access to Operands

For each expression type `rtl.def' specifies the number
of contained objects and their kinds, with four possibili-
ties: `e' for expression (actually a pointer to an expres-
sion), `i' for integer, `s' for string, and `E' for vector
of expressions. The sequence of letters for an expression
code is called its format. Thus, the format of subreg is
`ei'.

A few other format characters are used occasionally:

u `u' is equivalent to `e' except that it is printed
differently in debugging dumps. It is used for
pointers to insns.

n `n' is equivalent to `i' except that it is printed
differently in debugging dumps. It is used for
the line number or code number of a note insn.

S `S' indicates a string which is optional. In the
RTL objects in core, `S' is equivalent to `s', but
when the object is read, from an `md' file, the
string value of this operand may be omitted. An
omitted string is taken to be the null string.













V `V' indicates a vector which is optional. In the
RTL objects in core, `V' is equivalent to `E', but
when the object is read from an `md' file, the
vector value of this operand may be omitted. An
omitted vector is effectively the same as a vector
of no elements.

0 `0' means a slot whose contents do not fit any
normal category. `0' slots are not printed at all
in dumps, and are often used in special ways by
small parts of the compiler.


There are macros to get the number of operands, the
format, and the class of an expression code:

GET_RTX_LENGTH (code)
Number of operands of an RTX of code code.

GET_RTX_FORMAT (code)
The format of an RTX of code code, as a C string.

GET_RTX_CLASS (code)
A single character representing the type of RTX
operation that code code performs.

The following classes are defined:

o An RTX code that represents an actual object,
such as reg or mem. subreg is not in this
class.

< An RTX code for a comparison. The codes in
this class are NE, EQ, LE, LT, GE, GT, LEU,
LTU, GEU, GTU.

1 An RTX code for a unary arithmetic operation,
such as neg.

c An RTX code for a commutative binary opera-
tion, other than NE and EQ (which have class
`<').

2 An RTX code for a noncommutative binary
operation, such as MINUS.

b An RTX code for a bitfield operation
(ZERO_EXTRACT and SIGN_EXTRACT).

3 An RTX code for other three input operations,
such as IF_THEN_ELSE.















i An RTX code for a machine insn (INSN,
JUMP_INSN, and CALL_INSN).

m An RTX code for something that matches in
insns, such as MATCH_DUP.

x All other RTX codes.



Operands of expressions are accessed using the macros
XEXP, XINT and XSTR. Each of these macros takes two argu-
ments: an expression-pointer (RTX) and an operand number
(counting from zero). Thus,


XEXP (x, 2)



accesses operand 2 of expression x, as an expression.


XINT (x, 2)



accesses the same operand as an integer. XSTR, used in the
same fashion, would access it as a string.

Any operand can be accessed as an integer, as an
expression or as a string. You must choose the correct
method of access for the kind of value actually stored in
the operand. You would do this based on the expression code
of the containing expression. That is also how you would
know how many operands there are.

For example, if x is a subreg expression, you know that
it has two operands which can be correctly accessed as XEXP
(x, 0) and XINT (x, 1). If you did XINT (x, 0), you would
get the address of the expression operand but cast as an
integer; that might occasionally be useful, but it would be
cleaner to write (int) XEXP (x, 0). XEXP (x, 1) would also
compile without error, and would return the second, integer
operand cast as an expression pointer, which would probably
result in a crash when accessed. Nothing stops you from
writing XEXP (x, 28) either, but this will access memory
past the end of the expression with unpredictable results.

Access to operands which are vectors is more compli-
cated. You can use the macro XVEC to get the vector-pointer
itself, or the macros XVECEXP and XVECLEN to access the ele-
ments and length of a vector.













XVEC (exp, idx)
Access the vector-pointer which is operand number
idx in exp.

XVECLEN (exp, idx)
Access the length (number of elements) in the vec-
tor which is in operand number idx in exp. This
value is an int.

XVECEXP (exp, idx, eltnum)
Access element number eltnum in the vector which
is in operand number idx in exp. This value is an
RTX.

It is up to you to make sure that eltnum is not
negative and is less than XVECLEN (exp, idx).


All the macros defined in this section expand into
lvalues and therefore can be used to assign the operands,
lengths and vector elements as well as to access them.

1.3. Flags in an RTL Expression

RTL expressions contain several flags (one-bit bit-
fields) that are used in certain types of expression. Most
often they are accessed with the following macros:

MEM_VOLATILE_P (x)
In mem expressions, nonzero for volatile memory
references. Stored in the volatil field and
printed as `/v'.

MEM_IN_STRUCT_P (x)
In mem expressions, nonzero for reference to an
entire structure, union or array, or to a com-
ponent of one. Zero for references to a scalar
variable or through a pointer to a scalar. Stored
in the in_struct field and printed as `/s'.

REG_LOOP_TEST_P
In reg expressions, nonzero if this register's en-
tire life is contained in the exit test code for
some loop. Stored in the in_struct field and
printed as `/s'.

REG_USERVAR_P (x)
In a reg, nonzero if it corresponds to a variable
present in the user's source code. Zero for tem-
poraries generated internally by the compiler.
Stored in the volatil field and printed as `/v'.















REG_FUNCTION_VALUE_P (x)
Nonzero in a reg if it is the place in which this
function's value is going to be returned. (This
happens only in a hard register.) Stored in the
integrated field and printed as `/i'.

The same hard register may be used also for col-
lecting the values of functions called by this
one, but REG_FUNCTION_VALUE_P is zero in this kind
of use.

RTX_UNCHANGING_P (x)
Nonzero in a reg or mem if the value is not
changed. (This flag is not set for memory refer-
ences via pointers to constants. Such pointers
only guarantee that the object will not be changed
explicitly by the current function. The object
might be changed by other functions or by alias-
ing.) Stored in the unchanging field and printed
as `/u'.

RTX_INTEGRATED_P (insn)
Nonzero in an insn if it resulted from an in-line
function call. Stored in the integrated field and
printed as `/i'. This may be deleted; nothing
currently depends on it.

SYMBOL_REF_USED (x)
In a symbol_ref, indicates that x has been used.
This is normally only used to ensure that x is
only declared external once. Stored in the used
field.

SYMBOL_REF_FLAG (x)
In a symbol_ref, this is used as a flag for
machine-specific purposes. Stored in the volatil
field and printed as `/v'.

LABEL_OUTSIDE_LOOP_P
In label_ref expressions, nonzero if this is a
reference to a label that is outside the innermost
loop containing the reference to the label.
Stored in the in_struct field and printed as `/s'.

INSN_DELETED_P (insn)
In an insn, nonzero if the insn has been deleted.
Stored in the volatil field and printed as `/v'.

INSN_ANNULLED_BRANCH_P (insn)
In an insn in the delay slot of a branch insn, in-
dicates that an annulling branch should be used.
See the discussion under sequence below. Stored
in the unchanging field and printed as `/u'.













INSN_FROM_TARGET_P (insn)
In an insn in a delay slot of a branch, indicates
that the insn is from the target of the branch.
If the branch insn has INSN_ANNULLED_BRANCH_P set,
this insn should only be executed if the branch is
taken. For annulled branches with this bit clear,
the insn should be executed only if the branch is
not taken. Stored in the in_struct field and
printed as `/s'.

CONSTANT_POOL_ADDRESS_P (x)
Nonzero in a symbol_ref if it refers to part of
the current function's ``constants pool''. These
are addresses close to the beginning of the func-
tion, and GNU CC assumes they can be addressed
directly (perhaps with the help of base regis-
ters). Stored in the unchanging field and printed
as `/u'.

CONST_CALL_P (x)
In a call_insn, indicates that the insn represents
a call to a const function. Stored in the un-
changing field and printed as `/u'.

LABEL_PRESERVE_P (x)
In a code_label, indicates that the label can nev-
er be deleted. Labels referenced by a a non-local
goto will have this bit set. Stored in the
in_struct field and printed as `/s'.

SCHED_GROUP_P (insn)
During instruction scheduling, in an insn, indi-
cates that the previous insn must be scheduled to-
gether with this insn. This is used to ensure
that certain groups of instructions will not be
split up by the instruction scheduling pass, for
example, use insns before a call_insn may not be
separated from the call_insn. Stored in the
in_struct field and printed as `/s'.


These are the fields which the above macros refer to:

used
Normally, this flag is used only momentarily, at
the end of RTL generation for a function, to count
the number of times an expression appears in
insns. Expressions that appear more than once are
copied, according to the rules for shared struc-
ture (see section Sharing).

In a symbol_ref, it indicates that an external de-
claration for the symbol has already been written.













In a reg, it is used by the leaf register
renumbering code to ensure that each register is
only renumbered once.

volatil
This flag is used in mem,symbol_ref and reg ex-
pressions and in insns. In RTL dump files, it is
printed as `/v'.

In a mem expression, it is 1 if the memory refer-
ence is volatile. Volatile memory references may
not be deleted, reordered or combined.

In a symbol_ref expression, it is used for
machine-specific purposes.

In a reg expression, it is 1 if the value is a
user-level variable. 0 indicates an internal com-
piler temporary.

In an insn, 1 means the insn has been deleted.

in_struct
In mem expressions, it is 1 if the memory datum
referred to is all or part of a structure or ar-
ray; 0 if it is (or might be) a scalar variable.
A reference through a C pointer has 0 because the
pointer might point to a scalar variable. This
information allows the compiler to determine some-
thing about possible cases of aliasing.

In an insn in the delay slot of a branch, 1 means
that this insn is from the target of the branch.

During instruction scheduling, in an insn, 1 means
that this insn must be scheduled as part of a
group together with the previous insn.

In reg expressions, it is 1 if the register has
its entire life contained within the test expres-
sion of some loopl.

In label_ref expressions, 1 means that the refer-
enced label is outside the innermost loop contain-
ing the insn in which the label_ref was found.

In code_label expressions, it is 1 if the label
may never be deleted. This is used for labels
which are the target of non-local gotos.

In an RTL dump, this flag is represented as `/s'.















unchanging
In reg and mem expressions, 1 means that the value
of the expression never changes.

In an insn, 1 means that this is an annulling
branch.

In a symbol_ref expression, 1 means that this sym-
bol addresses something in the per-function con-
stants pool.

In a call_insn, 1 means that this instruction is a
call to a const function.

In an RTL dump, this flag is represented as `/u'.

integrated
In some kinds of expressions, including insns,
this flag means the rtl was produced by procedure
integration.

In a reg expression, this flag indicates the re-
gister containing the value to be returned by the
current function. On machines that pass parame-
ters in registers, the same register number may be
used for parameters as well, but this flag is not
set on such uses.


1.4. Machine Modes

A machine mode describes a size of data object and the
representation used for it. In the C code, machine modes
are represented by an enumeration type, enum machine_mode,
defined in `machmode.def'. Each RTL expression has room for
a machine mode and so do certain kinds of tree expressions
(declarations and types, to be precise).

In debugging dumps and machine descriptions, the
machine mode of an RTL expression is written after the
expression code with a colon to separate them. The letters
`mode' which appear at the end of each machine mode name are
omitted. For example, (reg:SI 38) is a reg expression with
machine mode SImode. If the mode is VOIDmode, it is not
written at all.

Here is a table of machine modes. The term ``byte''
below refers to an object of BITS_PER_UNIT bits (see section
Storage Layout).

QImode
``Quarter-Integer'' mode represents a single byte
treated as an integer.













HImode
``Half-Integer'' mode represents a two-byte in-
teger.

PSImode
``Partial Single Integer'' mode represents an in-
teger which occupies four bytes but which doesn't
really use all four. On some machines, this is
the right mode to use for pointers.

SImode
``Single Integer'' mode represents a four-byte in-
teger.

PDImode
``Partial Double Integer'' mode represents an in-
teger which occupies eight bytes but which doesn't
really use all eight. On some machines, this is
the right mode to use for certain pointers.

DImode
``Double Integer'' mode represents an eight-byte
integer.

TImode
``Tetra Integer'' (?) mode represents a sixteen-
byte integer.

SFmode
``Single Floating'' mode represents a single-
precision (four byte) floating point number.

DFmode
``Double Floating'' mode represents a double-
precision (eight byte) floating point number.

XFmode
``Extended Floating'' mode represents a triple-
precision (twelve byte) floating point number.
This mode is used for IEEE extended floating
point.

TFmode
``Tetra Floating'' mode represents a quadruple-
precision (sixteen byte) floating point number.

CCmode
``Condition Code'' mode represents the value of a
condition code, which is a machine-specific set of
bits used to represent the result of a comparison
operation. Other machine-specific modes may also
be used for the condition code. These modes are
not used on machines that use cc0 (see see section













Condition Code).

BLKmode
``Block'' mode represents values that are aggre-
gates to which none of the other modes apply. In
RTL, only memory references can have this mode,
and only if they appear in string-move or vector
instructions. On machines which have no such in-
structions, BLKmode will not appear in RTL.

VOIDmode
Void mode means the absence of a mode or an un-
specified mode. For example, RTL expressions of
code const_int have mode VOIDmode because they can
be taken to have whatever mode the context re-
quires. In debugging dumps of RTL, VOIDmode is
expressed by the absence of any mode.

SCmode, DCmode, XCmode, TCmode
These modes stand for a complex number represented
as a pair of floating point values. The values
are in SFmode, DFmode, XFmode, and TFmode, respec-
tively. Since C does not support complex numbers,
these machine modes are only partially implement-
ed.


The machine description defines Pmode as a C macro
which expands into the machine mode used for addresses.
Normally this is the mode whose size is BITS_PER_WORD,
SImode on 32-bit machines.

The only modes which a machine description must support
are QImode, and the modes corresponding to BITS_PER_WORD,
FLOAT_TYPE_SIZE and DOUBLE_TYPE_SIZE. The compiler will
attempt to use DImode for 8-byte structures and unions, but
this can be prevented by overriding the definition of
MAX_FIXED_MODE_SIZE. Alternatively, you can have the com-
piler use TImode for 16-byte structures and unions. Like-
wise, you can arrange for the C type short int to avoid
using HImode.

Very few explicit references to machine modes remain in
the compiler and these few references will soon be removed.
Instead, the machine modes are divided into mode classes.
These are represented by the enumeration type enum
mode_class defined in `machmode.h'. The possible mode
classes are:

MODE_INT
Integer modes. By default these are QImode,
HImode, SImode, DImode, and TImode.














MODE_PARTIAL_INT
The ``partial integer'' modes, PSImode and PDI-
mode.

MODE_FLOAT
floating point modes. By default these are
SFmode, DFmode, XFmode and TFmode.

MODE_COMPLEX_INT
Complex integer modes. (These are not currently
implemented).

MODE_COMPLEX_FLOAT
Complex floating point modes. By default these
are SCmode, DCmode, XCmode, and TCmode.

MODE_FUNCTION
Algol or Pascal function variables including a
static chain. (These are not currently implement-
ed).

MODE_CC
Modes representing condition code values. These
are CCmode plus any modes listed in the
EXTRA_CC_MODES macro. See section Jump Patterns,
also see `Condition Code'.

MODE_RANDOM
This is a catchall mode class for modes which
don't fit into the above classes. Currently VOID-
mode and BLKmode are in MODE_RANDOM.


Here are some C macros that relate to machine modes:

GET_MODE (x)
Returns the machine mode of the RTX x.

PUT_MODE (x, newmode)
Alters the machine mode of the RTX x to be
newmode.

NUM_MACHINE_MODES
Stands for the number of machine modes available
on the target machine. This is one greater than
the largest numeric value of any machine mode.

GET_MODE_NAME (m)
Returns the name of mode m as a string.

GET_MODE_CLASS (m)
Returns the mode class of mode m.














GET_MODE_WIDER_MODE (m)
Returns the next wider natural mode. E.g.,
GET_WIDER_MODE(QImode) returns HImode.

GET_MODE_SIZE (m)
Returns the size in bytes of a datum of mode m.

GET_MODE_BITSIZE (m)
Returns the size in bits of a datum of mode m.

GET_MODE_MASK (m)
Returns a bitmask containing 1 for all bits in a
word that fit within mode m. This macro can only
be used for modes whose bitsize is less than or
equal to HOST_BITS_PER_INT.

GET_MODE_ALIGNMENT (m))
Return the required alignment, in bits, for an ob-
ject of mode m.

GET_MODE_UNIT_SIZE (m)
Returns the size in bytes of the subunits of a da-
tum of mode m. This is the same as GET_MODE_SIZE
except in the case of complex modes. For them,
the unit size is the size of the real or imaginary
part.

GET_MODE_NUNITS (m)
Returns the number of units contained in a mode,
i.e., GET_MODE_SIZE divided by GET_MODE_UNIT_SIZE.

GET_CLASS_NARROWEST_MODE (c)
Returns the narrowest mode in mode class c.


The global variables byte_mode and word_mode contain
modes whose classes are MODE_INT and whose bitsizes are
BITS_PER_UNIT or BITS_PER_WORD, respectively. On 32-bit
machines, these are QImode and SImode, respectively.

1.5. Constant Expression Types

The simplest RTL expressions are those that represent
constant values.

(const_int i)
This type of expression represents the integer
value i. i is customarily accessed with the macro
INTVAL as in INTVAL (exp), which is equivalent to
XINT (exp, 0).

Keep in mind that the result of INTVAL is an in-
teger on the host machine. If the host machine













has more bits in an int than the target machine
has in the mode in which the constant will be
used, then some of the bits you get from INTVAL
will be superfluous. In many cases, for proper
results, you must carefully disregard the values
of those bits.

There is only one expression object for the in-
teger value zero; it is the value of the variable
const0_rtx. Likewise, the only expression for in-
teger value one is found in const1_rtx, the only
expression for integer value two is found in
const2_rtx, and the only expression for integer
value negative one is found in constm1_rtx. Any
attempt to create an expression of code const_int
and value zero, one, two or negative one will re-
turn const0_rtx, const1_rtx, const2_rtx or
constm1_rtx as appropriate.

Similarly, there is only one object for the in-
teger whose value is STORE_FLAG_VALUE. It is
found in const_true_rtx. If STORE_FLAG_VALUE is
one, const_true_rtx and const1_rtx will point to
the same object. If STORE_FLAG_VALUE is -1,
const_true_rtx and constm1_rtx will point to the
same object.

(const_double:m addr i0 i1 ...)
Represents either a floating-point constant of
mode m or an integer constant that is too large to
fit into HOST_BITS_PER_INT bits but small enough
to fit within twice that number of bits (GNU CC
does not provide a mechanism to represent even
larger constants). In the latter case, m will be
VOIDmode.

addr is used to contain the mem expression that
corresponds to the location in memory that at
which the constant can be found. If it has not
been allocated a memory location, but is on the
chain of all const_double expressions in this com-
pilation (maintained using an undisplayed field),
addr contains const0_rtx. If it is not on the
chain, addr contains cc0_rtx. addr is customarily
accessed with the macro CONST_DOUBLE_MEM and the
chain field via CONST_DOUBLE_CHAIN.

If m is VOIDmode, the bit of the value are stored
in i0 and i1. i0 is customarily accessed with the
macro CONST_DOUBLE_LOW and i1 with
CONST_DOUBLE_HIGH.















If the constant is floating point (either single
or double precision), then the number of integers
used to store the value depends on the size of
REAL_VALUE_TYPE (see section Cross-compilation).
The integers represent a double. To convert them
to a double, do


union real_extract u;
bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);



and then refer to u.d.

The macro CONST0_RTX (mode) refers to an ex-
pression with value 0 in mode mode. If mode
mode is of mode class MODE_INT, it returns
const0_rtx. Otherwise, it returns a
CONST_DOUBLE expression in mode mode. Simi-
larly, the macro CONST1_RTX (mode) refers to
an expression with value 1 in mode mode and
similarly for CONST2_RTX.

(const_string str)
Represents a constant string with value str.
Currently this is used only for insn attri-
butes (see section Insn Attributes) since
constant strings in C are placed in memory.

(symbol_ref symbol)
Represents the value of an assembler label for
data. symbol is a string that describes the
name of the assembler label. If it starts
with a `*', the label is the rest of symbol
not including the `*'. Otherwise, the label
is symbol, usually prefixed with `_'.

(label_ref label)
Represents the value of an assembler label for
code. It contains one operand, an expression,
which must be a code_label that appears in the
instruction sequence to identify the place
where the label should go.

The reason for using a distinct expression
type for code label references is so that jump
optimization can distinguish them.

(const:m exp)
Represents a constant that is the result of an
assembly-time arithmetic computation. The
operand, exp, is an expression that contains













only constants (const_int, symbol_ref and
label_ref expressions) combined with plus and
minus. However, not all combinations are
valid, since the assembler cannot do arbitrary
arithmetic on relocatable symbols.

m should be Pmode.

(high:m exp)
Represents the high-order bits of exp, usually
a symbol_ref. The number of bits is machine-
dependent and is normally the number of bits
specified in an instruction that initializes
the high order bits of a register. It is used
with lo_sum to represent the typical two-
instruction sequence used in RISC machines to
reference a global memory location.

m should be Pmode.


1.6. Registers and Memory

Here are the RTL expression types for describing access
to machine registers and to main memory.

(reg:m n)
For small values of the integer n (less than
FIRST_PSEUDO_REGISTER), this stands for a refer-
ence to machine register number n: a hard regis-
ter. For larger values of n, it stands for a tem-
porary value or pseudo register. The compiler's
strategy is to generate code assuming an unlimited
number of such pseudo registers, and later convert
them into hard registers or into memory refer-
ences.

m is the machine mode of the reference. It is
necessary because machines can generally refer to
each register in more than one mode. For example,
a register may contain a full word but there may
be instructions to refer to it as a half word or
as a single byte, as well as instructions to refer
to it as a floating point number of various preci-
sions.

Even for a register that the machine can access in
only one mode, the mode must always be specified.

The symbol FIRST_PSEUDO_REGISTER is defined by the
machine description, since the number of hard re-
gisters on the machine is an invariant charac-
teristic of the machine. Note, however, that not













all of the machine registers must be general re-
gisters. All the machine registers that can be
used for storage of data are given hard register
numbers, even those that can be used only in cer-
tain instructions or can hold only certain types
of data.

A hard register may be accessed in various modes
throughout one function, but each pseudo register
is given a natural mode and is accessed only in
that mode. When it is necessary to describe an
access to a pseudo register using a nonnatural
mode, a subreg expression is used.

A reg expression with a machine mode that speci-
fies more than one word of data may actually stand
for several consecutive registers. If in addition
the register number specifies a hardware register,
then it actually represents several consecutive
hardware registers starting with the specified
one.

Each pseudo register number used in a function's
RTL code is represented by a unique reg expres-
sion.

Some pseudo register numbers, those within the
range of FIRST_VIRTUAL_REGISTER to
LAST_VIRTUAL_REGISTER only appear during the RTL
generation phase and are eliminated before the op-
timization phases. These represent locations in
the stack frame that cannot be determined until
RTL generation for the function has been complet-
ed. The following virtual register numbers are
defined:

VIRTUAL_INCOMING_ARGS_REGNUM
This points to the first word of the incoming
arguments passed on the stack. Normally
these arguments are placed there by the call-
er, but the callee may have pushed some argu-
ments that were previously passed in regis-
ters.

When RTL generation is complete, this virtual
register is replaced by the sum of the regis-
ter given by ARG_POINTER_REGNUM and the value
of FIRST_PARM_OFFSET.

VIRTUAL_STACK_VARS_REGNUM
If FRAME_GROWS_DOWNWARDS is defined, this
points to immediately above the first vari-
able on the stack. Otherwise, it points to













the first variable on the stack.

It is replaced with the sum of the register
given by FRAME_POINTER_REGNUM and the value
STARTING_FRAME_OFFSET.

VIRTUAL_STACK_DYNAMIC_REGNUM
This points to the location of dynamically
allocated memory on the stack immediately
after the stack pointer has been adjusted by
the amount of memory desired.

It is replaced by the sum of the register
given by STACK_POINTER_REGNUM and the value
STACK_DYNAMIC_OFFSET.

VIRTUAL_OUTGOING_ARGS_REGNUM
This points to the location in the stack at
which outgoing arguments should be written
when the stack is pre-pushed (arguments
pushed using push insns should always use
STACK_POINTER_REGNUM).

It is replaced by the sum of the register
given by STACK_POINTER_REGNUM and the value
STACK_POINTER_OFFSET.


(subreg:m reg wordnum)
subreg expressions are used to refer to a register
in a machine mode other than its natural one, or
to refer to one register of a multi-word reg that
actually refers to several registers.

Each pseudo-register has a natural mode. If it is
necessary to operate on it in a different mode---
for example, to perform a fullword move instruc-
tion on a pseudo-register that contains a single
byte---the pseudo-register must be enclosed in a
subreg. In such a case, wordnum is zero.

Usually m is at least as narrow as the mode of
reg, in which case it is restricting consideration
to only the bits of reg that are in m. However,
sometimes m is wider than the mode of reg. These
subreg expressions are often called paradoxical.
They are used in cases where we want to refer to
an object in a wider mode but do not care what
value the additional bits have. The reload pass
ensures that paradoxical references are only made
to hard registers.















The other use of subreg is to extract the indivi-
dual registers of a multi-register value. Machine
modes such as DImode and TImode can indicate
values longer than a word, values which usually
require two or more consecutive registers. To ac-
cess one of the registers, use a subreg with mode
SImode and a wordnum that says which register.

The compilation parameter WORDS_BIG_ENDIAN, if set
to 1, says that word number zero is the most sig-
nificant part; otherwise, it is the least signifi-
cant part.

Between the combiner pass and the reload pass, it
is possible to have a paradoxical subreg which
contains a mem instead of a reg as its first
operand. After the reload pass, it is also possi-
ble to have a non-paradoxical subreg which con-
tains a mem; this usually occurs when the mem is a
stack slot which replaced a pseudo register.

Note that it is not valid to access a DFmode value
in SFmode using a subreg. On some machines the
most significant part of a DFmode value does not
have the same format as a single-precision float-
ing value.

It is also not valid to access a single word of a
multi-word value in a hard register when less re-
gisters can hold the value than would be expected
from its size. For example, some 32-bit machines
have floating-point registers that can hold an en-
tire DFmode value. If register 10 were such a re-
gister (subreg:SI (reg:DF 10) 1) would be invalid
because there is no way to convert that reference
to a single machine register. The reload pass
prevents subreg expressions such as these from be-
ing formed.

The first operand of a subreg expression is cus-
tomarily accessed with the SUBREG_REG macro and
the second operand is customarily accessed with
the SUBREG_WORD macro.

(scratch:m)
This represents a scratch register that will be
required for the execution of a single instruction
and not used subsequently. It is converted into a
reg by either the local register allocator or the
reload pass.

scratch is usually present inside a clobber opera-
tion (see section Side Effects).













(cc0)
This refers to the machine's condition code regis-
ter. It has no operands and may not have a
machine mode. There are two ways to use it:

o+ To stand for a complete set of condition code
flags. This is best on most machines, where
each comparison sets the entire series of
flags.

With this technique, (cc0) may be validly
used in only two contexts: as the destination
of an assignment (in test and compare in-
structions) and in comparison operators com-
paring against zero (const_int with value
zero; that is to say, const0_rtx).

o+ To stand for a single flag that is the result
of a single condition. This is useful on
machines that have only a single flag bit,
and in which comparison instructions must
specify the condition to test.

With this technique, (cc0) may be validly
used in only two contexts: as the destination
of an assignment (in test and compare in-
structions) where the source is a comparison
operator, and as the first operand of
if_then_else (in a conditional branch).


There is only one expression object of code cc0;
it is the value of the variable cc0_rtx. Any at-
tempt to create an expression of code cc0 will re-
turn cc0_rtx.

Instructions can set the condition code implicit-
ly. On many machines, nearly all instructions set
the condition code based on the value that they
compute or store. It is not necessary to record
these actions explicitly in the RTL because the
machine description includes a prescription for
recognizing the instructions that do so (by means
of the macro NOTICE_UPDATE_CC). See section Con-
dition Code. Only instructions whose sole purpose
is to set the condition code, and instructions
that use the condition code, need mention (cc0).

On some machines, the condition code register is
given a register number and a reg is used instead
of (cc0). This is usually the preferable approach
if only a small subset of instructions modify the
condition code. Other machines store condition













codes in general registers; in such cases a pseudo
register should be used.

Some machines, such as the Sparc and RS/6000, have
two sets of arithmetic instructions, one that sets
and one that does not set the condition code.
This is best handled by normally generating the
instruction that does not set the condition code,
and making a pattern that both performs the arith-
metic and sets the condition code register (which
would not be (cc0) in this case). For examples,
search for `addcc' and `andcc' in `sparc.md'.

(pc)
This represents the machine's program counter. It
has no operands and may not have a machine mode.
(pc) may be validly used only in certain specific
contexts in jump instructions.

There is only one expression object of code pc; it
is the value of the variable pc_rtx. Any attempt
to create an expression of code pc will return
pc_rtx.

All instructions that do not jump alter the pro-
gram counter implicitly by incrementing it, but
there is no need to mention this in the RTL.

(mem:m addr)
This RTX represents a reference to main memory at
an address represented by the expression addr. m
specifies how large a unit of memory is accessed.


1.7. RTL Expressions for Arithmetic

Unless otherwise specified, all the operands of arith-
metic expressions must be valid for mode m. An operand is
valid for mode m if it has mode m, or if it is a const_int
or const_double and m is a mode of class MODE_INT.

For commutative binary operations, constants should be
placed in the second operand.

(plus:m x y)
Represents the sum of the values represented by x
and y carried out in machine mode m.

(lo_sum:m x y)
Like plus, except that it represents that sum of x
and the low-order bits of y. The number of low
order bits is machine-dependent but is normally
the number of bits in a Pmode item minus the













number of bits set by the high code (see section
Constants).

m should be Pmode.

(minus:m x y)
Like plus but represents subtraction.

(compare:m x y)
Represents the result of subtracting y from x for
purposes of comparison. The result is computed
without overflow, as if with infinite precision.

Of course, machines can't really subtract with in-
finite precision. However, they can pretend to do
so when only the sign of the result will be used,
which is the case when the result is stored in the
condition code. And that is the only way this
kind of expression may validly be used: as a value
to be stored in the condition codes.

The mode m is not related to the modes of x and y,
but instead is the mode of the condition code
value. If (cc0) is used, it is VOIDmode. Other-
wise it is some mode in class MODE_CC, often
CCmode. See section Condition Code.

Normally, x and y must have the same mode. Other-
wise, compare is valid only if the mode of x is in
class MODE_INT and y is a const_int or
const_double with mode VOIDmode. The mode of x
determines what mode the comparison is to be done
in; thus it must not be VOIDmode.

If one of the operands is a constant, it should be
placed in the second operand and the comparison
code adjusted as appropriate.

A compare specifying two VOIDmode constants is not
valid since there is no way to know in what mode
the comparison is to be performed; the comparison
must either be folded during the compilation or
the first operand must be loaded into a register
while its mode is still known.

(neg:m x)
Represents the negation (subtraction from zero) of
the value represented by x, carried out in mode m.

(mult:m x y)
Represents the signed product of the values
represented by x and y carried out in machine mode
m.













Some machines support a multiplication that gen-
erates a product wider than the operands. Write
the pattern for this as


(mult:m (sign_extend:m x) (sign_extend:m y))



where m is wider than the modes of x and y,
which need not be the same.

Write patterns for unsigned widening multipli-
cation similarly using zero_extend.

(div:m x y)
Represents the quotient in signed division of
x by y, carried out in machine mode m. If m
is a floating point mode, it represents the
exact quotient; otherwise, the integerized
quotient.

Some machines have division instructions in
which the operands and quotient widths are not
all the same; you should represent such in-
structions using truncate and sign_extend as
in,


(truncate:m1 (div:m2 x (sign_extend:m2 y)))



(udiv:m x y)
Like div but represents unsigned division.

(mod:m x y)

(umod:m x y)
Like div and udiv but represent the remainder
instead of the quotient.

(smin:m x y)

(smax:m x y)
Represents the smaller (for smin) or larger
(for smax) of x and y, interpreted as signed
integers in mode m.

(umin:m x y)

(umax:m x y)
Like smin and smax, but the values are inter-













preted as unsigned integers.

(not:m x)
Represents the bitwise complement of the value
represented by x, carried out in mode m, which
must be a fixed-point machine mode.

(and:m x y)
Represents the bitwise logical-and of the
values represented by x and y, carried out in
machine mode m, which must be a fixed-point
machine mode.

(ior:m x y)
Represents the bitwise inclusive-or of the
values represented by x and y, carried out in
machine mode m, which must be a fixed-point
mode.

(xor:m x y)
Represents the bitwise exclusive-or of the
values represented by x and y, carried out in
machine mode m, which must be a fixed-point
mode.

(ashift:m x c)
Represents the result of arithmetically shift-
ing x left by c places. x have mode m, a
fixed-point machine mode. c be a fixed-point
mode or be a constant with mode VOIDmode;
which mode is determined by the mode called
for in the machine description entry for the
left-shift instruction. For example, on the
Vax, the mode of c is QImode regardless of m.

(lshift:m x c)
Like lshift but for arithmetic left shift.
ashift and lshift are identical operations; we
customarily use ashift for both.

(lshiftrt:m x c)

(ashiftrt:m x c)
Like lshift and ashift but for right shift.
Unlike the case for left shift, these two
operations are distinct.

(rotate:m x c)

(rotatert:m x c)
Similar but represent left and right rotate.
If c is a constant, use rotate.














(abs:m x)
Represents the absolute value of x, computed
in mode m.

(sqrt:m x)
Represents the square root of x, computed in
mode m. Most often m will be a floating point
mode.

(ffs:m x)
Represents one plus the index of the least
significant 1-bit in x, represented as an in-
teger of mode m. (The value is zero if x is
zero.) The mode of x need not be m; depending
on the target machine, various mode combina-
tions may be valid.


1.8. Comparison Operations

Comparison operators test a relation on two operands
and are considered to represent a machine-dependent nonzero
value described by, but not necessarily equal to,
STORE_FLAG_VALUE (see section Misc) if the relation holds,
or zero if it does not. The mode of the comparison opera-
tion is independent of the mode of the data being compared.
If the comparison operation is being tested (e.g., the first
operand of an if_then_else), the mode must be VOIDmode. If
the comparison operation is producing data to be stored in
some variable, the mode must be in class MODE_INT. All com-
parison operations producing data must use the same mode,
which is machine-specific.

There are two ways that comparison operations may be
used. The comparison operators may be used to compare the
condition codes (cc0) against zero, as in (eq (cc0)
(const_int 0)). Such a construct actually refers to the
result of the preceding instruction in which the condition
codes were set. The instructing setting the condition code
must be adjacent to the instruction using the condition
code; only note insns may separate them.

Alternatively, a comparison operation may directly com-
pare two data objects. The mode of the comparison is deter-
mined by the operands; they must both be valid for a common
machine mode. A comparison with both operands constant
would be invalid as the machine mode could not be deduced
from it, but such a comparison should never exist in RTL due
to constant folding.

In the example above, if (cc0) were last set to (com-
pare x y), the comparison operation is identical to (eq x
y). Usually only one style of comparisons is supported on a













particular machine, but the combine pass will try to merge
the operations to produce the eq shown in case it exists in
the context of the particular insn involved.

Inequality comparisons come in two flavors, signed and
unsigned. Thus, there are distinct expression codes gt and
gtu for signed and unsigned greater-than. These can produce
different results for the same pair of integer values: for
example, 1 is signed greater-than -1 but not unsigned
greater-than, because -1 when regarded as unsigned is actu-
ally 0xffffffff which is greater than 1.

The signed comparisons are also used for floating point
values. Floating point comparisons are distinguished by the
machine modes of the operands.

(eq:m x y)
1 if the values represented by x and y are equal,
otherwise 0.

(ne:m x y)
1 if the values represented by x and y are not
equal, otherwise 0.

(gt:m x y)
1 if the x is greater than y. If they are fixed-
point, the comparison is done in a signed sense.

(gtu:m x y)
Like gt but does unsigned comparison, on fixed-
point numbers only.

(lt:m x y)

(ltu:m x y)
Like gt and gtu but test for ``less than''.

(ge:m x y)

(geu:m x y)
Like gt and gtu but test for ``greater than or
equal''.

(le:m x y)

(leu:m x y)
Like gt and gtu but test for ``less than or
equal''.

(if_then_else cond then else)
This is not a comparison operation but is listed
here because it is always used in conjunction with
a comparison operation. To be precise, cond is a













comparison expression. This expression represents
a choice, according to cond, between the value
represented by then and the one represented by
else.

On most machines, if_then_else expressions are
valid only to express conditional jumps.

(cond [test1 value1 test2 value2 ...] default)
Similar to if_then_else, but more general. Each
of test1, test2, ... is performed in turn. The
result of this expression is the value correspond-
ing to the first non-zero test, or default if none
of the tests are non-zero expressions.

This is currently not valid for instruction pat-
terns and is supported only for insn attributes.
See section Insn Attributes.


1.9. Bit Fields

Special expression codes exist to represent bit-field
instructions. These types of expressions are lvalues in
RTL; they may appear on the left side of an assignment,
indicating insertion of a value into the specified bit
field.

(sign_extract:m loc size pos)
This represents a reference to a sign-extended bit
field contained or starting in loc (a memory or
register reference). The bit field is size bits
wide and starts at bit pos. The compilation op-
tion BITS_BIG_ENDIAN says which end of the memory
unit pos counts from.

If loc is in memory, its mode must be a single-
byte integer mode. If loc is in a register, the
mode to use is specified by the operand of the
insv or extv pattern (see section Standard Names)
and is usually a full-word integer mode.

The mode of pos is machine-specific and is also
specified in the insv or extv pattern.

The mode m is the same as the mode that would be
used for loc if it were a register.

(zero_extract:m loc size pos)
Like sign_extract but refers to an unsigned or
zero-extended bit field. The same sequence of
bits are extracted, but they are filled to an en-
tire word with zeros instead of by sign-extension.













1.10. Conversions

All conversions between machine modes must be
represented by explicit conversion operations. For example,
an expression which is the sum of a byte and a full word
cannot be written as (plus:SI (reg:QI 34) (reg:SI 80))
because the plus operation requires two operands of the same
machine mode. Therefore, the byte-sized operand is enclosed
in a conversion operation, as in


(plus:SI (sign_extend:SI (reg:QI 34)) (reg:SI 80))



The conversion operation is not a mere placeholder,
because there may be more than one way of converting from a
given starting mode to the desired final mode. The conver-
sion operation code says how to do it.

For all conversion operations, x must not be VOIDmode
because the mode in which to do the conversion would not be
known. The conversion must either be done at compile-time
or x must be placed into a register.

(sign_extend:m x)
Represents the result of sign-extending the value
x to machine mode m. m must be a fixed-point mode
and x a fixed-point value of a mode narrower than
m.

(zero_extend:m x)
Represents the result of zero-extending the value
x to machine mode m. m must be a fixed-point mode
and x a fixed-point value of a mode narrower than
m.

(float_extend:m x)
Represents the result of extending the value x to
machine mode m. m must be a floating point mode
and x a floating point value of a mode narrower
than m.

(truncate:m x)
Represents the result of truncating the value x to
machine mode m. m must be a fixed-point mode and
x a fixed-point value of a mode wider than m.

(float_truncate:m x)
Represents the result of truncating the value x to
machine mode m. m must be a floating point mode
and x a floating point value of a mode wider than
m.













(float:m x)
Represents the result of converting fixed point
value x, regarded as signed, to floating point
mode m.

(unsigned_float:m x)
Represents the result of converting fixed point
value x, regarded as unsigned, to floating point
mode m.

(fix:m x)
When m is a fixed point mode, represents the
result of converting floating point value x to
mode m, regarded as signed. How rounding is done
is not specified, so this operation may be used
validly in compiling C code only for integer-
valued operands.

(unsigned_fix:m x)
Represents the result of converting floating point
value x to fixed point mode m, regarded as un-
signed. How rounding is done is not specified.

(fix:m x)
When m is a floating point mode, represents the
result of converting floating point value x (valid
for mode m) to an integer, still represented in
floating point mode m, by rounding towards zero.


1.11. Declarations

Declaration expression codes do not represent arith-
metic operations but rather state assertions about their
operands.

(strict_low_part (subreg:m (reg:n r) 0))
This expression code is used in only one context:
operand 0 of a set expression. In addition, the
operand of this expression must be a non-
paradoxical subreg expression.

The presence of strict_low_part says that the part
of the register which is meaningful in mode n, but
is not part of mode m, is not to be altered. Nor-
mally, an assignment to such a subreg is allowed
to have undefined effects on the rest of the re-
gister when m is less than a word.


















1.12. Side Effect Expressions

The expression codes described so far represent values,
not actions. But machine instructions never produce values;
they are meaningful only for their side effects on the state
of the machine. Special expression codes are used to
represent side effects.

The body of an instruction is always one of these side
effect codes; the codes described above, which represent
values, appear only as the operands of these.

(set lval x)
Represents the action of storing the value of x
into the place represented by lval. lval must be
an expression representing a place that can be
stored in: reg (or subreg or strict_low_part),
mem, pc or cc0.

If lval is a reg, subreg or mem, it has a machine
mode; then x must be valid for that mode.

If lval is a reg whose machine mode is less than
the full width of the register, then it means that
the part of the register specified by the machine
mode is given the specified value and the rest of
the register receives an undefined value. Like-
wise, if lval is a subreg whose machine mode is
narrower than the mode of the register, the rest
of the register can be changed in an undefined
way.

If lval is a strict_low_part of a subreg, then the
part of the register specified by the machine mode
of the subreg is given the value x and the rest of
the register is not changed.

If lval is (cc0), it has no machine mode, and x
may be either a compare expression or a value that
may have any mode. The latter case represents a
``test'' instruction. The expression (set (cc0)
(reg:m n)) is equivalent to (set (cc0) (compare
(reg:m n) (const_int 0))). Use the former expres-
sion to save space during the compilation.

If lval is (pc), we have a jump instruction, and
the possibilities for x are very limited. It may
be a label_ref expression (unconditional jump).
It may be an if_then_else (conditional jump), in
which case either the second or the third operand
must be (pc) (for the case which does not jump)
and the other of the two must be a label_ref (for
the case which does jump). x may also be a mem or













(plus:SI (pc) y), where y may be a reg or a mem;
these unusual patterns are used to represent jumps
through branch tables.

If lval is neither (cc0) nor (pc), the mode of
lval must not be VOIDmode and the mode of x must
be valid for the mode of lval.

lval is customarily accessed with the SET_DEST
macro and x with the SET_SRC macro.

(return)
As the sole expression in a pattern, represents a
return from the current function, on machines
where this can be done with one instruction, such
as Vaxes. On machines where a multi-instruction
``epilogue'' must be executed in order to return
from the function, returning is done by jumping to
a label which precedes the epilogue, and the re-
turn expression code is never used.

Inside an if_then_else expression, represents the
value to be placed in pc to return to the caller.

Note that an insn pattern of (return) is logically
equivalent to (set (pc) (return)), but the latter
form is never used.

(call function nargs)
Represents a function call. function is a mem ex-
pression whose address is the address of the func-
tion to be called. nargs is an expression which
can be used for two purposes: on some machines it
represents the number of bytes of stack argument;
on others, it represents the number of argument
registers.

Each machine has a standard machine mode which
function must have. The machine description de-
fines macro FUNCTION_MODE to expand into the re-
quisite mode name. The purpose of this mode is to
specify what kind of addressing is allowed, on
machines where the allowed kinds of addressing
depend on the machine mode being addressed.

(clobber x)
Represents the storing or possible storing of an
unpredictable, undescribed value into x, which
must be a reg, scratch or mem expression.

One place this is used is in string instructions
that store standard values into particular hard
registers. It may not be worth the trouble to













describe the values that are stored, but it is
essential to inform the compiler that the regis-
ters will be altered, lest it attempt to keep data
in them across the string instruction.

If x is (mem:BLK (const_int 0)), it means that all
memory locations must be presumed clobbered.

Note that the machine description classifies cer-
tain hard registers as ``call-clobbered''. All
function call instructions are assumed by default
to clobber these registers, so there is no need to
use clobber expressions to indicate this fact.
Also, each function call is assumed to have the
potential to alter any memory location, unless the
function is declared const.

If the last group of expressions in a parallel are
each a clobber expression whose arguments are reg
or match_scratch (see section RTL Template) ex-
pressions, the combiner phase can add the ap-
propriate clobber expressions to an insn it has
constructed when doing so will cause a pattern to
be matched.

This feature can be used, for example, on a
machine that whose multiply and add instructions
don't use an MQ register but which has an add-
accumulate instruction that does clobber the MQ
register. Similarly, a combined instruction might
require a temporary register while the constituent
instructions might not.

When a clobber expression for a register appears
inside a parallel with other side effects, the re-
gister allocator guarantees that the register is
unoccupied both before and after that insn. How-
ever, the reload phase may allocate a register
used for one of the inputs unless the `&' con-
straint is specified for the selected alternative
(see section Modifiers). You can clobber either
a specific hard register, a pseudo register, or a
scratch expression; in the latter two cases, GNU
CC will allocate a hard register that is available
there for use as a temporary.

For instructions that require a temporary regis-
ter, you should use scratch instead of a pseudo-
register because this will allow the combiner
phase to add the clobber when required. You do
this by coding (clobber (match_scratch ...)). If
you do clobber a pseudo register, use one which
appears nowhere else---generate a new one each













time. Otherwise, you may confuse CSE.

There is one other known use for clobbering a
pseudo register in a parallel: when one of the in-
put operands of the insn is also clobbered by the
insn. In this case, using the same pseudo regis-
ter in the clobber and elsewhere in the insn pro-
duces the expected results.

(use x)
Represents the use of the value of x. It indi-
cates that the value in x at this point in the
program is needed, even though it may not be ap-
parent why this is so. Therefore, the compiler
will not attempt to delete previous instructions
whose only effect is to store a value in x. x
must be a reg expression.

During the delayed branch scheduling phase, x may
be an insn. This indicates that x previously was
located at this place in the code and its data
dependencies need to be taken into account. These
use insns will be deleted before the delayed
branch scheduling phase exits.

(parallel [x0 x1 ...])
Represents several side effects performed in
parallel. The square brackets stand for a vector;
the operand of parallel is a vector of expres-
sions. x0, x1 and so on are individual side ef-
fect expressions---expressions of code set, call,
return, clobber or use.

``In parallel'' means that first all the values
used in the individual side-effects are computed,
and second all the actual side-effects are per-
formed. For example,


(parallel [(set (reg:SI 1) (mem:SI (reg:SI 1)))
(set (mem:SI (reg:SI 1)) (reg:SI 1))])



says unambiguously that the values of hard register
1 and the memory location addressed by it are in-
terchanged. In both places where (reg:SI 1) ap-
pears as a memory address it refers to the value in
register 1 before the execution of the insn.

It follows that it is incorrect to use paral-
lel and expect the result of one set to be
available for the next one. For example, peo-













ple sometimes attempt to represent a jump-if-
zero instruction this way:


(parallel [(set (cc0) (reg:SI 34))
(set (pc) (if_then_else
(eq (cc0) (const_int 0))
(label_ref ...)
(pc)))])



But this is incorrect, because it says that the
jump condition depends on the condition code value
before this instruction, not on the new value that
is set by this instruction.

Peephole optimization, which takes place to-
gether with final assembly code output, can
produce insns whose patterns consist of a
parallel whose elements are the operands need-
ed to output the resulting assembler code---
often reg, mem or constant expressions. This
would not be well-formed RTL at any other
stage in compilation, but it is ok then be-
cause no further optimization remains to be
done. However, the definition of the macro
NOTICE_UPDATE_CC, if any, must deal with such
insns if you define any peephole optimiza-
tions.

(sequence [insns ...])
Represents a sequence of insns. Each of the
insns that appears in the vector is suitable
for appearing in the chain of insns, so it
must be an insn, jump_insn, call_insn,
code_label, barrier or note.

A sequence RTX is never placed in an actual
insn during RTL generation. It represents the
sequence of insns that result from a
define_expand before those insns are passed to
emit_insn to insert them in the chain of
insns. When actually inserted, the individual
sub-insns are separated out and the sequence
is forgotten.

After delay-slot scheduling is completed, an
insn and all the insns that reside in its de-
lay slots are grouped together into a se-
quence. The insn requiring the delay slot is
the first insn in the vector; subsequent insns
are to be placed in the delay slot.













INSN_ANNULLED_BRANCH_P is set on an insn in a
delay slot to indicate that a branch insn
should be used that will conditionally annul
the effect of the insns in the delay slots.
In such a case, INSN_FROM_TARGET_P indicates
that the insn is from the target of the branch
and should be executed only if the branch is
taken; otherwise the insn should be executed
only if the branch is not taken. See section
Delay Slots.


These expression codes appear in place of a side
effect, as the body of an insn, though strictly speaking
they do not always describe side effects as such:

(asm_input s)
Represents literal assembler code as described by
the string s.

(unspec [operands ...] index)

(unspec [operands ...] index)
Represents a machine-specific operation on
operands. index selects between multiple macine-
specific operations. unspec_volatile is used for
volatile operations and operations that may trap;
unspec is used for other operations.

These codes may appear themselves inside a pattern
of an insn, inside a parallel, or inside an ex-
pression.

(addr_vec:m [lr0 lr1 ...])
Represents a table of jump addresses. The vector
elements lr0, etc., are label_ref expressions.
The mode m specifies how much space is given to
each address; normally m would be Pmode.

(addr_diff_vec:m base [lr0 lr1 ...])
Represents a table of jump addresses expressed as
offsets from base. The vector elements lr0, etc.,
are label_ref expressions and so is base. The
mode m specifies how much space is given to each
address-difference.


1.13. Embedded Side-Effects on Addresses

Four special side-effect expression codes appear as
memory addresses.















(pre_dec:m x)
Represents the side effect of decrementing x by a
standard amount and represents also the value that
x has after being decremented. x must be a reg or
mem, but most machines allow only a reg. m must
be the machine mode for pointers on the machine in
use. The amount x is decremented by is the length
in bytes of the machine mode of the containing
memory reference of which this expression serves
as the address. Here is an example of its use:


(mem:DF (pre_dec:SI (reg:SI 39)))



This says to decrement pseudo register 39 by the
length of a DFmode value and use the result to ad-
dress a DFmode value.

(pre_inc:m x)
Similar, but specifies incrementing x instead
of decrementing it.

(post_dec:m x)
Represents the same side effect as pre_dec but
a different value. The value represented here
is the value x has before being decremented.

(post_inc:m x)
Similar, but specifies incrementing x instead
of decrementing it.


These embedded side effect expressions must be used
with care. Instruction patterns may not use them. Until
the `flow' pass of the compiler, they may occur only to
represent pushes onto the stack. The `flow' pass finds
cases where registers are incremented or decremented in one
instruction and used as an address shortly before or after;
these cases are then transformed to use pre- or post-
increment or -decrement.

If a register used as the operand of these expressions
is used in another address in an insn, the original value of
the register is used. Uses of the register outside of an
address are not permitted within the same insn as a use in
an embedded side effect expression because such insns behave
differently on different machines and hence must be treated
as ambiguous and disallowed.

An instruction that can be represented with an embedded
side effect could also be represented using parallel













containing an additional set to describe how the address
register is altered. This is not done because machines that
allow these operations at all typically allow them wherever
a memory address is called for. Describing them as addi-
tional parallel stores would require doubling the number of
entries in the machine description.

1.14. Assembler Instructions as Expressions

The RTX code asm_operands represents a value produced
by a user-specified assembler instruction. It is used to
represent an asm statement with arguments. An asm statement
with a single output operand, like this:


asm ("foo %1,%2,%0" : "=a" (outputvar) : "g" (x + y), "di" (*z));



is represented using a single asm_operands RTX which
represents the value that is stored in outputvar:


(set rtx-for-outputvar
(asm_operands "foo %1,%2,%0" "a" 0
[rtx-for-addition-result rtx-for-*z]
[(asm_input:m1 "g")
(asm_input:m2 "di")]))



Here the operands of the asm_operands RTX are the assembler
template string, the output-operand's constraint, the
index-number of the output operand among the output operands
specified, a vector of input operand RTX's, and a vector of
input-operand modes and constraints. The mode m1 is the
mode of the sum x+y; m2 is that of *z.

When an asm statement has multiple output values, its
insn has several such set RTX's inside of a parallel. Each
set contains a asm_operands; all of these share the same
assembler template and vectors, but each contains the con-
straint for the respective output operand. They are also
distinguished by the output-operand index number, which is
0, 1, ... for successive output operands.

1.15. 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 schedul-
ing, 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 spe-
cial 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 con-
tained. Similar rules apply for PREV_INSN.

This means that the above invariants are not neces-
sarily true for insns inside sequence expressions. Specifi-
cally, 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 instruc-
tions that may jump (or, more generally, may con-
tain label_ref expressions). If there is an in-
struction 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
contains 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 instruc-
tions that may do function calls. It is important













to distinguish these instructions because they im-
ply that certain registers and memory locations
may be altered unpredictably.

A call_insn insn may be preceeded by insns that
contain a single use expression and be followed by
insns the contain a single clobber expression. If
so, these use and clobber expressions are treated
as being part of the function call. There must
not even be a note between the call_insn and the
use or clobber insns for this special treatment to
take place. This is somewhat of a kludge and will
be removed in a later version of GNU CC.

call_insn insns have the same extra fields as insn
insns, accessed in the same way.

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 debug-
ging and declarative information. They contain
two nonstandard fields, an integer which is ac-
cessed 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 alter-
ing 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_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 po-
sition 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 instruc-
tion 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 ap-
pear 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 reload-
ing 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, un-
spec, unspec_volatile, or parallel. If it is a
parallel, each element of the parallel must be one
these codes, except that parallel expressions can-
not 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 match-
ing 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 in-
formation 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 expres-
sions) 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 sig-
nificant.

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 instruc-
tion 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: antidependen-
cies 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 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 some-
thing 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 pro-













gram.

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 ap-
pears 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 contains a pattern named
`decrement_and_branch_until_zero'.

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 as-
signed 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 out-
put 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, be-
ing 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 re-
gister by the stack slot throughout the function.

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 se-
quence 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 pri-
or to register allocation (such as common subex-
pression 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 lo-
cation of a parameter on the stack) that may be













used in place of a register if insufficient regis-
ters 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 regis-
ters that are equivalent to a memory location
throughout there entire life, which is not detect-
ed until later in the compilation, all
equivalences are initially indicated by an at-
tached REG_EQUAL note. In the early stages of re-
gister 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 be-
fore 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 se-
quence (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 VOID-
mode, 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).


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 debug-
ging dumps as the insn's unique id; the first operand of an
expr_list is printed in the ordinary way as an expression.

1.16. 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 han-
dled 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 des-
troyed. 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 (see section 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 immedi-
ately after the call to indicate which registers.

1.17. Structure Sharing Assumptions

The compiler assumes that certain kinds of RTL expres-
sions 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 cer-
tain 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 func-
tions.

o+ Each pseudo-register has only a single reg object
to represent it, and therefore only a single
machine mode.

o+ For any symbolic label, there is only one
symbol_ref object referring to it.

o+ 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.

o+ There is only one pc expression.

o+ There is only one cc0 expression.

o+ There is only one const_double expression with
value 0 for each floating point mode. Likewise
for values 1 and 2.

o+ 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.

o+ 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 ap-
pear. However, separate but equal objects for
these variables are occasionally made.

o+ 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.

o+ 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.

o+ During initial RTL generation, shared structure is
freely introduced. After all the RTL for a func-
tion 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 fol-
lowed.

o+ 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.




























  3 Responses to “Category : C Source Code
Archive   : GCCTXT.ZIP
Filename : RTL.TXT

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/