1206 lines
50 KiB
Plaintext
1206 lines
50 KiB
Plaintext
This is Info file gcc.info, produced by Makeinfo version 1.68 from the
|
||
input file ../../gcc-2.95.2/gcc/gcc.texi.
|
||
|
||
INFO-DIR-SECTION Programming
|
||
START-INFO-DIR-ENTRY
|
||
* gcc: (gcc). The GNU Compiler Collection.
|
||
END-INFO-DIR-ENTRY
|
||
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,
|
||
1999 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" and "Funding
|
||
for Free Software" 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" and "Funding for Free Software", 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: Flags, Next: Machine Modes, Prev: Accessors, Up: RTL
|
||
|
||
Flags in an RTL Expression
|
||
==========================
|
||
|
||
RTL expressions contain several flags (one-bit bitfields) and other
|
||
values 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 component 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'. If both this flag and
|
||
MEM_SCALAR_P are clear, then we don't know whether this MEM is in a
|
||
structure or not. Both flags should never be simultaneously set.
|
||
|
||
`MEM_SCALAR_P (X)'
|
||
In `mem' expressions, nonzero for reference to a scalar known not
|
||
to be a member of a structure, union, or array. Zero for such
|
||
references and for indirections through pointers, even pointers
|
||
pointing to scalar types. If both this flag and MEM_STRUCT_P are
|
||
clear, then we don't know whether this MEM is in a structure or
|
||
not. Both flags should never be simultaneously set.
|
||
|
||
`MEM_ALIAS_SET (X)'
|
||
In `mem' expressions, the alias set to which X belongs. If zero,
|
||
X is not in any alias set, and may alias anything. If nonzero, X
|
||
may only alias objects in the same alias set. This value is set
|
||
(in a language-specific manner) by the front-end. This field is
|
||
not a bit-field; it is in an integer, found as the second argument
|
||
to the `mem'.
|
||
|
||
`REG_LOOP_TEST_P'
|
||
In `reg' expressions, nonzero if this register's entire 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 temporaries 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 collecting the values
|
||
of functions called by this one, but `REG_FUNCTION_VALUE_P' is zero
|
||
in this kind of use.
|
||
|
||
`SUBREG_PROMOTED_VAR_P'
|
||
Nonzero in a `subreg' if it was made when accessing an object that
|
||
was promoted to a wider mode in accord with the `PROMOTED_MODE'
|
||
machine description macro (*note Storage Layout::.). In this
|
||
case, the mode of the `subreg' is the declared mode of the object
|
||
and the mode of `SUBREG_REG' is the mode of the register that
|
||
holds the object. Promoted variables are always either sign- or
|
||
zero-extended to the wider mode on every assignment. Stored in
|
||
the `in_struct' field and printed as `/s'.
|
||
|
||
`SUBREG_PROMOTED_UNSIGNED_P'
|
||
Nonzero in a `subreg' that has `SUBREG_PROMOTED_VAR_P' nonzero if
|
||
the object being referenced is kept zero-extended and zero if it
|
||
is kept sign-extended. Stored in the `unchanging' field and
|
||
printed as `/u'.
|
||
|
||
`RTX_UNCHANGING_P (X)'
|
||
Nonzero in a `reg' or `mem' if the value is not changed. (This
|
||
flag is not set for memory references 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 aliasing.) 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'.
|
||
|
||
`RTX_FRAME_RELATED_P (X)'
|
||
Nonzero in an insn or expression which is part of a function
|
||
prologue and sets the stack pointer, sets the frame pointer, or
|
||
saves a register. This flag is required for exception handling
|
||
support on targets with RTL prologues.
|
||
|
||
`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, indicates 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 will only be executed if
|
||
the branch is taken. For annulled branches with
|
||
`INSN_FROM_TARGET_P' clear, the insn will be executed only if the
|
||
branch is not taken. When `INSN_ANNULLED_BRANCH_P' is not set,
|
||
this insn will always be executed. 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 function, and GNU CC assumes they can be addressed
|
||
directly (perhaps with the help of base registers). 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 `unchanging' field and printed as
|
||
`/u'.
|
||
|
||
`LABEL_PRESERVE_P (X)'
|
||
In a `code_label', indicates that the label can never be deleted.
|
||
Labels referenced by 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, indicates that the
|
||
previous insn must be scheduled together 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 structure
|
||
(*note Sharing::.).
|
||
|
||
In a `symbol_ref', it indicates that an external declaration 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' expressions and
|
||
in insns. In RTL dump files, it is printed as `/v'.
|
||
|
||
In a `mem' expression, it is 1 if the memory reference 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 compiler 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 array; 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 something 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 expression of some loop.
|
||
|
||
In `subreg' expressions, 1 means that the `subreg' is accessing an
|
||
object that has had its mode promoted from a wider mode.
|
||
|
||
In `label_ref' expressions, 1 means that the referenced label is
|
||
outside the innermost loop containing 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 `subreg' expressions, it is 1 if the `subreg' references an
|
||
unsigned object whose mode has been promoted to a wider mode.
|
||
|
||
In an insn, 1 means that this is an annulling branch.
|
||
|
||
In a `symbol_ref' expression, 1 means that this symbol addresses
|
||
something in the per-function constants 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 register containing
|
||
the value to be returned by the current function. On machines
|
||
that pass parameters in registers, the same register number may be
|
||
used for parameters as well, but this flag is not set on such uses.
|
||
|
||
|
||
File: gcc.info, Node: Machine Modes, Next: Constants, Prev: Flags, Up: RTL
|
||
|
||
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 (*note Storage Layout::.).
|
||
|
||
`QImode'
|
||
"Quarter-Integer" mode represents a single byte treated as an
|
||
integer.
|
||
|
||
`HImode'
|
||
"Half-Integer" mode represents a two-byte integer.
|
||
|
||
`PSImode'
|
||
"Partial Single Integer" mode represents an integer 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 integer.
|
||
|
||
`PDImode'
|
||
"Partial Double Integer" mode represents an integer 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. On some systems not all bits within these bytes
|
||
will actually be used.
|
||
|
||
`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 *note Condition Code::.).
|
||
|
||
`BLKmode'
|
||
"Block" mode represents values that are aggregates 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 instructions,
|
||
`BLKmode' will not appear in RTL.
|
||
|
||
`VOIDmode'
|
||
Void mode means the absence of a mode or an unspecified mode. For
|
||
example, RTL expressions of code `const_int' have mode `VOIDmode'
|
||
because they can be taken to have whatever mode the context
|
||
requires. 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 floating point values are in `SFmode',
|
||
`DFmode', `XFmode', and `TFmode', respectively.
|
||
|
||
`CQImode, CHImode, CSImode, CDImode, CTImode, COImode'
|
||
These modes stand for a complex number represented as a pair of
|
||
integer values. The integer values are in `QImode', `HImode',
|
||
`SImode', `DImode', `TImode', and `OImode', respectively.
|
||
|
||
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 compiler use `TImode' for 16-byte
|
||
structures and unions. Likewise, 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 `PDImode'.
|
||
|
||
`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 implemented).
|
||
|
||
`MODE_CC'
|
||
Modes representing condition code values. These are `CCmode' plus
|
||
any modes listed in the `EXTRA_CC_MODES' macro. *Note Jump
|
||
Patterns::, also see *Note Condition Code::.
|
||
|
||
`MODE_RANDOM'
|
||
This is a catchall mode class for modes which don't fit into the
|
||
above classes. Currently `VOIDmode' 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. For example, the expression
|
||
`GET_MODE_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 object of mode M.
|
||
|
||
`GET_MODE_UNIT_SIZE (M)'
|
||
Returns the size in bytes of the subunits of a datum 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 either `BITS_PER_UNIT' or
|
||
`BITS_PER_WORD', respectively. On 32-bit machines, these are `QImode'
|
||
and `SImode', respectively.
|
||
|
||
|
||
File: gcc.info, Node: Constants, Next: Regs and Memory, Prev: Machine Modes, Up: RTL
|
||
|
||
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 `XWINT (EXP, 0)'.
|
||
|
||
There is only one expression object for the integer value zero; it
|
||
is the value of the variable `const0_rtx'. Likewise, the only
|
||
expression for integer 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 return
|
||
`const0_rtx', `const1_rtx', `const2_rtx' or `constm1_rtx' as
|
||
appropriate.
|
||
|
||
Similarly, there is only one object for the integer 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 too large to fit into `HOST_BITS_PER_WIDE_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 compilation (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 bits 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 (regardless of its precision),
|
||
then the number of integers used to store the value depends on the
|
||
size of `REAL_VALUE_TYPE' (*note Cross-compilation::.). The
|
||
integers represent a floating point number, but not precisely in
|
||
the target machine's or host machine's floating point format. To
|
||
convert them to the precise bit pattern used by the target
|
||
machine, use the macro `REAL_VALUE_TO_TARGET_DOUBLE' and friends
|
||
(*note Data Output::.).
|
||
|
||
The macro `CONST0_RTX (MODE)' refers to an expression 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. Similarly, 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 attributes (*note Insn Attributes::.) since
|
||
constant strings in C are placed in memory.
|
||
|
||
`(symbol_ref:MODE 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
|
||
`_'.
|
||
|
||
The `symbol_ref' contains a mode, which is usually `Pmode'.
|
||
Usually that is the only mode for which a symbol is directly valid.
|
||
|
||
`(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'.
|
||
|
||
|
||
File: gcc.info, Node: Regs and Memory, Next: Arithmetic, Prev: Constants, Up: RTL
|
||
|
||
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 (those that are less than
|
||
`FIRST_PSEUDO_REGISTER'), this stands for a reference to machine
|
||
register number N: a "hard register". For larger values of N, it
|
||
stands for a temporary 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 references.
|
||
|
||
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 precisions.
|
||
|
||
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 registers on the machine is
|
||
an invariant characteristic of the machine. Note, however, that
|
||
not all of the machine registers must be general registers. 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
|
||
certain 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 specifies 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' expression.
|
||
|
||
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
|
||
optimization phases. These represent locations in the stack frame
|
||
that cannot be determined until RTL generation for the function
|
||
has been completed. 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 caller, but the callee may have pushed some
|
||
arguments that were previously passed in registers.
|
||
|
||
When RTL generation is complete, this virtual register is
|
||
replaced by the sum of the register given by
|
||
`ARG_POINTER_REGNUM' and the value of `FIRST_PARM_OFFSET'.
|
||
|
||
`VIRTUAL_STACK_VARS_REGNUM'
|
||
If `FRAME_GROWS_DOWNWARD' is defined, this points to
|
||
immediately above the first variable on the stack.
|
||
Otherwise, it points to the first variable on the stack.
|
||
|
||
`VIRTUAL_STACK_VARS_REGNUM' 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.
|
||
|
||
This virtual register 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').
|
||
|
||
This virtual register 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 instruction 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.
|
||
|
||
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 individual 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 access one
|
||
of the registers, use a `subreg' with mode `SImode' and a WORDNUM
|
||
that says which register.
|
||
|
||
Storing in a non-paradoxical `subreg' has undefined results for
|
||
bits belonging to the same word as the `subreg'. This laxity makes
|
||
it easier to generate efficient code for such instructions. To
|
||
represent an instruction that preserves all the bits outside of
|
||
those in the `subreg', use `strict_low_part' around the `subreg'.
|
||
|
||
The compilation parameter `WORDS_BIG_ENDIAN', if set to 1, says
|
||
that word number zero is the most significant part; otherwise, it
|
||
is the least significant part.
|
||
|
||
On a few targets, `FLOAT_WORDS_BIG_ENDIAN' disagrees with
|
||
`WORDS_BIG_ENDIAN'. However, most parts of the compiler treat
|
||
floating point values as if they had the same endianness as
|
||
integer values. This works because they handle them solely as a
|
||
collection of integer values, with no particular numerical value.
|
||
Only real.c and the runtime libraries care about
|
||
`FLOAT_WORDS_BIG_ENDIAN'.
|
||
|
||
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
|
||
possible to have a non-paradoxical `subreg' which contains 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
|
||
floating value.
|
||
|
||
It is also not valid to access a single word of a multi-word value
|
||
in a hard register when less registers 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 entire
|
||
`DFmode' value. If register 10 were such a register `(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 being formed.
|
||
|
||
The first operand of a `subreg' expression is customarily 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' operation (*note
|
||
Side Effects::.).
|
||
|
||
`(cc0)'
|
||
This refers to the machine's condition code register. It has no
|
||
operands and may not have a machine mode. There are two ways to
|
||
use it:
|
||
|
||
* 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 instructions) and in comparison operators comparing
|
||
against zero (`const_int' with value zero; that is to say,
|
||
`const0_rtx').
|
||
|
||
* 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 instructions) 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 attempt to create an expression of
|
||
code `cc0' will return `cc0_rtx'.
|
||
|
||
Instructions can set the condition code implicitly. 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'). *Note Condition 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 arithmetic 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 program 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.
|
||
|
||
`(addressof:M REG)'
|
||
This RTX represents a request for the address of register REG.
|
||
Its mode is always `Pmode'. If there are any `addressof'
|
||
expressions left in the function after CSE, REG is forced into the
|
||
stack and the `addressof' expression is replaced with a `plus'
|
||
expression for the address of its stack slot.
|
||
|
||
|
||
File: gcc.info, Node: Arithmetic, Next: Comparisons, Prev: Regs and Memory, Up: RTL
|
||
|
||
RTL Expressions for Arithmetic
|
||
==============================
|
||
|
||
Unless otherwise specified, all the operands of arithmetic
|
||
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 (*note
|
||
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 infinite 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'. Otherwise it is some mode in class `MODE_CC', often
|
||
`CCmode'. *Note Condition Code::.
|
||
|
||
Normally, X and Y must have the same mode. Otherwise, `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 generates 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 multiplication 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
|
||
instructions 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 interpreted 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 shifting 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.
|
||
|
||
`(lshiftrt:M X C)'
|
||
`(ashiftrt:M X C)'
|
||
Like `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 integer 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 combinations may be valid.
|
||
|
||
|
||
File: gcc.info, Node: Comparisons, Next: Bit Fields, Prev: Arithmetic, Up: RTL
|
||
|
||
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' (*note Misc::.) if
|
||
the relation holds, or zero if it does not. The mode of the comparison
|
||
operation 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 comparison 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 compare two data
|
||
objects. The mode of the comparison is determined 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 `(compare 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 actually
|
||
`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 corresponding to the first non-zero test, or DEFAULT if
|
||
none of the tests are non-zero expressions.
|
||
|
||
This is currently not valid for instruction patterns and is
|
||
supported only for insn attributes. *Note Insn Attributes::.
|
||
|
||
|
||
File: gcc.info, Node: Bit Fields, Next: Conversions, Prev: Comparisons, Up: RTL
|
||
|
||
Bit Fields
|
||
==========
|
||
|
||
Special expression codes exist to represent bitfield 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 option
|
||
`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 (*note Standard Names::.)
|
||
and is usually a full-word integer mode, which is the default if
|
||
none is specified.
|
||
|
||
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 entire word with zeros instead of by sign-extension.
|
||
|
||
|
||
File: gcc.info, Node: Conversions, Next: RTL Declarations, Prev: Bit Fields, Up: RTL
|
||
|
||
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 conversion 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 unsigned. 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.
|
||
|