This page contains information that is likely needed when writing a back end but isn't part of the GCC internals documentation.
Misc operand preparations
In a machine description, it is often necessary (or at least desirable) to use preparation statements to adjust instruction operands to match the capabilities of the machine. There are useful functions in emit-rtl.c, explow.c and simplify-rtx.c for that.
- rtx force_reg (enum machine_mode mode, rtx x)
Emit insns to load X into a register if it is not already one. The register is marked as a "constant" register and must not be altered (http://gcc.gnu.org/onlinedocs/gccint/Expander-Definitions.html example).
- rtx make_safe_from (rtx x, rtx other)
Emit insns to copy X if necessary so that it won't be altered by changes in OTHER. Return X or the rtx for the pseudo reg the value of X was copied into (http://gcc.gnu.org/onlinedocs/gccint/Expander-Definitions.html example).
- rtx copy_to_mode_reg (enum machine_mode mode, rtx x)
- Emit insns to copy the value or contents of X to a new temp reg and return that reg.
- rtx copy_addr_to_reg (rtx x)
- Equivalent to copy_to_mode_reg (Pmode, x). For example, this function can be used to compute a complex address X in a register for an instruction which supports only register indirect addressing. See also replace_equiv_address() below.
- rtx simplify_gen_subreg (enum machine_mode outermode, rtx op, enum machine_mode innermode, unsigned int byte)
Create a (subreg:OUTERMODE (OP:INNERMODE) BYTE) expression, simplified as much as possible. OP need not be a register; it can be a subreg, a memory reference or a constant as well. The result is not necessarily a subreg expression. NULL_RTX is returned if the requested subreg is not valid.
Memory references contain attributes such as alignment and alias set that needs to be correct to avoid missing or incorrect optimizations. Several functions in emit-rtl.c are available to create or manipulate memory references such that the attributes are set correctly.
Creating a new memory reference
- rtx gen_rtx_MEM (enum machine_mode mode, rtx addr)
- Generate a MEM expression with all attributes cleared.
- rtx gen_const_mem (enum machine_mode mode, rtx addr)
- Generate a MEM referring to non-trapping constant memory.
- rtx gen_frame_mem (enum machine_mode mode, rtx addr)
- Generate a MEM referring to fixed portions of the frame, e.g., register save areas.
- rtx gen_tmp_stack_mem (enum machine_mode mode, rtx addr)
- Generate a MEM referring to a temporary use of the stack, not part of the fixed stack frame. For example, something which is pushed by a target splitter.
Modifying a memory reference
- rtx change_address (rtx memref, enum machine_mode mode, rtx addr)
- Return a memory reference like MEMREF, but with its mode changed to MODE and its address changed to ADDR. Preserve just the alias set.
- rtx offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
- Return a memory reference like MEMREF, but whose address is changed by adding OFFSET, an RTX, to it. POW2 is the highest power of two factor known to be in OFFSET (possibly 1).
- rtx replace_equiv_address (rtx memref, rtx addr)
- Return a memory reference like MEMREF, but with its address changed to ADDR. The actual piece of memory pointed to must be the same, but the address may have been e.g. copied to a register or simplified in some way. See also copy_addr_to_reg() above.
- rtx replace_equiv_address_nv (rtx memref, rtx addr)
- Likewise, but the reference is not required to be valid.
- rtx widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
- Return a memory reference like MEMREF, but with its mode widened to MODE and offset by OFFSET.
A pitfall of GCC is that constants are signed. For example, using GEN_INT (0x80000000) to generate a 32-bit constant gives you a broken compiler when GCC is built on a 64-bit system but it happens to work when GCC is built on a 32-bit system. Either make sure you only pass signed values to GEN_INT() or use the helper functions such as these from emit-rtl.c and explow.c.
- rtx gen_int_mode (HOST_WIDE_INT c, enum machine_mode mode)
- Generate a CONST_INT with the value C correctly sign extended to MODE.
- HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT c, enum machine_mode mode)
- Truncate and perhaps sign-extend C as appropriate for MODE.
- rtx plus_constant (rtx x, HOST_WIDE_INT c)
- Return an rtx for the sum of X and the integer C.