PREV UP NEXT Using and Porting GNU CC

16.11: Addressing Modes

HAVE_POST_INCREMENT
Define this macro if the machine supports post-increment addressing.
HAVE_PRE_INCREMENT
HAVE_POST_DECREMENT
HAVE_PRE_DECREMENT
Similar for other kinds of addressing.
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.

CONSTANT_P 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.

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.
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 macro 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.

The best way to modify the name string is by adding text to the beginning, with suitable punctuation to prevent any ambiguity. Allocate the new name in saveable_obstack. You will have to modify ASM_OUTPUT_LABELREF to remove and decode the added text and output the name accordingly, and define STRIP_NAME_ENCODING to access the original name string.

You can check the information stored here into the symbol_ref in the definitions of the macros GO_IF_LEGITIMATE_ADDRESS and PRINT_OPERAND_ADDRESS.

REG_OK_FOR_BASE_P (x)
A C expression that is nonzero if x (assumed to be a reg RTX) is valid for use as a base register. For hard registers, it should always accept those which the hardware permits and reject the others. Whether the macro accepts or rejects pseudo registers must be controlled by REG_OK_STRICT as described above. This usually requires two variant definitions, of which REG_OK_STRICT controls the one actually used.
REG_OK_FOR_INDEX_P (x)
A C expression that is nonzero if x (assumed to be a reg RTX) is valid for use as an index register.

The difference between an index register and a base register is that the index register may be scaled. If an address involves the sum of two registers, neither one of them scaled, then either one may be labeled the ``base'' and the other the ``index''; but whichever labeling is used must fit the machine's constraints of which registers may serve in each capacity. The compiler will try both labelings, looking for one that is valid, and will reload one or both registers only if neither labeling works.

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 for this macro to do nothing. But often a machine-dependent strategy can generate better code.

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.

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.