17.14 Addressing Modes

A C expression that is nonzero if the machine supports pre-increment,
pre-decrement, post-increment, or post-decrement addressing respectively.

— Macro: HAVE_PRE_MODIFY_DISP
— Macro: HAVE_POST_MODIFY_DISP

A C expression that is nonzero if the machine supports pre- or
post-address side-effect generation involving constants other than
the size of the memory operand.

— Macro: HAVE_PRE_MODIFY_REG
— Macro: HAVE_POST_MODIFY_REG

A C expression that is nonzero if the machine supports pre- or
post-address side-effect generation involving a register displacement.

— Macro: CONSTANT_ADDRESS_P (x)

A C expression that is 1 if the RTX x is a constant which
is a valid address. On most machines, this can be defined as
CONSTANT_P (x), but a few machines are more restrictive
in which constant addresses are supported.

— Macro: CONSTANT_P (x)

CONSTANT_P, which is defined by target-independent code,
accepts integer-values expressions whose values are not explicitly
known, such as symbol_ref, label_ref, and high
expressions and const arithmetic expressions, in addition to
const_int and const_double expressions.

— Macro: MAX_REGS_PER_ADDRESS

A number, the maximum number of registers that can appear in a valid
memory address. Note that it is up to you to specify a value equal to
the maximum number that GO_IF_LEGITIMATE_ADDRESS would ever
accept.

— Macro: GO_IF_LEGITIMATE_ADDRESS (mode, x, label)

A C compound statement with a conditional goto label;
executed if x (an RTX) is a legitimate memory address on the
target machine for a memory operand of mode mode.

It usually pays to define several simpler macros to serve as
subroutines for this one. Otherwise it may be too complicated to
understand.

This macro must exist in two variants: a strict variant and a
non-strict one. The strict variant is used in the reload pass. It
must be defined so that any pseudo-register that has not been
allocated a hard register is considered a memory reference. In
contexts where some kind of register is required, a pseudo-register
with no hard register must be rejected.

The non-strict variant is used in other passes. It must be defined to
accept all pseudo-registers in every context where some kind of
register is required.

Compiler source files that want to use the strict variant of this
macro define the macro REG_OK_STRICT. You should use an
#ifdef REG_OK_STRICT conditional to define the strict variant
in that case and the non-strict variant otherwise.

Subroutines to check for acceptable registers for various purposes (one
for base registers, one for index registers, and so on) are typically
among the subroutines used to define GO_IF_LEGITIMATE_ADDRESS.
Then only these subroutine macros need have two variants; the higher
levels of macros may be the same whether strict or not.

Normally, constant addresses which are the sum of a symbol_ref
and an integer are stored inside a const RTX to mark them as
constant. Therefore, there is no need to recognize such sums
specifically as legitimate addresses. Normally you would simply
recognize any const as legitimate.

Usually PRINT_OPERAND_ADDRESS is not prepared to handle constant
sums that are not marked with const. It assumes that a naked
plus indicates indexing. If so, then you must reject such
naked constant sums as illegitimate addresses, so that none of them will
be given to PRINT_OPERAND_ADDRESS.

On some machines, whether a symbolic address is legitimate depends on
the section that the address refers to. On these machines, define the
target hook TARGET_ENCODE_SECTION_INFO to store the information
into the symbol_ref, and then check for it here. When you see a
const, you will have to look inside it to find the
symbol_ref in order to determine the section. See Assembler Format.

— Macro: TARGET_MEM_CONSTRAINT

A single character to be used instead of the default 'm'
character for general memory addresses. This defines the constraint
letter which matches the memory addresses accepted by
GO_IF_LEGITIMATE_ADDRESS_P. Define this macro if you want to
support new address formats in your back end without changing the
semantics of the 'm' constraint. This is necessary in order to
preserve functionality of inline assembly constructs using the
'm' constraint.

— Macro: FIND_BASE_TERM (x)

A C expression to determine the base term of address x,
or to provide a simplified version of x from which alias.c
can easily find the base term. This macro is used in only two places:
find_base_value and find_base_term in alias.c.

It is always safe for this macro to not be defined. It exists so
that alias analysis can understand machine-dependent addresses.

The typical use of this macro is to handle addresses containing
a label_ref or symbol_ref within an UNSPEC.

— Macro: LEGITIMIZE_ADDRESS (x, oldx, mode, win)

A C compound statement that attempts to replace x with a valid
memory address for an operand of mode mode. win will be a
C statement label elsewhere in the code; the macro definition may use

GO_IF_LEGITIMATE_ADDRESS (mode, x, win);

to avoid further processing if the address has become legitimate.

x will always be the result of a call to break_out_memory_refs,
and oldx will be the operand that was given to that function to produce
x.

The code generated by this macro should not alter the substructure of
x. If it transforms x into a more legitimate form, it
should assign x (which will always be a C variable) a new value.

It is not necessary for this macro to come up with a legitimate
address. The compiler has standard ways of doing so in all cases. In
fact, it is safe to omit this macro. But often a
machine-dependent strategy can generate better code.

A C compound statement that attempts to replace x, which is an address
that needs reloading, with a valid memory address for an operand of mode
mode. win will be a C statement label elsewhere in the code.
It is not necessary to define this macro, but it might be useful for
performance reasons.

For example, on the i386, it is sometimes possible to use a single
reload register instead of two by reloading a sum of two pseudo
registers into a register. On the other hand, for number of RISC
processors offsets are limited so that often an intermediate address
needs to be generated in order to address a stack slot. By defining
LEGITIMIZE_RELOAD_ADDRESS appropriately, the intermediate addresses
generated for adjacent some stack slots can be made identical, and thus
be shared.

Note: This macro should be used with caution. It is necessary
to know something of how reload works in order to effectively use this,
and it is quite easy to produce macros that build in too much knowledge
of reload internals.

Note: This macro must be able to reload an address created by a
previous invocation of this macro. If it fails to handle such addresses
then the compiler may generate incorrect code or abort.

The macro definition should use push_reload to indicate parts that
need reloading; opnum, type and ind_levels are usually
suitable to be passed unaltered to push_reload.

The code generated by this macro must not alter the substructure of
x. If it transforms x into a more legitimate form, it
should assign x (which will always be a C variable) a new value.
This also applies to parts that you change indirectly by calling
push_reload.

The macro definition may use strict_memory_address_p to test if
the address has become legitimate.

If you want to change only a part of x, one standard way of doing
this is to use copy_rtx. Note, however, that it unshares only a
single level of rtl. Thus, if the part to be changed is not at the
top level, you'll need to replace first the top level.
It is not necessary for this macro to come up with a legitimate
address; but often a machine-dependent strategy can generate better code.

— Macro: GO_IF_MODE_DEPENDENT_ADDRESS (addr, label)

A C statement or compound statement with a conditional goto
label; executed if memory address x (an RTX) can have
different meanings depending on the machine mode of the memory
reference it is used for or if the address is valid for some modes
but not others.

Autoincrement and autodecrement addresses typically have mode-dependent
effects because the amount of the increment or decrement is the size
of the operand being addressed. Some machines have other mode-dependent
addresses. Many RISC machines have no mode-dependent addresses.

You may assume that addr is a valid address for the machine.

— Macro: LEGITIMATE_CONSTANT_P (x)

A C expression that is nonzero if x is a legitimate constant for
an immediate operand on the target machine. You can assume that
x satisfies CONSTANT_P, so you need not check this. In fact,
`1' is a suitable definition for this macro on machines where
anything CONSTANT_P is valid.

— Target Hook: rtx TARGET_DELEGITIMIZE_ADDRESS (rtx x)

This hook is used to undo the possibly obfuscating effects of the
LEGITIMIZE_ADDRESS and LEGITIMIZE_RELOAD_ADDRESS target
macros. Some backend implementations of these macros wrap symbol
references inside an UNSPEC rtx to represent PIC or similar
addressing modes. This target hook allows GCC's optimizers to understand
the semantics of these opaque UNSPECs by converting them back
into their original form.

— Target Hook: bool TARGET_CANNOT_FORCE_CONST_MEM (rtx x)

This hook should return true if x is of a form that cannot (or
should not) be spilled to the constant pool. The default version of
this hook returns false.

The primary reason to define this hook is to prevent reload from
deciding that a non-legitimate constant would be better reloaded
from the constant pool instead of spilling and reloading a register
holding the constant. This restriction is often true of addresses
of TLS symbols for various targets.

This hook should return the DECL of a function that implements reciprocal of
the builtin function with builtin function code fn, or
NULL_TREE if such a function is not available. tm_fn is true
when fn is a code of a machine-dependent builtin function. When
sqrt is true, additional optimizations that apply only to the reciprocal
of a square root function are performed, and only reciprocals of sqrt
function are valid.

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD (void)

This hook should return the DECL of a function f that given an
address addr as an argument returns a mask m that can be
used to extract from two vectors the relevant data that resides in
addr in case addr is not properly aligned.

The autovectorizer, when vectorizing a load operation from an address
addr that may be unaligned, will generate two vector loads from
the two aligned addresses around addr. It then generates a
REALIGN_LOAD operation to extract the relevant data from the
two loaded vectors. The first two arguments to REALIGN_LOAD,
v1 and v2, are the two vectors, each of size VS, and
the third argument, OFF, defines how the data will be extracted
from these two vectors: if OFF is 0, then the returned vector is
v2; otherwise, the returned vector is composed from the last
VS-OFF elements of v1 concatenated to the first
OFF elements of v2.

If this hook is defined, the autovectorizer will generate a call
to f (using the DECL tree that this hook returns) and will
use the return value of f as the argument OFF to
REALIGN_LOAD. Therefore, the mask m returned by f
should comply with the semantics expected by REALIGN_LOAD
described above.
If this hook is not defined, then addr will be used as
the argument OFF to REALIGN_LOAD, in which case the low
log2(VS)-1 bits of addr will be considered.

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN (tree x)

This hook should return the DECL of a function f that implements
widening multiplication of the even elements of two input vectors of type x.

If this hook is defined, the autovectorizer will use it along with the
TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD target hook when vectorizing
widening multiplication in cases that the order of the results does not have to be
preserved (e.g. used only by a reduction computation). Otherwise, the
widen_mult_hi/lo idioms will be used.

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD (tree x)

This hook should return the DECL of a function f that implements
widening multiplication of the odd elements of two input vectors of type x.

If this hook is defined, the autovectorizer will use it along with the
TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN target hook when vectorizing
widening multiplication in cases that the order of the results does not have to be
preserved (e.g. used only by a reduction computation). Otherwise, the
widen_mult_hi/lo idioms will be used.

This hook should return the DECL of a function that implements conversion of the
input vector of type type.
If type is an integral type, the result of the conversion is a vector of
floating-point type of the same size.
If type is a floating-point type, the result of the conversion is a vector
of integral type of the same size.
code specifies how the conversion is to be applied
(truncation, rounding, etc.).

If this hook is defined, the autovectorizer will use the
TARGET_VECTORIZE_BUILTIN_CONVERSION target hook when vectorizing
conversion. Otherwise, it will return NULL_TREE.

This hook should return the decl of a function that implements the vectorized
variant of the builtin function with builtin function code code or
NULL_TREE if such a function is not available. The return type of
the vectorized function shall be of vector type vec_type_out and the
argument types should be vec_type_in.