mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-14 17:20:59 +08:00
sphinx: use tm.rst.in file in target macros
gcc/ChangeLog: * doc/gccint/target-macros/adding-support-for-named-address-spaces.rst: Use tm.rst.in file. * doc/gccint/target-macros/addressing-modes.rst: Likewise. * doc/gccint/target-macros/adjusting-the-instruction-scheduler.rst: Likewise. * doc/gccint/target-macros/anchored-addresses.rst: Likewise. * doc/gccint/target-macros/c++-abi-parameters.rst: Likewise. * doc/gccint/target-macros/condition-code-status.rst: Likewise. * doc/gccint/target-macros/controlling-debugging-information-format.rst: Likewise. * doc/gccint/target-macros/controlling-the-compilation-driver-gcc.rst: Likewise. * doc/gccint/target-macros/d-abi-parameters.rst: Likewise. * doc/gccint/target-macros/defining-target-specific-uses-of-attribute.rst: Likewise. * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-exception-regions.rst: Likewise. * doc/gccint/target-macros/defining-the-output-assembler-language/macros-controlling-initialization-routines.rst: Likewise. * doc/gccint/target-macros/defining-the-output-assembler-language/output-and-generation-of-labels.rst: Likewise. * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-assembler-instructions.rst: Likewise. * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-data.rst: Likewise. * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-dispatch-tables.rst: Likewise. * doc/gccint/target-macros/defining-the-output-assembler-language/the-overall-framework-of-an-assembler-file.rst: Likewise. * doc/gccint/target-macros/describing-relative-costs-of-operations.rst: Likewise. * doc/gccint/target-macros/dividing-the-output-into-sections-texts-data.rst: Likewise. * doc/gccint/target-macros/emulating-tls.rst: Likewise. * doc/gccint/target-macros/implementing-the-varargs-macros.rst: Likewise. * doc/gccint/target-macros/implicit-calls-to-library-routines.rst: Likewise. * doc/gccint/target-macros/layout-of-source-language-data-types.rst: Likewise. * doc/gccint/target-macros/miscellaneous-parameters.rst: Likewise. * doc/gccint/target-macros/mode-switching-instructions.rst: Likewise. * doc/gccint/target-macros/parameters-for-precompiled-header-validity-checking.rst: Likewise. * doc/gccint/target-macros/register-classes.rst: Likewise. * doc/gccint/target-macros/register-usage.rst: Likewise. * doc/gccint/target-macros/run-time-target-specification.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/basic-stack-layout.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/eliminating-frame-pointer-and-arg-pointer.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/function-entry-and-exit.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/generating-code-for-profiling.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-large-values-are-returned.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-scalar-function-values-are-returned.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/miscellaneous-register-hooks.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-arguments-in-registers.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-function-arguments-on-the-stack.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/permitting-tail-calls.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/registers-that-address-the-stack-frame.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/shrink-wrapping-separate-components.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/specifying-how-stack-checking-is-done.rst: Likewise. * doc/gccint/target-macros/stack-layout-and-calling-conventions/stack-smashing-protection.rst: Likewise. * doc/gccint/target-macros/storage-layout.rst: Likewise. * doc/gccint/target-macros/support-for-nested-functions.rst: Likewise.
This commit is contained in:
parent
c8874c5e8a
commit
8f2b513c28
@ -45,119 +45,51 @@ named address space #1:
|
||||
#define ADDR_SPACE_EA 1
|
||||
c_register_addr_space ("__ea", ADDR_SPACE_EA);
|
||||
|
||||
.. function:: scalar_int_mode TARGET_ADDR_SPACE_POINTER_MODE (addr_space_t address_space)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_POINTER_MODE]
|
||||
:end-before: [TARGET_ADDR_SPACE_POINTER_MODE]
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_POINTER_MODE
|
||||
|
||||
Define this to return the machine mode to use for pointers to
|
||||
:samp:`{address_space}` if the target supports named address spaces.
|
||||
The default version of this hook returns ``ptr_mode``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_ADDRESS_MODE]
|
||||
:end-before: [TARGET_ADDR_SPACE_ADDRESS_MODE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: scalar_int_mode TARGET_ADDR_SPACE_ADDRESS_MODE (addr_space_t address_space)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_VALID_POINTER_MODE]
|
||||
:end-before: [TARGET_ADDR_SPACE_VALID_POINTER_MODE]
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_ADDRESS_MODE
|
||||
|
||||
Define this to return the machine mode to use for addresses in
|
||||
:samp:`{address_space}` if the target supports named address spaces.
|
||||
The default version of this hook returns ``Pmode``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P]
|
||||
:end-before: [TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ADDR_SPACE_VALID_POINTER_MODE (scalar_int_mode mode, addr_space_t as)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS]
|
||||
:end-before: [TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS]
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_VALID_POINTER_MODE
|
||||
|
||||
Define this to return nonzero if the port can handle pointers
|
||||
with machine mode :samp:`{mode}` to address space :samp:`{as}`. This target
|
||||
hook is the same as the ``TARGET_VALID_POINTER_MODE`` target hook,
|
||||
except that it includes explicit named address space support. The default
|
||||
version of this hook returns true for the modes returned by either the
|
||||
``TARGET_ADDR_SPACE_POINTER_MODE`` or ``TARGET_ADDR_SPACE_ADDRESS_MODE``
|
||||
target hooks for the given address space.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_SUBSET_P]
|
||||
:end-before: [TARGET_ADDR_SPACE_SUBSET_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P (machine_mode mode, rtx exp, bool strict, addr_space_t as)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID]
|
||||
:end-before: [TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID]
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
|
||||
|
||||
Define this to return true if :samp:`{exp}` is a valid address for mode
|
||||
:samp:`{mode}` in the named address space :samp:`{as}`. The :samp:`{strict}`
|
||||
parameter says whether strict addressing is in effect after reload has
|
||||
finished. This target hook is the same as the
|
||||
``TARGET_LEGITIMATE_ADDRESS_P`` target hook, except that it includes
|
||||
explicit named address space support.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_CONVERT]
|
||||
:end-before: [TARGET_ADDR_SPACE_CONVERT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS (rtx x, rtx oldx, machine_mode mode, addr_space_t as)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_DEBUG]
|
||||
:end-before: [TARGET_ADDR_SPACE_DEBUG]
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
|
||||
|
||||
Define this to modify an invalid address :samp:`{x}` to be a valid address
|
||||
with mode :samp:`{mode}` in the named address space :samp:`{as}`. This target
|
||||
hook is the same as the ``TARGET_LEGITIMIZE_ADDRESS`` target hook,
|
||||
except that it includes explicit named address space support.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ADDR_SPACE_SUBSET_P (addr_space_t subset, addr_space_t superset)
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_SUBSET_P
|
||||
|
||||
Define this to return whether the :samp:`{subset}` named address space is
|
||||
contained within the :samp:`{superset}` named address space. Pointers to
|
||||
a named address space that is a subset of another named address space
|
||||
will be converted automatically without a cast if used together in
|
||||
arithmetic operations. Pointers to a superset address space can be
|
||||
converted to pointers to a subset address space via explicit casts.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID (addr_space_t as)
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
|
||||
|
||||
Define this to modify the default handling of address 0 for the
|
||||
address space. Return true if 0 should be considered a valid address.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx TARGET_ADDR_SPACE_CONVERT (rtx op, tree from_type, tree to_type)
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_CONVERT
|
||||
|
||||
Define this to convert the pointer expression represented by the RTL
|
||||
:samp:`{op}` with type :samp:`{from_type}` that points to a named address
|
||||
space to a new pointer expression with type :samp:`{to_type}` that points
|
||||
to a different named address space. When this hook it called, it is
|
||||
guaranteed that one of the two address spaces is a subset of the other,
|
||||
as determined by the ``TARGET_ADDR_SPACE_SUBSET_P`` target hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_ADDR_SPACE_DEBUG (addr_space_t as)
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_DEBUG
|
||||
|
||||
Define this to define how the address space is encoded in dwarf.
|
||||
The result is the value to be used with ``DW_AT_address_class``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ADDR_SPACE_DIAGNOSE_USAGE (addr_space_t as, location_t loc)
|
||||
|
||||
.. hook-start:TARGET_ADDR_SPACE_DIAGNOSE_USAGE
|
||||
|
||||
Define this hook if the availability of an address space depends on
|
||||
command line options and some diagnostics should be printed when the
|
||||
address space is used. This hook is called during parsing and allows
|
||||
to emit a better diagnostic compared to the case where the address space
|
||||
was not registered with ``c_register_addr_space``. :samp:`{as}` is
|
||||
the address space as registered with ``c_register_addr_space``.
|
||||
:samp:`{loc}` is the location of the address space qualifier token.
|
||||
The default implementation does nothing.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDR_SPACE_DIAGNOSE_USAGE]
|
||||
:end-before: [TARGET_ADDR_SPACE_DIAGNOSE_USAGE]
|
||||
|
@ -58,75 +58,10 @@ This is about addressing modes.
|
||||
the maximum number that ``TARGET_LEGITIMATE_ADDRESS_P`` would ever
|
||||
accept.
|
||||
|
||||
.. function:: bool TARGET_LEGITIMATE_ADDRESS_P (machine_mode mode, rtx x, bool strict)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LEGITIMATE_ADDRESS_P]
|
||||
:end-before: [TARGET_LEGITIMATE_ADDRESS_P]
|
||||
|
||||
.. hook-start:TARGET_LEGITIMATE_ADDRESS_P
|
||||
|
||||
A function that returns whether :samp:`{x}` (an RTX) is a legitimate memory
|
||||
address on the target machine for a memory operand of mode :samp:`{mode}`.
|
||||
|
||||
Legitimate addresses are defined in two variants: a strict variant and a
|
||||
non-strict one. The :samp:`{strict}` parameter chooses which variant is
|
||||
desired by the caller.
|
||||
|
||||
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. This is because in contexts where some
|
||||
kind of register is required, a pseudo-register with no hard register
|
||||
must be rejected. For non-hard registers, the strict variant should look
|
||||
up the ``reg_renumber`` array; it should then proceed using the hard
|
||||
register number in the array, or treat the pseudo as a memory reference
|
||||
if the array holds ``-1``.
|
||||
|
||||
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.
|
||||
|
||||
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``.
|
||||
|
||||
.. index:: TARGET_ENCODE_SECTION_INFO and address validation
|
||||
|
||||
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 :ref:`assembler-format`.
|
||||
|
||||
.. index:: GO_IF_LEGITIMATE_ADDRESS
|
||||
|
||||
Some ports are still using a deprecated legacy substitute for
|
||||
this hook, the ``GO_IF_LEGITIMATE_ADDRESS`` macro. This macro
|
||||
has this syntax:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#define GO_IF_LEGITIMATE_ADDRESS (mode, x, label)
|
||||
|
||||
and should ``goto label`` if the address :samp:`{x}` is a valid
|
||||
address on the target machine for a memory operand of mode :samp:`{mode}`.
|
||||
|
||||
.. index:: REG_OK_STRICT
|
||||
|
||||
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.
|
||||
|
||||
Using the hook is usually simpler because it limits the number of
|
||||
files that are recompiled when changes are made.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: TARGET_MEM_CONSTRAINT
|
||||
|
||||
@ -152,33 +87,10 @@ This is about addressing modes.
|
||||
The typical use of this macro is to handle addresses containing
|
||||
a label_ref or symbol_ref within an UNSPEC.
|
||||
|
||||
.. function:: rtx TARGET_LEGITIMIZE_ADDRESS (rtx x, rtx oldx, machine_mode mode)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LEGITIMIZE_ADDRESS]
|
||||
:end-before: [TARGET_LEGITIMIZE_ADDRESS]
|
||||
|
||||
.. hook-start:TARGET_LEGITIMIZE_ADDRESS
|
||||
|
||||
This hook is given an invalid memory address :samp:`{x}` for an
|
||||
operand of mode :samp:`{mode}` and should try to return a valid memory
|
||||
address.
|
||||
|
||||
.. index:: break_out_memory_refs
|
||||
|
||||
:samp:`{x}` will always be the result of a call to ``break_out_memory_refs``,
|
||||
and :samp:`{oldx}` will be the operand that was given to that function to produce
|
||||
:samp:`{x}`.
|
||||
|
||||
The code of the hook should not alter the substructure of
|
||||
:samp:`{x}`. If it transforms :samp:`{x}` into a more legitimate form, it
|
||||
should return the new :samp:`{x}`.
|
||||
|
||||
It is not necessary for this hook to come up with a legitimate address,
|
||||
with the exception of native TLS addresses (see :ref:`emulated-tls`).
|
||||
The compiler has standard ways of doing so in all cases. In fact, if
|
||||
the target supports only emulated TLS, it
|
||||
is safe to omit this hook or make it return :samp:`{x}` if it cannot find
|
||||
a valid way to legitimize the address. But often a machine-dependent
|
||||
strategy can generate better code.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: LEGITIMIZE_RELOAD_ADDRESS (x, mode, opnum, type, ind_levels, win)
|
||||
|
||||
@ -236,589 +148,201 @@ This is about addressing modes.
|
||||
It is not necessary for this macro to come up with a legitimate
|
||||
address; but often a machine-dependent strategy can generate better code.
|
||||
|
||||
.. function:: bool TARGET_MODE_DEPENDENT_ADDRESS_P (const_rtx addr, addr_space_t addrspace)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MODE_DEPENDENT_ADDRESS_P]
|
||||
:end-before: [TARGET_MODE_DEPENDENT_ADDRESS_P]
|
||||
|
||||
.. hook-start:TARGET_MODE_DEPENDENT_ADDRESS_P
|
||||
|
||||
This hook returns ``true`` if memory address :samp:`{addr}` in address
|
||||
space :samp:`{addrspace}` 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.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LEGITIMATE_CONSTANT_P]
|
||||
:end-before: [TARGET_LEGITIMATE_CONSTANT_P]
|
||||
|
||||
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 :samp:`{addr}` is a valid address for the machine.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PRECOMPUTE_TLS_P]
|
||||
:end-before: [TARGET_PRECOMPUTE_TLS_P]
|
||||
|
||||
The default version of this hook returns ``false``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DELEGITIMIZE_ADDRESS]
|
||||
:end-before: [TARGET_DELEGITIMIZE_ADDRESS]
|
||||
|
||||
.. function:: bool TARGET_LEGITIMATE_CONSTANT_P (machine_mode mode, rtx x)
|
||||
|
||||
.. hook-start:TARGET_LEGITIMATE_CONSTANT_P
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CONST_NOT_OK_FOR_DEBUG_P]
|
||||
:end-before: [TARGET_CONST_NOT_OK_FOR_DEBUG_P]
|
||||
|
||||
This hook returns true if :samp:`{x}` is a legitimate constant for a
|
||||
:samp:`{mode}` -mode immediate operand on the target machine. You can assume that
|
||||
:samp:`{x}` satisfies ``CONSTANT_P``, so you need not check this.
|
||||
|
||||
The default definition returns true.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CANNOT_FORCE_CONST_MEM]
|
||||
:end-before: [TARGET_CANNOT_FORCE_CONST_MEM]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_PRECOMPUTE_TLS_P (machine_mode mode, rtx x)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_USE_BLOCKS_FOR_CONSTANT_P]
|
||||
:end-before: [TARGET_USE_BLOCKS_FOR_CONSTANT_P]
|
||||
|
||||
.. hook-start:TARGET_PRECOMPUTE_TLS_P
|
||||
|
||||
This hook returns true if :samp:`{x}` is a TLS operand on the target
|
||||
machine that should be pre-computed when used as the argument in a call.
|
||||
You can assume that :samp:`{x}` satisfies ``CONSTANT_P``, so you need not
|
||||
check this.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_USE_BLOCKS_FOR_DECL_P]
|
||||
:end-before: [TARGET_USE_BLOCKS_FOR_DECL_P]
|
||||
|
||||
The default definition returns false.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_BUILTIN_RECIPROCAL]
|
||||
:end-before: [TARGET_BUILTIN_RECIPROCAL]
|
||||
|
||||
.. function:: rtx TARGET_DELEGITIMIZE_ADDRESS (rtx x)
|
||||
|
||||
.. hook-start:TARGET_DELEGITIMIZE_ADDRESS
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD]
|
||||
:end-before: [TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD]
|
||||
|
||||
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 ``UNSPEC`` s by converting them back
|
||||
into their original form.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST]
|
||||
:end-before: [TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST]
|
||||
|
||||
.. function:: bool TARGET_CONST_NOT_OK_FOR_DEBUG_P (rtx x)
|
||||
|
||||
.. hook-start:TARGET_CONST_NOT_OK_FOR_DEBUG_P
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT]
|
||||
:end-before: [TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT]
|
||||
|
||||
This hook should return true if :samp:`{x}` should not be emitted into
|
||||
debug sections.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE]
|
||||
:end-before: [TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE]
|
||||
|
||||
.. function:: bool TARGET_CANNOT_FORCE_CONST_MEM (machine_mode mode, rtx x)
|
||||
|
||||
.. hook-start:TARGET_CANNOT_FORCE_CONST_MEM
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_VEC_PERM_CONST]
|
||||
:end-before: [TARGET_VECTORIZE_VEC_PERM_CONST]
|
||||
|
||||
This hook should return true if :samp:`{x}` is of a form that cannot (or
|
||||
should not) be spilled to the constant pool. :samp:`{mode}` is the mode
|
||||
of :samp:`{x}`.
|
||||
|
||||
The default version of this hook returns false.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION]
|
||||
:end-before: [TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION]
|
||||
|
||||
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.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION]
|
||||
:end-before: [TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION]
|
||||
|
||||
.. function:: bool TARGET_USE_BLOCKS_FOR_CONSTANT_P (machine_mode mode, const_rtx x)
|
||||
|
||||
.. hook-start:TARGET_USE_BLOCKS_FOR_CONSTANT_P
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT]
|
||||
:end-before: [TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT]
|
||||
|
||||
This hook should return true if pool entries for constant :samp:`{x}` can
|
||||
be placed in an ``object_block`` structure. :samp:`{mode}` is the mode
|
||||
of :samp:`{x}`.
|
||||
|
||||
The default version returns false for all constants.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_PREFERRED_SIMD_MODE]
|
||||
:end-before: [TARGET_VECTORIZE_PREFERRED_SIMD_MODE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_USE_BLOCKS_FOR_DECL_P (const_tree decl)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_SPLIT_REDUCTION]
|
||||
:end-before: [TARGET_VECTORIZE_SPLIT_REDUCTION]
|
||||
|
||||
.. hook-start:TARGET_USE_BLOCKS_FOR_DECL_P
|
||||
|
||||
This hook should return true if pool entries for :samp:`{decl}` should
|
||||
be placed in an ``object_block`` structure.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES]
|
||||
:end-before: [TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES]
|
||||
|
||||
The default version returns true for all decls.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_RELATED_MODE]
|
||||
:end-before: [TARGET_VECTORIZE_RELATED_MODE]
|
||||
|
||||
.. function:: tree TARGET_BUILTIN_RECIPROCAL (tree fndecl)
|
||||
|
||||
.. hook-start:TARGET_BUILTIN_RECIPROCAL
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_GET_MASK_MODE]
|
||||
:end-before: [TARGET_VECTORIZE_GET_MASK_MODE]
|
||||
|
||||
This hook should return the DECL of a function that implements the
|
||||
reciprocal of the machine-specific builtin function :samp:`{fndecl}`, or
|
||||
``NULL_TREE`` if such a function is not available.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE]
|
||||
:end-before: [TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE]
|
||||
|
||||
.. function:: tree TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD (void)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_CREATE_COSTS]
|
||||
:end-before: [TARGET_VECTORIZE_CREATE_COSTS]
|
||||
|
||||
This hook should return the DECL of a function :samp:`{f}` that given an
|
||||
address :samp:`{addr}` as an argument returns a mask :samp:`{m}` that can be
|
||||
used to extract from two vectors the relevant data that resides in
|
||||
:samp:`{addr}` in case :samp:`{addr}` is not properly aligned.
|
||||
|
||||
The autovectorizer, when vectorizing a load operation from an address
|
||||
:samp:`{addr}` that may be unaligned, will generate two vector loads from
|
||||
the two aligned addresses around :samp:`{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``,
|
||||
:samp:`{v1}` and :samp:`{v2}`, are the two vectors, each of size :samp:`{VS}`, and
|
||||
the third argument, :samp:`{OFF}`, defines how the data will be extracted
|
||||
from these two vectors: if :samp:`{OFF}` is 0, then the returned vector is
|
||||
:samp:`{v2}` ; otherwise, the returned vector is composed from the last
|
||||
:samp:`{VS}` - :samp:`{OFF}` elements of :samp:`{v1}` concatenated to the first
|
||||
:samp:`{OFF}` elements of :samp:`{v2}`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_BUILTIN_GATHER]
|
||||
:end-before: [TARGET_VECTORIZE_BUILTIN_GATHER]
|
||||
|
||||
If this hook is defined, the autovectorizer will generate a call
|
||||
to :samp:`{f}` (using the DECL tree that this hook returns) and will
|
||||
use the return value of :samp:`{f}` as the argument :samp:`{OFF}` to
|
||||
``REALIGN_LOAD``. Therefore, the mask :samp:`{m}` returned by :samp:`{f}`
|
||||
should comply with the semantics expected by ``REALIGN_LOAD``
|
||||
described above.
|
||||
If this hook is not defined, then :samp:`{addr}` will be used as
|
||||
the argument :samp:`{OFF}` to ``REALIGN_LOAD``, in which case the low
|
||||
log2(:samp:`{VS}`) - 1 bits of :samp:`{addr}` will be considered.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTORIZE_BUILTIN_SCATTER]
|
||||
:end-before: [TARGET_VECTORIZE_BUILTIN_SCATTER]
|
||||
|
||||
.. function:: int TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST (enum vect_cost_for_stmt type_of_cost, tree vectype, int misalign)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN]
|
||||
:end-before: [TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN]
|
||||
|
||||
Returns cost of different scalar or vector statements for vectorization cost model.
|
||||
For vector memory operations the cost may depend on type (:samp:`{vectype}`) and
|
||||
misalignment value (:samp:`{misalign}`).
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SIMD_CLONE_ADJUST]
|
||||
:end-before: [TARGET_SIMD_CLONE_ADJUST]
|
||||
|
||||
.. function:: poly_uint64 TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT (const_tree type)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SIMD_CLONE_USABLE]
|
||||
:end-before: [TARGET_SIMD_CLONE_USABLE]
|
||||
|
||||
This hook returns the preferred alignment in bits for accesses to
|
||||
vectors of type :samp:`{type}` in vectorized code. This might be less than
|
||||
or greater than the ABI-defined value returned by
|
||||
``TARGET_VECTOR_ALIGNMENT``. It can be equal to the alignment of
|
||||
a single element, in which case the vectorizer will not try to optimize
|
||||
for alignment.
|
||||
|
||||
The default hook returns ``TYPE_ALIGN (type)``, which is
|
||||
correct for most targets.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SIMT_VF]
|
||||
:end-before: [TARGET_SIMT_VF]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE (const_tree type, bool is_packed)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OMP_DEVICE_KIND_ARCH_ISA]
|
||||
:end-before: [TARGET_OMP_DEVICE_KIND_ARCH_ISA]
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
|
||||
|
||||
Return true if vector alignment is reachable (by peeling N iterations)
|
||||
for the given scalar type :samp:`{type}`. :samp:`{is_packed}` is false if the scalar
|
||||
access using :samp:`{type}` is known to be naturally aligned.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GOACC_VALIDATE_DIMS]
|
||||
:end-before: [TARGET_GOACC_VALIDATE_DIMS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_VECTORIZE_VEC_PERM_CONST (machine_mode mode, machine_mode op_mode, rtx output, rtx in0, rtx in1, const vec_perm_indices &sel)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GOACC_DIM_LIMIT]
|
||||
:end-before: [TARGET_GOACC_DIM_LIMIT]
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_VEC_PERM_CONST
|
||||
|
||||
This hook is used to test whether the target can permute up to two
|
||||
vectors of mode :samp:`{op_mode}` using the permutation vector ``sel``,
|
||||
producing a vector of mode :samp:`{mode}`. The hook is also used to emit such
|
||||
a permutation.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GOACC_FORK_JOIN]
|
||||
:end-before: [TARGET_GOACC_FORK_JOIN]
|
||||
|
||||
When the hook is being used to test whether the target supports a permutation,
|
||||
:samp:`{in0}`, :samp:`{in1}`, and :samp:`{out}` are all null. When the hook is being used
|
||||
to emit a permutation, :samp:`{in0}` and :samp:`{in1}` are the source vectors of mode
|
||||
:samp:`{op_mode}` and :samp:`{out}` is the destination vector of mode :samp:`{mode}`.
|
||||
:samp:`{in1}` is the same as :samp:`{in0}` if :samp:`{sel}` describes a permutation on one
|
||||
vector instead of two.
|
||||
|
||||
Return true if the operation is possible, emitting instructions for it
|
||||
if rtxes are provided.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GOACC_REDUCTION]
|
||||
:end-before: [TARGET_GOACC_REDUCTION]
|
||||
|
||||
.. index:: vec_permm instruction pattern
|
||||
|
||||
If the hook returns false for a mode with multibyte elements, GCC will
|
||||
try the equivalent byte operation. If that also fails, it will try forcing
|
||||
the selector into a register and using the :samp:`{vec_perm {mode} }`
|
||||
instruction pattern. There is no need for the hook to handle these two
|
||||
implementation approaches itself.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PREFERRED_ELSE_VALUE]
|
||||
:end-before: [TARGET_PREFERRED_ELSE_VALUE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION (unsigned code, tree vec_type_out, tree vec_type_in)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GOACC_ADJUST_PRIVATE_DECL]
|
||||
:end-before: [TARGET_GOACC_ADJUST_PRIVATE_DECL]
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
|
||||
|
||||
This hook should return the decl of a function that implements the
|
||||
vectorized variant of the function with the ``combined_fn`` code
|
||||
:samp:`{code}` or ``NULL_TREE`` if such a function is not available.
|
||||
The return type of the vectorized function shall be of vector type
|
||||
:samp:`{vec_type_out}` and the argument types should be :samp:`{vec_type_in}`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GOACC_EXPAND_VAR_DECL]
|
||||
:end-before: [TARGET_GOACC_EXPAND_VAR_DECL]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION (tree fndecl, tree vec_type_out, tree vec_type_in)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GOACC_CREATE_WORKER_BROADCAST_RECORD]
|
||||
:end-before: [TARGET_GOACC_CREATE_WORKER_BROADCAST_RECORD]
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION
|
||||
|
||||
This hook should return the decl of a function that implements the
|
||||
vectorized variant of target built-in function ``fndecl``. The
|
||||
return type of the vectorized function shall be of vector type
|
||||
:samp:`{vec_type_out}` and the argument types should be :samp:`{vec_type_in}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT (machine_mode mode, const_tree type, int misalignment, bool is_packed)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
|
||||
|
||||
This hook should return true if the target supports misaligned vector
|
||||
store/load of a specific factor denoted in the :samp:`{misalignment}`
|
||||
parameter. The vector store/load should be of machine mode :samp:`{mode}` and
|
||||
the elements in the vectors should be of type :samp:`{type}`. :samp:`{is_packed}`
|
||||
parameter is true if the memory access is defined in a packed struct.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: machine_mode TARGET_VECTORIZE_PREFERRED_SIMD_MODE (scalar_mode mode)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_PREFERRED_SIMD_MODE
|
||||
|
||||
This hook should return the preferred mode for vectorizing scalar
|
||||
mode :samp:`{mode}`. The default is
|
||||
equal to ``word_mode``, because the vectorizer can do some
|
||||
transformations even in absence of specialized SIMD hardware.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: machine_mode TARGET_VECTORIZE_SPLIT_REDUCTION (machine_mode)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_SPLIT_REDUCTION
|
||||
|
||||
This hook should return the preferred mode to split the final reduction
|
||||
step on :samp:`{mode}` to. The reduction is then carried out reducing upper
|
||||
against lower halves of vectors recursively until the specified mode is
|
||||
reached. The default is :samp:`{mode}` which means no splitting.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: unsigned int TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES (vector_modes *modes, bool all)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
|
||||
|
||||
If using the mode returned by ``TARGET_VECTORIZE_PREFERRED_SIMD_MODE``
|
||||
is not the only approach worth considering, this hook should add one mode to
|
||||
:samp:`{modes}` for each useful alternative approach. These modes are then
|
||||
passed to ``TARGET_VECTORIZE_RELATED_MODE`` to obtain the vector mode
|
||||
for a given element mode.
|
||||
|
||||
The modes returned in :samp:`{modes}` should use the smallest element mode
|
||||
possible for the vectorization approach that they represent, preferring
|
||||
integer modes over floating-poing modes in the event of a tie. The first
|
||||
mode should be the ``TARGET_VECTORIZE_PREFERRED_SIMD_MODE`` for its
|
||||
element mode.
|
||||
|
||||
If :samp:`{all}` is true, add suitable vector modes even when they are generally
|
||||
not expected to be worthwhile.
|
||||
|
||||
The hook returns a bitmask of flags that control how the modes in
|
||||
:samp:`{modes}` are used. The flags are:
|
||||
|
||||
.. envvar:: VECT_COMPARE_COSTS
|
||||
|
||||
Tells the loop vectorizer to try all the provided modes and pick the one
|
||||
with the lowest cost. By default the vectorizer will choose the first
|
||||
mode that works.
|
||||
|
||||
The hook does not need to do anything if the vector returned by
|
||||
``TARGET_VECTORIZE_PREFERRED_SIMD_MODE`` is the only one relevant
|
||||
for autovectorization. The default implementation adds no modes and
|
||||
returns 0.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: opt_machine_mode TARGET_VECTORIZE_RELATED_MODE (machine_mode vector_mode, scalar_mode element_mode, poly_uint64 nunits)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_RELATED_MODE
|
||||
|
||||
If a piece of code is using vector mode :samp:`{vector_mode}` and also wants
|
||||
to operate on elements of mode :samp:`{element_mode}`, return the vector mode
|
||||
it should use for those elements. If :samp:`{nunits}` is nonzero, ensure that
|
||||
the mode has exactly :samp:`{nunits}` elements, otherwise pick whichever vector
|
||||
size pairs the most naturally with :samp:`{vector_mode}`. Return an empty
|
||||
``opt_machine_mode`` if there is no supported vector mode with the
|
||||
required properties.
|
||||
|
||||
There is no prescribed way of handling the case in which :samp:`{nunits}`
|
||||
is zero. One common choice is to pick a vector mode with the same size
|
||||
as :samp:`{vector_mode}` ; this is the natural choice if the target has a
|
||||
fixed vector size. Another option is to choose a vector mode with the
|
||||
same number of elements as :samp:`{vector_mode}` ; this is the natural choice
|
||||
if the target has a fixed number of elements. Alternatively, the hook
|
||||
might choose a middle ground, such as trying to keep the number of
|
||||
elements as similar as possible while applying maximum and minimum
|
||||
vector sizes.
|
||||
|
||||
The default implementation uses ``mode_for_vector`` to find the
|
||||
requested mode, returning a mode with the same size as :samp:`{vector_mode}`
|
||||
when :samp:`{nunits}` is zero. This is the correct behavior for most targets.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: opt_machine_mode TARGET_VECTORIZE_GET_MASK_MODE (machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_GET_MASK_MODE
|
||||
|
||||
Return the mode to use for a vector mask that holds one boolean
|
||||
result for each element of vector mode :samp:`{mode}`. The returned mask mode
|
||||
can be a vector of integers (class ``MODE_VECTOR_INT``), a vector of
|
||||
booleans (class ``MODE_VECTOR_BOOL``) or a scalar integer (class
|
||||
``MODE_INT``). Return an empty ``opt_machine_mode`` if no such
|
||||
mask mode exists.
|
||||
|
||||
The default implementation returns a ``MODE_VECTOR_INT`` with the
|
||||
same size and number of elements as :samp:`{mode}`, if such a mode exists.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE (unsigned ifn)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE
|
||||
|
||||
This hook returns true if masked internal function :samp:`{ifn}` (really of
|
||||
type ``internal_fn``) should be considered expensive when the mask is
|
||||
all zeros. GCC can then try to branch around the instruction instead.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: class vector_costs * TARGET_VECTORIZE_CREATE_COSTS (vec_info *vinfo, bool costing_for_scalar)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_CREATE_COSTS
|
||||
|
||||
This hook should initialize target-specific data structures in preparation
|
||||
for modeling the costs of vectorizing a loop or basic block. The default
|
||||
allocates three unsigned integers for accumulating costs for the prologue,
|
||||
body, and epilogue of the loop or basic block. If :samp:`{loop_info}` is
|
||||
non-NULL, it identifies the loop being vectorized; otherwise a single block
|
||||
is being vectorized. If :samp:`{costing_for_scalar}` is true, it indicates the
|
||||
current cost model is for the scalar version of a loop or block; otherwise
|
||||
it is for the vector version.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_VECTORIZE_BUILTIN_GATHER (const_tree mem_vectype, const_tree index_type, int scale)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_BUILTIN_GATHER
|
||||
|
||||
Target builtin that implements vector gather operation. :samp:`{mem_vectype}`
|
||||
is the vector type of the load and :samp:`{index_type}` is scalar type of
|
||||
the index, scaled by :samp:`{scale}`.
|
||||
The default is ``NULL_TREE`` which means to not vectorize gather
|
||||
loads.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_VECTORIZE_BUILTIN_SCATTER (const_tree vectype, const_tree index_type, int scale)
|
||||
|
||||
.. hook-start:TARGET_VECTORIZE_BUILTIN_SCATTER
|
||||
|
||||
Target builtin that implements vector scatter operation. :samp:`{vectype}`
|
||||
is the vector type of the store and :samp:`{index_type}` is scalar type of
|
||||
the index, scaled by :samp:`{scale}`.
|
||||
The default is ``NULL_TREE`` which means to not vectorize scatter
|
||||
stores.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN (struct cgraph_node *, struct cgraph_simd_clone *, tree, int)
|
||||
|
||||
.. hook-start:TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
|
||||
|
||||
This hook should set :samp:`{vecsize_mangle}`, :samp:`{vecsize_int}`, :samp:`{vecsize_float}`
|
||||
fields in :samp:`{simd_clone}` structure pointed by :samp:`{clone_info}` argument and also
|
||||
:samp:`{simdlen}` field if it was previously 0.
|
||||
:samp:`{vecsize_mangle}` is a marker for the backend only. :samp:`{vecsize_int}` and
|
||||
:samp:`{vecsize_float}` should be left zero on targets where the number of lanes is
|
||||
not determined by the bitsize (in which case :samp:`{simdlen}` is always used).
|
||||
The hook should return 0 if SIMD clones shouldn't be emitted,
|
||||
or number of :samp:`{vecsize_mangle}` variants that should be emitted.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SIMD_CLONE_ADJUST (struct cgraph_node *)
|
||||
|
||||
.. hook-start:TARGET_SIMD_CLONE_ADJUST
|
||||
|
||||
This hook should add implicit ``attribute(target("..."))`` attribute
|
||||
to SIMD clone :samp:`{node}` if needed.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SIMD_CLONE_USABLE (struct cgraph_node *)
|
||||
|
||||
.. hook-start:TARGET_SIMD_CLONE_USABLE
|
||||
|
||||
This hook should return -1 if SIMD clone :samp:`{node}` shouldn't be used
|
||||
in vectorized loops in current function, or non-negative number if it is
|
||||
usable. In that case, the smaller the number is, the more desirable it is
|
||||
to use it.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SIMT_VF (void)
|
||||
|
||||
.. hook-start:TARGET_SIMT_VF
|
||||
|
||||
Return number of threads in SIMT thread group on the target.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_OMP_DEVICE_KIND_ARCH_ISA (enum omp_device_kind_arch_isa trait, const char *name)
|
||||
|
||||
.. hook-start:TARGET_OMP_DEVICE_KIND_ARCH_ISA
|
||||
|
||||
Return 1 if :samp:`{trait}` :samp:`{name}` is present in the OpenMP context's
|
||||
device trait set, return 0 if not present in any OpenMP context in the
|
||||
whole translation unit, or -1 if not present in the current OpenMP context
|
||||
but might be present in another OpenMP context in the same TU.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_GOACC_VALIDATE_DIMS (tree decl, int *dims, int fn_level, unsigned used)
|
||||
|
||||
.. hook-start:TARGET_GOACC_VALIDATE_DIMS
|
||||
|
||||
This hook should check the launch dimensions provided for an OpenACC
|
||||
compute region, or routine. Defaulted values are represented as -1
|
||||
and non-constant values as 0. The :samp:`{fn_level}` is negative for the
|
||||
function corresponding to the compute region. For a routine it is the
|
||||
outermost level at which partitioned execution may be spawned. The hook
|
||||
should verify non-default values. If DECL is NULL, global defaults
|
||||
are being validated and unspecified defaults should be filled in.
|
||||
Diagnostics should be issued as appropriate. Return
|
||||
true, if changes have been made. You must override this hook to
|
||||
provide dimensions larger than 1.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_GOACC_DIM_LIMIT (int axis)
|
||||
|
||||
.. hook-start:TARGET_GOACC_DIM_LIMIT
|
||||
|
||||
This hook should return the maximum size of a particular dimension,
|
||||
or zero if unbounded.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_GOACC_FORK_JOIN (gcall *call, const int *dims, bool is_fork)
|
||||
|
||||
.. hook-start:TARGET_GOACC_FORK_JOIN
|
||||
|
||||
This hook can be used to convert IFN_GOACC_FORK and IFN_GOACC_JOIN
|
||||
function calls to target-specific gimple, or indicate whether they
|
||||
should be retained. It is executed during the oacc_device_lower pass.
|
||||
It should return true, if the call should be retained. It should
|
||||
return false, if it is to be deleted (either because target-specific
|
||||
gimple has been inserted before it, or there is no need for it).
|
||||
The default hook returns false, if there are no RTL expanders for them.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_GOACC_REDUCTION (gcall *call)
|
||||
|
||||
.. hook-start:TARGET_GOACC_REDUCTION
|
||||
|
||||
This hook is used by the oacc_transform pass to expand calls to the
|
||||
:samp:`{GOACC_REDUCTION}` internal function, into a sequence of gimple
|
||||
instructions. :samp:`{call}` is gimple statement containing the call to
|
||||
the function. This hook removes statement :samp:`{call}` after the
|
||||
expanded sequence has been inserted. This hook is also responsible
|
||||
for allocating any storage for reductions when necessary.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_PREFERRED_ELSE_VALUE (unsigned ifn, tree type, unsigned nops, tree *ops)
|
||||
|
||||
.. hook-start:TARGET_PREFERRED_ELSE_VALUE
|
||||
|
||||
This hook returns the target's preferred final argument for a call
|
||||
to conditional internal function :samp:`{ifn}` (really of type
|
||||
``internal_fn``). :samp:`{type}` specifies the return type of the
|
||||
function and :samp:`{ops}` are the operands to the conditional operation,
|
||||
of which there are :samp:`{nops}`.
|
||||
|
||||
For example, if :samp:`{ifn}` is ``IFN_COND_ADD``, the hook returns
|
||||
a value of type :samp:`{type}` that should be used when :samp:`{ops}[0]`
|
||||
and :samp:`{ops}[1]` are conditionally added together.
|
||||
|
||||
This hook is only relevant if the target supports conditional patterns
|
||||
like ``cond_addm``. The default implementation returns a zero
|
||||
constant of type :samp:`{type}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_GOACC_ADJUST_PRIVATE_DECL (location_t loc, tree var, int level)
|
||||
|
||||
.. hook-start:TARGET_GOACC_ADJUST_PRIVATE_DECL
|
||||
|
||||
This hook, if defined, is used by accelerator target back-ends to adjust
|
||||
OpenACC variable declarations that should be made private to the given
|
||||
parallelism level (i.e. ``GOMP_DIM_GANG``, ``GOMP_DIM_WORKER`` or
|
||||
``GOMP_DIM_VECTOR``). A typical use for this hook is to force variable
|
||||
declarations at the ``gang`` level to reside in GPU shared memory.
|
||||
:samp:`{loc}` may be used for diagnostic purposes.
|
||||
|
||||
You may also use the ``TARGET_GOACC_EXPAND_VAR_DECL`` hook if the
|
||||
adjusted variable declaration needs to be expanded to RTL in a non-standard
|
||||
way.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx TARGET_GOACC_EXPAND_VAR_DECL (tree var)
|
||||
|
||||
.. hook-start:TARGET_GOACC_EXPAND_VAR_DECL
|
||||
|
||||
This hook, if defined, is used by accelerator target back-ends to expand
|
||||
specially handled kinds of ``VAR_DECL`` expressions. A particular use is
|
||||
to place variables with specific attributes inside special accelarator
|
||||
memories. A return value of ``NULL`` indicates that the target does not
|
||||
handle this ``VAR_DECL``, and normal RTL expanding is resumed.
|
||||
|
||||
Only define this hook if your accelerator target needs to expand certain
|
||||
``VAR_DECL`` nodes in a way that differs from the default. You can also adjust
|
||||
private variables at OpenACC device-lowering time using the
|
||||
``TARGET_GOACC_ADJUST_PRIVATE_DECL`` target hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_GOACC_CREATE_WORKER_BROADCAST_RECORD (tree rec, bool sender, const char *name, unsigned HOST_WIDE_INT offset)
|
||||
|
||||
.. hook-start:TARGET_GOACC_CREATE_WORKER_BROADCAST_RECORD
|
||||
|
||||
Create a record used to propagate local-variable state from an active
|
||||
worker to other workers. A possible implementation might adjust the type
|
||||
of REC to place the new variable in shared GPU memory.
|
||||
|
||||
Presence of this target hook indicates that middle end neutering/broadcasting
|
||||
be used.
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_GOACC_SHARED_MEM_LAYOUT (unsigned HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, int[], unsigned HOST_WIDE_INT[], unsigned HOST_WIDE_INT[])
|
||||
|
||||
.. hook-start:TARGET_GOACC_SHARED_MEM_LAYOUT
|
||||
|
||||
Lay out a fixed shared-memory region on the target. The LO and HI
|
||||
arguments should be set to a range of addresses that can be used for worker
|
||||
broadcasting. The dimensions, reduction size and gang-private size
|
||||
arguments are for the current offload region.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GOACC_SHARED_MEM_LAYOUT]
|
||||
:end-before: [TARGET_GOACC_SHARED_MEM_LAYOUT]
|
||||
|
@ -13,648 +13,236 @@ adjustment in order to produce good code. GCC provides several target
|
||||
hooks for this purpose. It is usually enough to define just a few of
|
||||
them: try the first ones in this list first.
|
||||
|
||||
.. function:: int TARGET_SCHED_ISSUE_RATE (void)
|
||||
|
||||
.. hook-start:TARGET_SCHED_ISSUE_RATE
|
||||
|
||||
This hook returns the maximum number of instructions that can ever
|
||||
issue at the same time on the target machine. The default is one.
|
||||
Although the insn scheduler can define itself the possibility of issue
|
||||
an insn on the same cycle, the value can serve as an additional
|
||||
constraint to issue insns on the same simulated processor cycle (see
|
||||
hooks :samp:`TARGET_SCHED_REORDER` and :samp:`TARGET_SCHED_REORDER2`).
|
||||
This value must be constant over the entire compilation. If you need
|
||||
it to vary depending on what the instructions are, you must use
|
||||
:samp:`TARGET_SCHED_VARIABLE_ISSUE`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_ISSUE_RATE]
|
||||
:end-before: [TARGET_SCHED_ISSUE_RATE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_VARIABLE_ISSUE (FILE *file, int verbose, rtx_insn *insn, int more)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_VARIABLE_ISSUE]
|
||||
:end-before: [TARGET_SCHED_VARIABLE_ISSUE]
|
||||
|
||||
.. hook-start:TARGET_SCHED_VARIABLE_ISSUE
|
||||
|
||||
This hook is executed by the scheduler after it has scheduled an insn
|
||||
from the ready list. It should return the number of insns which can
|
||||
still be issued in the current cycle. The default is
|
||||
:samp:`{more} - 1` for insns other than ``CLOBBER`` and
|
||||
``USE``, which normally are not counted against the issue rate.
|
||||
You should define this hook if some insns take more machine resources
|
||||
than others, so that fewer insns can follow them in the same cycle.
|
||||
:samp:`{file}` is either a null pointer, or a stdio stream to write any
|
||||
debug output to. :samp:`{verbose}` is the verbose level provided by
|
||||
:option:`-fsched-verbose-n`. :samp:`{insn}` is the instruction that
|
||||
was scheduled.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_ADJUST_COST]
|
||||
:end-before: [TARGET_SCHED_ADJUST_COST]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_ADJUST_COST (rtx_insn *insn, int dep_type1, rtx_insn *dep_insn, int cost, unsigned int dw)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_ADJUST_PRIORITY]
|
||||
:end-before: [TARGET_SCHED_ADJUST_PRIORITY]
|
||||
|
||||
.. hook-start:TARGET_SCHED_ADJUST_COST
|
||||
|
||||
This function corrects the value of :samp:`{cost}` based on the
|
||||
relationship between :samp:`{insn}` and :samp:`{dep_insn}` through a
|
||||
dependence of type dep_type, and strength :samp:`{dw}`. It should return the new
|
||||
value. The default is to make no adjustment to :samp:`{cost}`. This can be
|
||||
used for example to specify to the scheduler using the traditional pipeline
|
||||
description that an output- or anti-dependence does not incur the same cost
|
||||
as a data-dependence. If the scheduler using the automaton based pipeline
|
||||
description, the cost of anti-dependence is zero and the cost of
|
||||
output-dependence is maximum of one and the difference of latency
|
||||
times of the first and the second insns. If these values are not
|
||||
acceptable, you could use the hook to modify them too. See also
|
||||
see :ref:`processor-pipeline-description`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_REORDER]
|
||||
:end-before: [TARGET_SCHED_REORDER]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_ADJUST_PRIORITY (rtx_insn *insn, int priority)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_REORDER2]
|
||||
:end-before: [TARGET_SCHED_REORDER2]
|
||||
|
||||
.. hook-start:TARGET_SCHED_ADJUST_PRIORITY
|
||||
|
||||
This hook adjusts the integer scheduling priority :samp:`{priority}` of
|
||||
:samp:`{insn}`. It should return the new priority. Increase the priority to
|
||||
execute :samp:`{insn}` earlier, reduce the priority to execute :samp:`{insn}`
|
||||
later. Do not define this hook if you do not need to adjust the
|
||||
scheduling priorities of insns.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_MACRO_FUSION_P]
|
||||
:end-before: [TARGET_SCHED_MACRO_FUSION_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_REORDER (FILE *file, int verbose, rtx_insn **ready, int *n_readyp, int clock)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_MACRO_FUSION_PAIR_P]
|
||||
:end-before: [TARGET_SCHED_MACRO_FUSION_PAIR_P]
|
||||
|
||||
.. hook-start:TARGET_SCHED_REORDER
|
||||
|
||||
This hook is executed by the scheduler after it has scheduled the ready
|
||||
list, to allow the machine description to reorder it (for example to
|
||||
combine two small instructions together on :samp:`VLIW` machines).
|
||||
:samp:`{file}` is either a null pointer, or a stdio stream to write any
|
||||
debug output to. :samp:`{verbose}` is the verbose level provided by
|
||||
:option:`-fsched-verbose-n`. :samp:`{ready}` is a pointer to the ready
|
||||
list of instructions that are ready to be scheduled. :samp:`{n_readyp}` is
|
||||
a pointer to the number of elements in the ready list. The scheduler
|
||||
reads the ready list in reverse order, starting with
|
||||
:samp:`{ready}` [ :samp:`{*n_readyp}` - 1] and going to :samp:`{ready}` [0]. :samp:`{clock}`
|
||||
is the timer tick of the scheduler. You may modify the ready list and
|
||||
the number of ready insns. The return value is the number of insns that
|
||||
can issue this cycle; normally this is just ``issue_rate``. See also
|
||||
:samp:`TARGET_SCHED_REORDER2`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK]
|
||||
:end-before: [TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_REORDER2 (FILE *file, int verbose, rtx_insn **ready, int *n_readyp, int clock)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_INIT]
|
||||
:end-before: [TARGET_SCHED_INIT]
|
||||
|
||||
.. hook-start:TARGET_SCHED_REORDER2
|
||||
|
||||
Like :samp:`TARGET_SCHED_REORDER`, but called at a different time. That
|
||||
function is called whenever the scheduler starts a new cycle. This one
|
||||
is called once per iteration over a cycle, immediately after
|
||||
:samp:`TARGET_SCHED_VARIABLE_ISSUE`; it can reorder the ready list and
|
||||
return the number of insns to be scheduled in the same cycle. Defining
|
||||
this hook can be useful if there are frequent situations where
|
||||
scheduling one insn causes other insns to become ready in the same
|
||||
cycle. These other insns can then be taken into account properly.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FINISH]
|
||||
:end-before: [TARGET_SCHED_FINISH]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SCHED_MACRO_FUSION_P (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_INIT_GLOBAL]
|
||||
:end-before: [TARGET_SCHED_INIT_GLOBAL]
|
||||
|
||||
.. hook-start:TARGET_SCHED_MACRO_FUSION_P
|
||||
|
||||
This hook is used to check whether target platform supports macro fusion.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FINISH_GLOBAL]
|
||||
:end-before: [TARGET_SCHED_FINISH_GLOBAL]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SCHED_MACRO_FUSION_PAIR_P (rtx_insn *prev, rtx_insn *curr)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_DFA_PRE_CYCLE_INSN]
|
||||
:end-before: [TARGET_SCHED_DFA_PRE_CYCLE_INSN]
|
||||
|
||||
.. hook-start:TARGET_SCHED_MACRO_FUSION_PAIR_P
|
||||
|
||||
This hook is used to check whether two insns should be macro fused for
|
||||
a target microarchitecture. If this hook returns true for the given insn pair
|
||||
(:samp:`{prev}` and :samp:`{curr}`), the scheduler will put them into a sched
|
||||
group, and they will not be scheduled apart. The two insns will be either
|
||||
two SET insns or a compare and a conditional jump and this hook should
|
||||
validate any dependencies needed to fuse the two insns together.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN]
|
||||
:end-before: [TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK (rtx_insn *head, rtx_insn *tail)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_DFA_POST_CYCLE_INSN]
|
||||
:end-before: [TARGET_SCHED_DFA_POST_CYCLE_INSN]
|
||||
|
||||
.. hook-start:TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
|
||||
|
||||
This hook is called after evaluation forward dependencies of insns in
|
||||
chain given by two parameter values (:samp:`{head}` and :samp:`{tail}`
|
||||
correspondingly) but before insns scheduling of the insn chain. For
|
||||
example, it can be used for better insn classification if it requires
|
||||
analysis of dependencies. This hook can use backward and forward
|
||||
dependencies of the insn scheduler because they are already
|
||||
calculated.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN]
|
||||
:end-before: [TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_INIT (FILE *file, int verbose, int max_ready)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE]
|
||||
:end-before: [TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE]
|
||||
|
||||
.. hook-start:TARGET_SCHED_INIT
|
||||
|
||||
This hook is executed by the scheduler at the beginning of each block of
|
||||
instructions that are to be scheduled. :samp:`{file}` is either a null
|
||||
pointer, or a stdio stream to write any debug output to. :samp:`{verbose}`
|
||||
is the verbose level provided by :option:`-fsched-verbose-n`.
|
||||
:samp:`{max_ready}` is the maximum number of insns in the current scheduling
|
||||
region that can be live at the same time. This can be used to allocate
|
||||
scratch space if it is needed, e.g. by :samp:`TARGET_SCHED_REORDER`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_DFA_POST_ADVANCE_CYCLE]
|
||||
:end-before: [TARGET_SCHED_DFA_POST_ADVANCE_CYCLE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FINISH (FILE *file, int verbose)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD]
|
||||
:end-before: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD]
|
||||
|
||||
.. hook-start:TARGET_SCHED_FINISH
|
||||
|
||||
This hook is executed by the scheduler at the end of each block of
|
||||
instructions that are to be scheduled. It can be used to perform
|
||||
cleanup of any actions done by the other scheduling hooks. :samp:`{file}`
|
||||
is either a null pointer, or a stdio stream to write any debug output
|
||||
to. :samp:`{verbose}` is the verbose level provided by
|
||||
:option:`-fsched-verbose-n`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD]
|
||||
:end-before: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_INIT_GLOBAL (FILE *file, int verbose, int old_max_uid)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BEGIN]
|
||||
:end-before: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BEGIN]
|
||||
|
||||
.. hook-start:TARGET_SCHED_INIT_GLOBAL
|
||||
|
||||
This hook is executed by the scheduler after function level initializations.
|
||||
:samp:`{file}` is either a null pointer, or a stdio stream to write any debug output to.
|
||||
:samp:`{verbose}` is the verbose level provided by :option:`-fsched-verbose-n`.
|
||||
:samp:`{old_max_uid}` is the maximum insn uid when scheduling begins.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_ISSUE]
|
||||
:end-before: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_ISSUE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FINISH_GLOBAL (FILE *file, int verbose)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BACKTRACK]
|
||||
:end-before: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BACKTRACK]
|
||||
|
||||
.. hook-start:TARGET_SCHED_FINISH_GLOBAL
|
||||
|
||||
This is the cleanup hook corresponding to ``TARGET_SCHED_INIT_GLOBAL``.
|
||||
:samp:`{file}` is either a null pointer, or a stdio stream to write any debug output to.
|
||||
:samp:`{verbose}` is the verbose level provided by :option:`-fsched-verbose-n`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_END]
|
||||
:end-before: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_END]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx TARGET_SCHED_DFA_PRE_CYCLE_INSN (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_INIT]
|
||||
:end-before: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_INIT]
|
||||
|
||||
.. hook-start:TARGET_SCHED_DFA_PRE_CYCLE_INSN
|
||||
|
||||
The hook returns an RTL insn. The automaton state used in the
|
||||
pipeline hazard recognizer is changed as if the insn were scheduled
|
||||
when the new simulated processor cycle starts. Usage of the hook may
|
||||
simplify the automaton pipeline description for some VLIW
|
||||
processors. If the hook is defined, it is used only for the automaton
|
||||
based pipeline description. The default is not to change the state
|
||||
when the new simulated processor cycle starts.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_FINI]
|
||||
:end-before: [TARGET_SCHED_FIRST_CYCLE_MULTIPASS_FINI]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_DFA_NEW_CYCLE]
|
||||
:end-before: [TARGET_SCHED_DFA_NEW_CYCLE]
|
||||
|
||||
.. hook-start:TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN
|
||||
|
||||
The hook can be used to initialize data used by the previous hook.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_IS_COSTLY_DEPENDENCE]
|
||||
:end-before: [TARGET_SCHED_IS_COSTLY_DEPENDENCE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx_insn * TARGET_SCHED_DFA_POST_CYCLE_INSN (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_H_I_D_EXTENDED]
|
||||
:end-before: [TARGET_SCHED_H_I_D_EXTENDED]
|
||||
|
||||
.. hook-start:TARGET_SCHED_DFA_POST_CYCLE_INSN
|
||||
|
||||
The hook is analogous to :samp:`TARGET_SCHED_DFA_PRE_CYCLE_INSN` but used
|
||||
to changed the state as if the insn were scheduled when the new
|
||||
simulated processor cycle finishes.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_ALLOC_SCHED_CONTEXT]
|
||||
:end-before: [TARGET_SCHED_ALLOC_SCHED_CONTEXT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_INIT_SCHED_CONTEXT]
|
||||
:end-before: [TARGET_SCHED_INIT_SCHED_CONTEXT]
|
||||
|
||||
.. hook-start:TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN
|
||||
|
||||
The hook is analogous to :samp:`TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN` but
|
||||
used to initialize data used by the previous hook.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_SET_SCHED_CONTEXT]
|
||||
:end-before: [TARGET_SCHED_SET_SCHED_CONTEXT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_CLEAR_SCHED_CONTEXT]
|
||||
:end-before: [TARGET_SCHED_CLEAR_SCHED_CONTEXT]
|
||||
|
||||
.. hook-start:TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE
|
||||
|
||||
The hook to notify target that the current simulated cycle is about to finish.
|
||||
The hook is analogous to :samp:`TARGET_SCHED_DFA_PRE_CYCLE_INSN` but used
|
||||
to change the state in more complicated situations - e.g., when advancing
|
||||
state on a single insn is not enough.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FREE_SCHED_CONTEXT]
|
||||
:end-before: [TARGET_SCHED_FREE_SCHED_CONTEXT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_DFA_POST_ADVANCE_CYCLE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_SPECULATE_INSN]
|
||||
:end-before: [TARGET_SCHED_SPECULATE_INSN]
|
||||
|
||||
.. hook-start:TARGET_SCHED_DFA_POST_ADVANCE_CYCLE
|
||||
|
||||
The hook to notify target that new simulated cycle has just started.
|
||||
The hook is analogous to :samp:`TARGET_SCHED_DFA_POST_CYCLE_INSN` but used
|
||||
to change the state in more complicated situations - e.g., when advancing
|
||||
state on a single insn is not enough.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_NEEDS_BLOCK_P]
|
||||
:end-before: [TARGET_SCHED_NEEDS_BLOCK_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_GEN_SPEC_CHECK]
|
||||
:end-before: [TARGET_SCHED_GEN_SPEC_CHECK]
|
||||
|
||||
.. hook-start:TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
|
||||
|
||||
This hook controls better choosing an insn from the ready insn queue
|
||||
for the DFA-based insn scheduler. Usually the scheduler
|
||||
chooses the first insn from the queue. If the hook returns a positive
|
||||
value, an additional scheduler code tries all permutations of
|
||||
:samp:`TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD ()`
|
||||
subsequent ready insns to choose an insn whose issue will result in
|
||||
maximal number of issued insns on the same cycle. For the
|
||||
VLIW processor, the code could actually solve the problem of
|
||||
packing simple insns into the VLIW insn. Of course, if the
|
||||
rules of VLIW packing are described in the automaton.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_SET_SCHED_FLAGS]
|
||||
:end-before: [TARGET_SCHED_SET_SCHED_FLAGS]
|
||||
|
||||
This code also could be used for superscalar RISC
|
||||
processors. Let us consider a superscalar RISC processor
|
||||
with 3 pipelines. Some insns can be executed in pipelines :samp:`{A}` or
|
||||
:samp:`{B}`, some insns can be executed only in pipelines :samp:`{B}` or
|
||||
:samp:`{C}`, and one insn can be executed in pipeline :samp:`{B}`. The
|
||||
processor may issue the 1st insn into :samp:`{A}` and the 2nd one into
|
||||
:samp:`{B}`. In this case, the 3rd insn will wait for freeing :samp:`{B}`
|
||||
until the next cycle. If the scheduler issues the 3rd insn the first,
|
||||
the processor could issue all 3 insns per cycle.
|
||||
|
||||
Actually this code demonstrates advantages of the automaton based
|
||||
pipeline hazard recognizer. We try quickly and easy many insn
|
||||
schedules to choose the best one.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_CAN_SPECULATE_INSN]
|
||||
:end-before: [TARGET_SCHED_CAN_SPECULATE_INSN]
|
||||
|
||||
The default is no multipass scheduling.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_SMS_RES_MII]
|
||||
:end-before: [TARGET_SCHED_SMS_RES_MII]
|
||||
|
||||
.. function:: int TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD (rtx_insn *insn, int ready_index)
|
||||
|
||||
.. hook-start:TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_DISPATCH]
|
||||
:end-before: [TARGET_SCHED_DISPATCH]
|
||||
|
||||
This hook controls what insns from the ready insn queue will be
|
||||
considered for the multipass insn scheduling. If the hook returns
|
||||
zero for :samp:`{insn}`, the insn will be considered in multipass scheduling.
|
||||
Positive return values will remove :samp:`{insn}` from consideration on
|
||||
the current round of multipass scheduling.
|
||||
Negative return values will remove :samp:`{insn}` from consideration for given
|
||||
number of cycles.
|
||||
Backends should be careful about returning non-zero for highest priority
|
||||
instruction at position 0 in the ready list. :samp:`{ready_index}` is passed
|
||||
to allow backends make correct judgements.
|
||||
|
||||
The default is that any ready insns can be chosen to be issued.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_DISPATCH_DO]
|
||||
:end-before: [TARGET_SCHED_DISPATCH_DO]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BEGIN (void *data, signed char *ready_try, int n_ready, bool first_cycle_insn_p)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_EXPOSED_PIPELINE]
|
||||
:end-before: [TARGET_SCHED_EXPOSED_PIPELINE]
|
||||
|
||||
.. hook-start:TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BEGIN
|
||||
|
||||
This hook prepares the target backend for a new round of multipass
|
||||
scheduling.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_REASSOCIATION_WIDTH]
|
||||
:end-before: [TARGET_SCHED_REASSOCIATION_WIDTH]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_ISSUE (void *data, signed char *ready_try, int n_ready, rtx_insn *insn, const void *prev_data)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SCHED_FUSION_PRIORITY]
|
||||
:end-before: [TARGET_SCHED_FUSION_PRIORITY]
|
||||
|
||||
.. hook-start:TARGET_SCHED_FIRST_CYCLE_MULTIPASS_ISSUE
|
||||
|
||||
This hook is called when multipass scheduling evaluates instruction INSN.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BACKTRACK (const void *data, signed char *ready_try, int n_ready)
|
||||
|
||||
.. hook-start:TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BACKTRACK
|
||||
|
||||
This is called when multipass scheduling backtracks from evaluation of
|
||||
an instruction.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_END (const void *data)
|
||||
|
||||
.. hook-start:TARGET_SCHED_FIRST_CYCLE_MULTIPASS_END
|
||||
|
||||
This hook notifies the target about the result of the concluded current
|
||||
round of multipass scheduling.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_INIT (void *data)
|
||||
|
||||
.. hook-start:TARGET_SCHED_FIRST_CYCLE_MULTIPASS_INIT
|
||||
|
||||
This hook initializes target-specific data used in multipass scheduling.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_FINI (void *data)
|
||||
|
||||
.. hook-start:TARGET_SCHED_FIRST_CYCLE_MULTIPASS_FINI
|
||||
|
||||
This hook finalizes target-specific data used in multipass scheduling.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_DFA_NEW_CYCLE (FILE *dump, int verbose, rtx_insn *insn, int last_clock, int clock, int *sort_p)
|
||||
|
||||
.. hook-start:TARGET_SCHED_DFA_NEW_CYCLE
|
||||
|
||||
This hook is called by the insn scheduler before issuing :samp:`{insn}`
|
||||
on cycle :samp:`{clock}`. If the hook returns nonzero,
|
||||
:samp:`{insn}` is not issued on this processor cycle. Instead,
|
||||
the processor cycle is advanced. If \* :samp:`{sort_p}`
|
||||
is zero, the insn ready queue is not sorted on the new cycle
|
||||
start as usually. :samp:`{dump}` and :samp:`{verbose}` specify the file and
|
||||
verbosity level to use for debugging output.
|
||||
:samp:`{last_clock}` and :samp:`{clock}` are, respectively, the
|
||||
processor cycle on which the previous insn has been issued,
|
||||
and the current processor cycle.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SCHED_IS_COSTLY_DEPENDENCE (struct _dep *_dep, int cost, int distance)
|
||||
|
||||
.. hook-start:TARGET_SCHED_IS_COSTLY_DEPENDENCE
|
||||
|
||||
This hook is used to define which dependences are considered costly by
|
||||
the target, so costly that it is not advisable to schedule the insns that
|
||||
are involved in the dependence too close to one another. The parameters
|
||||
to this hook are as follows: The first parameter :samp:`{_dep}` is the dependence
|
||||
being evaluated. The second parameter :samp:`{cost}` is the cost of the
|
||||
dependence as estimated by the scheduler, and the third
|
||||
parameter :samp:`{distance}` is the distance in cycles between the two insns.
|
||||
The hook returns ``true`` if considering the distance between the two
|
||||
insns the dependence between them is considered costly by the target,
|
||||
and ``false`` otherwise.
|
||||
|
||||
Defining this hook can be useful in multiple-issue out-of-order machines,
|
||||
where (a) it's practically hopeless to predict the actual data/resource
|
||||
delays, however: (b) there's a better chance to predict the actual grouping
|
||||
that will be formed, and (c) correctly emulating the grouping can be very
|
||||
important. In such targets one may want to allow issuing dependent insns
|
||||
closer to one another---i.e., closer than the dependence distance; however,
|
||||
not in cases of 'costly dependences', which this hooks allows to define.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_H_I_D_EXTENDED (void)
|
||||
|
||||
.. hook-start:TARGET_SCHED_H_I_D_EXTENDED
|
||||
|
||||
This hook is called by the insn scheduler after emitting a new instruction to
|
||||
the instruction stream. The hook notifies a target backend to extend its
|
||||
per instruction data structures.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void * TARGET_SCHED_ALLOC_SCHED_CONTEXT (void)
|
||||
|
||||
.. hook-start:TARGET_SCHED_ALLOC_SCHED_CONTEXT
|
||||
|
||||
Return a pointer to a store large enough to hold target scheduling context.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_INIT_SCHED_CONTEXT (void *tc, bool clean_p)
|
||||
|
||||
.. hook-start:TARGET_SCHED_INIT_SCHED_CONTEXT
|
||||
|
||||
Initialize store pointed to by :samp:`{tc}` to hold target scheduling context.
|
||||
It :samp:`{clean_p}` is true then initialize :samp:`{tc}` as if scheduler is at the
|
||||
beginning of the block. Otherwise, copy the current context into :samp:`{tc}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_SET_SCHED_CONTEXT (void *tc)
|
||||
|
||||
.. hook-start:TARGET_SCHED_SET_SCHED_CONTEXT
|
||||
|
||||
Copy target scheduling context pointed to by :samp:`{tc}` to the current context.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_CLEAR_SCHED_CONTEXT (void *tc)
|
||||
|
||||
.. hook-start:TARGET_SCHED_CLEAR_SCHED_CONTEXT
|
||||
|
||||
Deallocate internal data in target scheduling context pointed to by :samp:`{tc}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FREE_SCHED_CONTEXT (void *tc)
|
||||
|
||||
.. hook-start:TARGET_SCHED_FREE_SCHED_CONTEXT
|
||||
|
||||
Deallocate a store for target scheduling context pointed to by :samp:`{tc}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_SPECULATE_INSN (rtx_insn *insn, unsigned int dep_status, rtx *new_pat)
|
||||
|
||||
.. hook-start:TARGET_SCHED_SPECULATE_INSN
|
||||
|
||||
This hook is called by the insn scheduler when :samp:`{insn}` has only
|
||||
speculative dependencies and therefore can be scheduled speculatively.
|
||||
The hook is used to check if the pattern of :samp:`{insn}` has a speculative
|
||||
version and, in case of successful check, to generate that speculative
|
||||
pattern. The hook should return 1, if the instruction has a speculative form,
|
||||
or -1, if it doesn't. :samp:`{request}` describes the type of requested
|
||||
speculation. If the return value equals 1 then :samp:`{new_pat}` is assigned
|
||||
the generated speculative pattern.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SCHED_NEEDS_BLOCK_P (unsigned int dep_status)
|
||||
|
||||
.. hook-start:TARGET_SCHED_NEEDS_BLOCK_P
|
||||
|
||||
This hook is called by the insn scheduler during generation of recovery code
|
||||
for :samp:`{insn}`. It should return ``true``, if the corresponding check
|
||||
instruction should branch to recovery code, or ``false`` otherwise.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx TARGET_SCHED_GEN_SPEC_CHECK (rtx_insn *insn, rtx_insn *label, unsigned int ds)
|
||||
|
||||
.. hook-start:TARGET_SCHED_GEN_SPEC_CHECK
|
||||
|
||||
This hook is called by the insn scheduler to generate a pattern for recovery
|
||||
check instruction. If :samp:`{mutate_p}` is zero, then :samp:`{insn}` is a
|
||||
speculative instruction for which the check should be generated.
|
||||
:samp:`{label}` is either a label of a basic block, where recovery code should
|
||||
be emitted, or a null pointer, when requested check doesn't branch to
|
||||
recovery code (a simple check). If :samp:`{mutate_p}` is nonzero, then
|
||||
a pattern for a branchy check corresponding to a simple check denoted by
|
||||
:samp:`{insn}` should be generated. In this case :samp:`{label}` can't be null.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_SET_SCHED_FLAGS (struct spec_info_def *spec_info)
|
||||
|
||||
.. hook-start:TARGET_SCHED_SET_SCHED_FLAGS
|
||||
|
||||
This hook is used by the insn scheduler to find out what features should be
|
||||
enabled/used.
|
||||
The structure \* :samp:`{spec_info}` should be filled in by the target.
|
||||
The structure describes speculation types that can be used in the scheduler.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SCHED_CAN_SPECULATE_INSN (rtx_insn *insn)
|
||||
|
||||
.. hook-start:TARGET_SCHED_CAN_SPECULATE_INSN
|
||||
|
||||
Some instructions should never be speculated by the schedulers, usually
|
||||
because the instruction is too expensive to get this wrong. Often such
|
||||
instructions have long latency, and often they are not fully modeled in the
|
||||
pipeline descriptions. This hook should return ``false`` if :samp:`{insn}`
|
||||
should not be speculated.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_SMS_RES_MII (struct ddg *g)
|
||||
|
||||
.. hook-start:TARGET_SCHED_SMS_RES_MII
|
||||
|
||||
This hook is called by the swing modulo scheduler to calculate a
|
||||
resource-based lower bound which is based on the resources available in
|
||||
the machine and the resources required by each instruction. The target
|
||||
backend can use :samp:`{g}` to calculate such bound. A very simple lower
|
||||
bound will be used in case this hook is not implemented: the total number
|
||||
of instructions divided by the issue rate.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SCHED_DISPATCH (rtx_insn *insn, int x)
|
||||
|
||||
.. hook-start:TARGET_SCHED_DISPATCH
|
||||
|
||||
This hook is called by Haifa Scheduler. It returns true if dispatch scheduling
|
||||
is supported in hardware and the condition specified in the parameter is true.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_DISPATCH_DO (rtx_insn *insn, int x)
|
||||
|
||||
.. hook-start:TARGET_SCHED_DISPATCH_DO
|
||||
|
||||
This hook is called by Haifa Scheduler. It performs the operation specified
|
||||
in its second parameter.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_SCHED_EXPOSED_PIPELINE
|
||||
|
||||
.. hook-start:TARGET_SCHED_EXPOSED_PIPELINE
|
||||
|
||||
True if the processor has an exposed pipeline, which means that not just
|
||||
the order of instructions is important for correctness when scheduling, but
|
||||
also the latencies of operations.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_SCHED_REASSOCIATION_WIDTH (unsigned int opc, machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_SCHED_REASSOCIATION_WIDTH
|
||||
|
||||
This hook is called by tree reassociator to determine a level of
|
||||
parallelism required in output calculations chain.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SCHED_FUSION_PRIORITY (rtx_insn *insn, int max_pri, int *fusion_pri, int *pri)
|
||||
|
||||
.. hook-start:TARGET_SCHED_FUSION_PRIORITY
|
||||
|
||||
This hook is called by scheduling fusion pass. It calculates fusion
|
||||
priorities for each instruction passed in by parameter. The priorities
|
||||
are returned via pointer parameters.
|
||||
|
||||
:samp:`{insn}` is the instruction whose priorities need to be calculated.
|
||||
:samp:`{max_pri}` is the maximum priority can be returned in any cases.
|
||||
:samp:`{fusion_pri}` is the pointer parameter through which :samp:`{insn}` 's
|
||||
fusion priority should be calculated and returned.
|
||||
:samp:`{pri}` is the pointer parameter through which :samp:`{insn}` 's priority
|
||||
should be calculated and returned.
|
||||
|
||||
Same :samp:`{fusion_pri}` should be returned for instructions which should
|
||||
be scheduled together. Different :samp:`{pri}` should be returned for
|
||||
instructions with same :samp:`{fusion_pri}`. :samp:`{fusion_pri}` is the major
|
||||
sort key, :samp:`{pri}` is the minor sort key. All instructions will be
|
||||
scheduled according to the two priorities. All priorities calculated
|
||||
should be between 0 (exclusive) and :samp:`{max_pri}` (inclusive). To avoid
|
||||
false dependencies, :samp:`{fusion_pri}` of instructions which need to be
|
||||
scheduled together should be smaller than :samp:`{fusion_pri}` of irrelevant
|
||||
instructions.
|
||||
|
||||
Given below example:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
ldr r10, [r1, 4]
|
||||
add r4, r4, r10
|
||||
ldr r15, [r2, 8]
|
||||
sub r5, r5, r15
|
||||
ldr r11, [r1, 0]
|
||||
add r4, r4, r11
|
||||
ldr r16, [r2, 12]
|
||||
sub r5, r5, r16
|
||||
|
||||
On targets like ARM/AArch64, the two pairs of consecutive loads should be
|
||||
merged. Since peephole2 pass can't help in this case unless consecutive
|
||||
loads are actually next to each other in instruction flow. That's where
|
||||
this scheduling fusion pass works. This hook calculates priority for each
|
||||
instruction based on its fustion type, like:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
ldr r10, [r1, 4] ; fusion_pri=99, pri=96
|
||||
add r4, r4, r10 ; fusion_pri=100, pri=100
|
||||
ldr r15, [r2, 8] ; fusion_pri=98, pri=92
|
||||
sub r5, r5, r15 ; fusion_pri=100, pri=100
|
||||
ldr r11, [r1, 0] ; fusion_pri=99, pri=100
|
||||
add r4, r4, r11 ; fusion_pri=100, pri=100
|
||||
ldr r16, [r2, 12] ; fusion_pri=98, pri=88
|
||||
sub r5, r5, r16 ; fusion_pri=100, pri=100
|
||||
|
||||
Scheduling fusion pass then sorts all ready to issue instructions according
|
||||
to the priorities. As a result, instructions of same fusion type will be
|
||||
pushed together in instruction flow, like:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
ldr r11, [r1, 0]
|
||||
ldr r10, [r1, 4]
|
||||
ldr r15, [r2, 8]
|
||||
ldr r16, [r2, 12]
|
||||
add r4, r4, r10
|
||||
sub r5, r5, r15
|
||||
add r4, r4, r11
|
||||
sub r5, r5, r16
|
||||
|
||||
Now peephole2 pass can simply merge the two pairs of loads.
|
||||
|
||||
Since scheduling fusion pass relies on peephole2 to do real fusion
|
||||
work, it is only enabled by default when peephole2 is in effect.
|
||||
|
||||
This is firstly introduced on ARM/AArch64 targets, please refer to
|
||||
the hook implementation for how different fusion types are supported.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_EXPAND_DIVMOD_LIBFUNC (rtx libfunc, machine_mode mode, rtx op0, rtx op1, rtx *quot, rtx *rem)
|
||||
|
||||
.. hook-start:TARGET_EXPAND_DIVMOD_LIBFUNC
|
||||
|
||||
Define this hook for enabling divmod transform if the port does not have
|
||||
hardware divmod insn but defines target-specific divmod libfuncs.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EXPAND_DIVMOD_LIBFUNC]
|
||||
:end-before: [TARGET_EXPAND_DIVMOD_LIBFUNC]
|
||||
|
@ -40,53 +40,21 @@ in order to make effective use of section anchors. It won't use
|
||||
section anchors at all unless either ``TARGET_MIN_ANCHOR_OFFSET``
|
||||
or ``TARGET_MAX_ANCHOR_OFFSET`` is set to a nonzero value.
|
||||
|
||||
.. c:var:: HOST_WIDE_INT TARGET_MIN_ANCHOR_OFFSET
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MIN_ANCHOR_OFFSET]
|
||||
:end-before: [TARGET_MIN_ANCHOR_OFFSET]
|
||||
|
||||
.. hook-start:TARGET_MIN_ANCHOR_OFFSET
|
||||
|
||||
The minimum offset that should be applied to a section anchor.
|
||||
On most targets, it should be the smallest offset that can be
|
||||
applied to a base register while still giving a legitimate address
|
||||
for every mode. The default value is 0.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MAX_ANCHOR_OFFSET]
|
||||
:end-before: [TARGET_MAX_ANCHOR_OFFSET]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: HOST_WIDE_INT TARGET_MAX_ANCHOR_OFFSET
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_OUTPUT_ANCHOR]
|
||||
:end-before: [TARGET_ASM_OUTPUT_ANCHOR]
|
||||
|
||||
.. hook-start:TARGET_MAX_ANCHOR_OFFSET
|
||||
|
||||
Like ``TARGET_MIN_ANCHOR_OFFSET``, but the maximum (inclusive)
|
||||
offset that should be applied to section anchors. The default
|
||||
value is 0.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_OUTPUT_ANCHOR (rtx x)
|
||||
|
||||
.. hook-start:TARGET_ASM_OUTPUT_ANCHOR
|
||||
|
||||
Write the assembly code to define section anchor :samp:`{x}`, which is a
|
||||
``SYMBOL_REF`` for which :samp:`SYMBOL_REF_ANCHOR_P ({x})` is true.
|
||||
The hook is called with the assembly output position set to the beginning
|
||||
of ``SYMBOL_REF_BLOCK (x)``.
|
||||
|
||||
If ``ASM_OUTPUT_DEF`` is available, the hook's default definition uses
|
||||
it to define the symbol as :samp:`. + SYMBOL_REF_BLOCK_OFFSET ({x})`.
|
||||
If ``ASM_OUTPUT_DEF`` is not available, the hook's default definition
|
||||
is ``NULL``, which disables the use of section anchors altogether.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_USE_ANCHORS_FOR_SYMBOL_P (const_rtx x)
|
||||
|
||||
.. hook-start:TARGET_USE_ANCHORS_FOR_SYMBOL_P
|
||||
|
||||
Return true if GCC should attempt to use anchors to access ``SYMBOL_REF``
|
||||
:samp:`{x}`. You can assume :samp:`SYMBOL_REF_HAS_BLOCK_INFO_P ({x})` and
|
||||
:samp:`!SYMBOL_REF_ANCHOR_P ({x})`.
|
||||
|
||||
The default version is correct for most targets, but you might need to
|
||||
intercept this hook to handle things like target-specific attributes
|
||||
or target-specific sections.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_USE_ANCHORS_FOR_SYMBOL_P]
|
||||
:end-before: [TARGET_USE_ANCHORS_FOR_SYMBOL_P]
|
||||
|
@ -10,155 +10,71 @@
|
||||
C++ ABI parameters
|
||||
******************
|
||||
|
||||
.. function:: tree TARGET_CXX_GUARD_TYPE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_GUARD_TYPE]
|
||||
:end-before: [TARGET_CXX_GUARD_TYPE]
|
||||
|
||||
.. hook-start:TARGET_CXX_GUARD_TYPE
|
||||
|
||||
Define this hook to override the integer type used for guard variables.
|
||||
These are used to implement one-time construction of static objects. The
|
||||
default is long_long_integer_type_node.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_GUARD_MASK_BIT]
|
||||
:end-before: [TARGET_CXX_GUARD_MASK_BIT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CXX_GUARD_MASK_BIT (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_GET_COOKIE_SIZE]
|
||||
:end-before: [TARGET_CXX_GET_COOKIE_SIZE]
|
||||
|
||||
.. hook-start:TARGET_CXX_GUARD_MASK_BIT
|
||||
|
||||
This hook determines how guard variables are used. It should return
|
||||
``false`` (the default) if the first byte should be used. A return value of
|
||||
``true`` indicates that only the least significant bit should be used.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_COOKIE_HAS_SIZE]
|
||||
:end-before: [TARGET_CXX_COOKIE_HAS_SIZE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_CXX_GET_COOKIE_SIZE (tree type)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_IMPORT_EXPORT_CLASS]
|
||||
:end-before: [TARGET_CXX_IMPORT_EXPORT_CLASS]
|
||||
|
||||
.. hook-start:TARGET_CXX_GET_COOKIE_SIZE
|
||||
|
||||
This hook returns the size of the cookie to use when allocating an array
|
||||
whose elements have the indicated :samp:`{type}`. Assumes that it is already
|
||||
known that a cookie is needed. The default is
|
||||
``max(sizeof (size_t), alignof(type))``, as defined in section 2.7 of the
|
||||
IA64/Generic C++ ABI.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_CDTOR_RETURNS_THIS]
|
||||
:end-before: [TARGET_CXX_CDTOR_RETURNS_THIS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CXX_COOKIE_HAS_SIZE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_KEY_METHOD_MAY_BE_INLINE]
|
||||
:end-before: [TARGET_CXX_KEY_METHOD_MAY_BE_INLINE]
|
||||
|
||||
.. hook-start:TARGET_CXX_COOKIE_HAS_SIZE
|
||||
|
||||
This hook should return ``true`` if the element size should be stored in
|
||||
array cookies. The default is to return ``false``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY]
|
||||
:end-before: [TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_CXX_IMPORT_EXPORT_CLASS (tree type, int import_export)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT]
|
||||
:end-before: [TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT]
|
||||
|
||||
.. hook-start:TARGET_CXX_IMPORT_EXPORT_CLASS
|
||||
|
||||
If defined by a backend this hook allows the decision made to export
|
||||
class :samp:`{type}` to be overruled. Upon entry :samp:`{import_export}`
|
||||
will contain 1 if the class is going to be exported, -1 if it is going
|
||||
to be imported and 0 otherwise. This function should return the
|
||||
modified value and perform any other actions necessary to support the
|
||||
backend's targeted operating system.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_LIBRARY_RTTI_COMDAT]
|
||||
:end-before: [TARGET_CXX_LIBRARY_RTTI_COMDAT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CXX_CDTOR_RETURNS_THIS (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_USE_AEABI_ATEXIT]
|
||||
:end-before: [TARGET_CXX_USE_AEABI_ATEXIT]
|
||||
|
||||
.. hook-start:TARGET_CXX_CDTOR_RETURNS_THIS
|
||||
|
||||
This hook should return ``true`` if constructors and destructors return
|
||||
the address of the object created/destroyed. The default is to return
|
||||
``false``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT]
|
||||
:end-before: [TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CXX_KEY_METHOD_MAY_BE_INLINE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_ADJUST_CLASS_AT_DEFINITION]
|
||||
:end-before: [TARGET_CXX_ADJUST_CLASS_AT_DEFINITION]
|
||||
|
||||
.. hook-start:TARGET_CXX_KEY_METHOD_MAY_BE_INLINE
|
||||
|
||||
This hook returns true if the key method for a class (i.e., the method
|
||||
which, if defined in the current translation unit, causes the virtual
|
||||
table to be emitted) may be an inline function. Under the standard
|
||||
Itanium C++ ABI the key method may be an inline function so long as
|
||||
the function is not declared inline in the class definition. Under
|
||||
some variants of the ABI, an inline function can never be the key
|
||||
method. The default is to return ``true``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY (tree decl)
|
||||
|
||||
.. hook-start:TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY
|
||||
|
||||
:samp:`{decl}` is a virtual table, virtual table table, typeinfo object,
|
||||
or other similar implicit class data object that will be emitted with
|
||||
external linkage in this translation unit. No ELF visibility has been
|
||||
explicitly specified. If the target needs to specify a visibility
|
||||
other than that of the containing class, use this hook to set
|
||||
``DECL_VISIBILITY`` and ``DECL_VISIBILITY_SPECIFIED``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT (void)
|
||||
|
||||
.. hook-start:TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT
|
||||
|
||||
This hook returns true (the default) if virtual tables and other
|
||||
similar implicit class data objects are always COMDAT if they have
|
||||
external linkage. If this hook returns false, then class data for
|
||||
classes whose virtual table will be emitted in only one translation
|
||||
unit will not be COMDAT.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CXX_LIBRARY_RTTI_COMDAT (void)
|
||||
|
||||
.. hook-start:TARGET_CXX_LIBRARY_RTTI_COMDAT
|
||||
|
||||
This hook returns true (the default) if the RTTI information for
|
||||
the basic types which is defined in the C++ runtime should always
|
||||
be COMDAT, false if it should not be COMDAT.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CXX_USE_AEABI_ATEXIT (void)
|
||||
|
||||
.. hook-start:TARGET_CXX_USE_AEABI_ATEXIT
|
||||
|
||||
This hook returns true if ``__aeabi_atexit`` (as defined by the ARM EABI)
|
||||
should be used to register static destructors when :option:`-fuse-cxa-atexit`
|
||||
is in effect. The default is to return false to use ``__cxa_atexit``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT (void)
|
||||
|
||||
.. hook-start:TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT
|
||||
|
||||
This hook returns true if the target ``atexit`` function can be used
|
||||
in the same manner as ``__cxa_atexit`` to register C++ static
|
||||
destructors. This requires that ``atexit`` -registered functions in
|
||||
shared libraries are run in the correct order when the libraries are
|
||||
unloaded. The default is to return false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_CXX_ADJUST_CLASS_AT_DEFINITION (tree type)
|
||||
|
||||
.. hook-start:TARGET_CXX_ADJUST_CLASS_AT_DEFINITION
|
||||
|
||||
:samp:`{type}` is a C++ class (i.e., RECORD_TYPE or UNION_TYPE) that has just
|
||||
been defined. Use this hook to make adjustments to the class (eg, tweak
|
||||
visibility or perform any other required target modifications).
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_CXX_DECL_MANGLING_CONTEXT (const_tree decl)
|
||||
|
||||
.. hook-start:TARGET_CXX_DECL_MANGLING_CONTEXT
|
||||
|
||||
Return target-specific mangling context of :samp:`{decl}` or ``NULL_TREE``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CXX_DECL_MANGLING_CONTEXT]
|
||||
:end-before: [TARGET_CXX_DECL_MANGLING_CONTEXT]
|
||||
|
@ -104,31 +104,10 @@ Representation of condition codes using registers
|
||||
You should define this macro if and only if you define extra CC modes
|
||||
in :samp:`{machine}-modes.def`.
|
||||
|
||||
.. function:: void TARGET_CANONICALIZE_COMPARISON (int *code, rtx *op0, rtx *op1, bool op0_preserve_value)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CANONICALIZE_COMPARISON]
|
||||
:end-before: [TARGET_CANONICALIZE_COMPARISON]
|
||||
|
||||
.. hook-start:TARGET_CANONICALIZE_COMPARISON
|
||||
|
||||
On some machines not all possible comparisons are defined, but you can
|
||||
convert an invalid comparison into a valid one. For example, the Alpha
|
||||
does not have a ``GT`` comparison, but you can use an ``LT``
|
||||
comparison instead and swap the order of the operands.
|
||||
|
||||
On such machines, implement this hook to do any required conversions.
|
||||
:samp:`{code}` is the initial comparison code and :samp:`{op0}` and :samp:`{op1}`
|
||||
are the left and right operands of the comparison, respectively. If
|
||||
:samp:`{op0_preserve_value}` is ``true`` the implementation is not
|
||||
allowed to change the value of :samp:`{op0}` since the value might be used
|
||||
in RTXs which aren't comparisons. E.g. the implementation is not
|
||||
allowed to swap operands in that case.
|
||||
|
||||
GCC will not assume that the comparison resulting from this macro is
|
||||
valid but will see if the resulting insn matches a pattern in the
|
||||
:samp:`md` file.
|
||||
|
||||
You need not to implement this hook if it would never change the
|
||||
comparison code or operands.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: REVERSIBLE_CC_MODE (mode)
|
||||
|
||||
@ -163,48 +142,16 @@ Representation of condition codes using registers
|
||||
((MODE) != CCFPmode ? reverse_condition (CODE) \
|
||||
: reverse_condition_maybe_unordered (CODE))
|
||||
|
||||
.. function:: bool TARGET_FIXED_CONDITION_CODE_REGS (unsigned int *p1, unsigned int *p2)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_FIXED_CONDITION_CODE_REGS]
|
||||
:end-before: [TARGET_FIXED_CONDITION_CODE_REGS]
|
||||
|
||||
.. hook-start:TARGET_FIXED_CONDITION_CODE_REGS
|
||||
|
||||
On targets which use a hard
|
||||
register rather than a pseudo-register to hold condition codes, the
|
||||
regular CSE passes are often not able to identify cases in which the
|
||||
hard register is set to a common value. Use this hook to enable a
|
||||
small pass which optimizes such cases. This hook should return true
|
||||
to enable this pass, and it should set the integers to which its
|
||||
arguments point to the hard register numbers used for condition codes.
|
||||
When there is only one such register, as is true on most systems, the
|
||||
integer pointed to by :samp:`{p2}` should be set to
|
||||
``INVALID_REGNUM``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CC_MODES_COMPATIBLE]
|
||||
:end-before: [TARGET_CC_MODES_COMPATIBLE]
|
||||
|
||||
The default version of this hook returns false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: machine_mode TARGET_CC_MODES_COMPATIBLE (machine_mode m1, machine_mode m2)
|
||||
|
||||
.. hook-start:TARGET_CC_MODES_COMPATIBLE
|
||||
|
||||
On targets which use multiple condition code modes in class
|
||||
``MODE_CC``, it is sometimes the case that a comparison can be
|
||||
validly done in more than one mode. On such a system, define this
|
||||
target hook to take two mode arguments and to return a mode in which
|
||||
both comparisons may be validly done. If there is no such mode,
|
||||
return ``VOIDmode``.
|
||||
|
||||
The default version of this hook checks whether the modes are the
|
||||
same. If they are, it returns that mode. If they are different, it
|
||||
returns ``VOIDmode``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: unsigned int TARGET_FLAGS_REGNUM
|
||||
|
||||
.. hook-start:TARGET_FLAGS_REGNUM
|
||||
|
||||
If the target has a dedicated flags register, and it needs to use the
|
||||
post-reload comparison elimination pass, or the delay slot filler pass,
|
||||
then this value should be set appropriately.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_FLAGS_REGNUM]
|
||||
:end-before: [TARGET_FLAGS_REGNUM]
|
||||
|
@ -103,15 +103,10 @@ Here are macros for DWARF output.
|
||||
prologue, or call ``dwarf2out_def_cfa`` and ``dwarf2out_reg_save``
|
||||
as appropriate from ``TARGET_ASM_FUNCTION_PROLOGUE`` if you don't.
|
||||
|
||||
.. function:: int TARGET_DWARF_CALLING_CONVENTION (const_tree function)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DWARF_CALLING_CONVENTION]
|
||||
:end-before: [TARGET_DWARF_CALLING_CONVENTION]
|
||||
|
||||
.. hook-start:TARGET_DWARF_CALLING_CONVENTION
|
||||
|
||||
Define this to enable the dwarf attribute ``DW_AT_calling_convention`` to
|
||||
be emitted for each function. Instead of an integer return the enum
|
||||
value for the ``DW_CC_`` tag.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_DWARF_CALLING_CONVENTION (const_tree function)
|
||||
|
||||
@ -127,22 +122,10 @@ Here are macros for DWARF output.
|
||||
exceptions are enabled, GCC will output this information not matter
|
||||
how you define ``DWARF2_FRAME_INFO``.
|
||||
|
||||
.. function:: enum unwind_info_type TARGET_DEBUG_UNWIND_INFO (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DEBUG_UNWIND_INFO]
|
||||
:end-before: [TARGET_DEBUG_UNWIND_INFO]
|
||||
|
||||
.. hook-start:TARGET_DEBUG_UNWIND_INFO
|
||||
|
||||
This hook defines the mechanism that will be used for describing frame
|
||||
unwind information to the debugger. Normally the hook will return
|
||||
``UI_DWARF2`` if DWARF 2 debug information is enabled, and
|
||||
return ``UI_NONE`` otherwise.
|
||||
|
||||
A target may return ``UI_DWARF2`` even when DWARF 2 debug information
|
||||
is disabled in order to always output DWARF 2 frame information.
|
||||
|
||||
A target may return ``UI_TARGET`` if it has ABI specified unwind tables.
|
||||
This will suppress generation of the normal debug frame unwind information.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: DWARF2_ASM_LINE_DEBUG_INFO
|
||||
|
||||
@ -157,63 +140,30 @@ Here are macros for DWARF output.
|
||||
user enables location views, the compiler may have to fallback to
|
||||
internal line number tables.
|
||||
|
||||
.. function:: int TARGET_RESET_LOCATION_VIEW (rtx_insn *)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_RESET_LOCATION_VIEW]
|
||||
:end-before: [TARGET_RESET_LOCATION_VIEW]
|
||||
|
||||
.. hook-start:TARGET_RESET_LOCATION_VIEW
|
||||
|
||||
This hook, if defined, enables -ginternal-reset-location-views, and
|
||||
uses its result to override cases in which the estimated min insn
|
||||
length might be nonzero even when a PC advance (i.e., a view reset)
|
||||
cannot be taken for granted.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_WANT_DEBUG_PUB_SECTIONS]
|
||||
:end-before: [TARGET_WANT_DEBUG_PUB_SECTIONS]
|
||||
|
||||
If the hook is defined, it must return a positive value to indicate
|
||||
the insn definitely advances the PC, and so the view number can be
|
||||
safely assumed to be reset; a negative value to mean the insn
|
||||
definitely does not advance the PC, and os the view number must not
|
||||
be reset; or zero to decide based on the estimated insn length.
|
||||
|
||||
If insn length is to be regarded as reliable, set the hook to
|
||||
``hook_int_rtx_insn_0``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DELAY_SCHED2]
|
||||
:end-before: [TARGET_DELAY_SCHED2]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_WANT_DEBUG_PUB_SECTIONS
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DELAY_VARTRACK]
|
||||
:end-before: [TARGET_DELAY_VARTRACK]
|
||||
|
||||
.. hook-start:TARGET_WANT_DEBUG_PUB_SECTIONS
|
||||
|
||||
True if the ``.debug_pubtypes`` and ``.debug_pubnames`` sections
|
||||
should be emitted. These sections are not used on most platforms, and
|
||||
in particular GDB does not use them.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_NO_REGISTER_ALLOCATION]
|
||||
:end-before: [TARGET_NO_REGISTER_ALLOCATION]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_DELAY_SCHED2
|
||||
|
||||
.. hook-start:TARGET_DELAY_SCHED2
|
||||
|
||||
True if sched2 is not to be run at its normal place.
|
||||
This usually means it will be run as part of machine-specific reorg.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_DELAY_VARTRACK
|
||||
|
||||
.. hook-start:TARGET_DELAY_VARTRACK
|
||||
|
||||
True if vartrack is not to be run at its normal place.
|
||||
This usually means it will be run as part of machine-specific reorg.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_NO_REGISTER_ALLOCATION
|
||||
|
||||
.. hook-start:TARGET_NO_REGISTER_ALLOCATION
|
||||
|
||||
True if register allocation and the passes
|
||||
following it should not be run. Usually true only for virtual assembler
|
||||
targets.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ASM_OUTPUT_DWARF_DELTA (stream, size, label1, label2)
|
||||
|
||||
@ -250,14 +200,10 @@ Here are macros for DWARF output.
|
||||
is used on some systems to avoid garbage collecting a DWARF table which
|
||||
is referenced by a function.
|
||||
|
||||
.. function:: void TARGET_ASM_OUTPUT_DWARF_DTPREL (FILE *file, int size, rtx x)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_OUTPUT_DWARF_DTPREL]
|
||||
:end-before: [TARGET_ASM_OUTPUT_DWARF_DTPREL]
|
||||
|
||||
.. hook-start:TARGET_ASM_OUTPUT_DWARF_DTPREL
|
||||
|
||||
If defined, this target hook is a function which outputs a DTP-relative
|
||||
reference to the given TLS symbol of the specified size.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. _vms-debug:
|
||||
|
||||
|
@ -291,16 +291,10 @@ You can control the compilation driver.
|
||||
the effect you need. Overriding this macro may be avoidable by overriding
|
||||
``LINK_GCC_C_SEQUENCE_SPEC`` instead.
|
||||
|
||||
.. c:var:: bool TARGET_ALWAYS_STRIP_DOTDOT
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ALWAYS_STRIP_DOTDOT]
|
||||
:end-before: [TARGET_ALWAYS_STRIP_DOTDOT]
|
||||
|
||||
.. hook-start:TARGET_ALWAYS_STRIP_DOTDOT
|
||||
|
||||
True if :samp:`..` components should always be removed from directory names
|
||||
computed relative to GCC's internal directories, false (default) if such
|
||||
components should be preserved and directory names containing them passed
|
||||
to other tools such as the linker.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: MULTILIB_DEFAULTS
|
||||
|
||||
|
@ -10,102 +10,46 @@
|
||||
D ABI parameters
|
||||
****************
|
||||
|
||||
.. function:: void TARGET_D_CPU_VERSIONS (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_CPU_VERSIONS]
|
||||
:end-before: [TARGET_D_CPU_VERSIONS]
|
||||
|
||||
.. hook-start:TARGET_D_CPU_VERSIONS
|
||||
|
||||
Declare all environmental version identifiers relating to the target CPU
|
||||
using the function ``builtin_version``, which takes a string representing
|
||||
the name of the version. Version identifiers predefined by this hook apply
|
||||
to all modules that are being compiled and imported.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_OS_VERSIONS]
|
||||
:end-before: [TARGET_D_OS_VERSIONS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_D_OS_VERSIONS (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_REGISTER_CPU_TARGET_INFO]
|
||||
:end-before: [TARGET_D_REGISTER_CPU_TARGET_INFO]
|
||||
|
||||
.. hook-start:TARGET_D_OS_VERSIONS
|
||||
|
||||
Similarly to ``TARGET_D_CPU_VERSIONS``, but is used for versions
|
||||
relating to the target operating system.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_REGISTER_OS_TARGET_INFO]
|
||||
:end-before: [TARGET_D_REGISTER_OS_TARGET_INFO]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_MINFO_SECTION]
|
||||
:end-before: [TARGET_D_MINFO_SECTION]
|
||||
|
||||
.. hook-start:TARGET_D_REGISTER_CPU_TARGET_INFO
|
||||
|
||||
Register all target information keys relating to the target CPU using the
|
||||
function ``d_add_target_info_handlers``, which takes a
|
||||
:samp:`struct d_target_info_spec` (defined in :samp:`d/d-target.h`). The keys
|
||||
added by this hook are made available at compile time by the
|
||||
``__traits(getTargetInfo)`` extension, the result is an expression
|
||||
describing the requested target information.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_MINFO_SECTION_START]
|
||||
:end-before: [TARGET_D_MINFO_SECTION_START]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_D_REGISTER_OS_TARGET_INFO (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_MINFO_SECTION_END]
|
||||
:end-before: [TARGET_D_MINFO_SECTION_END]
|
||||
|
||||
.. hook-start:TARGET_D_REGISTER_OS_TARGET_INFO
|
||||
|
||||
Same as ``TARGET_D_CPU_TARGET_INFO``, but is used for keys relating to
|
||||
the target operating system.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_HAS_STDCALL_CONVENTION]
|
||||
:end-before: [TARGET_D_HAS_STDCALL_CONVENTION]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_D_MINFO_SECTION
|
||||
|
||||
.. hook-start:TARGET_D_MINFO_SECTION
|
||||
|
||||
Contains the name of the section in which module info references should be
|
||||
placed. By default, the compiler puts all module info symbols in the
|
||||
``"minfo"`` section. Define this macro to override the string if a
|
||||
different section name should be used. This section is expected to be
|
||||
bracketed by two symbols ``TARGET_D_MINFO_SECTION_START`` and
|
||||
``TARGET_D_MINFO_SECTION_END`` to indicate the start and end address of
|
||||
the section, so that the runtime library can collect all modules for each
|
||||
loaded shared library and executable. Setting the value to ``NULL``
|
||||
disables the use of sections for storing module info altogether.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_D_MINFO_SECTION_START
|
||||
|
||||
.. hook-start:TARGET_D_MINFO_SECTION_START
|
||||
|
||||
If ``TARGET_D_MINFO_SECTION`` is defined, then this must also be defined
|
||||
as the name of the symbol indicating the start address of the module info
|
||||
section
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_D_MINFO_SECTION_END
|
||||
|
||||
.. hook-start:TARGET_D_MINFO_SECTION_END
|
||||
|
||||
If ``TARGET_D_MINFO_SECTION`` is defined, then this must also be defined
|
||||
as the name of the symbol indicating the end address of the module info
|
||||
section
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_D_HAS_STDCALL_CONVENTION (unsigned int *link_system, unsigned int *link_windows)
|
||||
|
||||
.. hook-start:TARGET_D_HAS_STDCALL_CONVENTION
|
||||
|
||||
Returns ``true`` if the target supports the stdcall calling convention.
|
||||
The hook should also set :samp:`{link_system}` to ``1`` if the ``stdcall``
|
||||
attribute should be applied to functions with ``extern(System)`` linkage,
|
||||
and :samp:`{link_windows}` to ``1`` to apply ``stdcall`` to functions with
|
||||
``extern(Windows)`` linkage.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_D_TEMPLATES_ALWAYS_COMDAT
|
||||
|
||||
.. hook-start:TARGET_D_TEMPLATES_ALWAYS_COMDAT
|
||||
|
||||
This flag is true if instantiated functions and variables are always COMDAT
|
||||
if they have external linkage. If this flag is false, then instantiated
|
||||
decls will be emitted as weak symbols. The default is ``false``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_D_TEMPLATES_ALWAYS_COMDAT]
|
||||
:end-before: [TARGET_D_TEMPLATES_ALWAYS_COMDAT]
|
||||
|
@ -14,100 +14,40 @@ Target-specific attributes may be defined for functions, data and types.
|
||||
These are described using the following target hooks; they also need to
|
||||
be documented in :samp:`extend.texi`.
|
||||
|
||||
.. c:var:: const struct attribute_spec * TARGET_ATTRIBUTE_TABLE
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ATTRIBUTE_TABLE]
|
||||
:end-before: [TARGET_ATTRIBUTE_TABLE]
|
||||
|
||||
.. hook-start:TARGET_ATTRIBUTE_TABLE
|
||||
|
||||
If defined, this target hook points to an array of :samp:`struct
|
||||
attribute_spec` (defined in :samp:`tree-core.h`) specifying the machine
|
||||
specific attributes for this target and some of the restrictions on the
|
||||
entities to which these attributes are applied and the arguments they
|
||||
take.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P]
|
||||
:end-before: [TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P (const_tree name)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_COMP_TYPE_ATTRIBUTES]
|
||||
:end-before: [TARGET_COMP_TYPE_ATTRIBUTES]
|
||||
|
||||
.. hook-start:TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
|
||||
|
||||
If defined, this target hook is a function which returns true if the
|
||||
machine-specific attribute named :samp:`{name}` expects an identifier
|
||||
given as its first argument to be passed on as a plain identifier, not
|
||||
subjected to name lookup. If this is not defined, the default is
|
||||
false for all machine-specific attributes.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SET_DEFAULT_TYPE_ATTRIBUTES]
|
||||
:end-before: [TARGET_SET_DEFAULT_TYPE_ATTRIBUTES]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_COMP_TYPE_ATTRIBUTES (const_tree type1, const_tree type2)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MERGE_TYPE_ATTRIBUTES]
|
||||
:end-before: [TARGET_MERGE_TYPE_ATTRIBUTES]
|
||||
|
||||
.. hook-start:TARGET_COMP_TYPE_ATTRIBUTES
|
||||
|
||||
If defined, this target hook is a function which returns zero if the attributes on
|
||||
:samp:`{type1}` and :samp:`{type2}` are incompatible, one if they are compatible,
|
||||
and two if they are nearly compatible (which causes a warning to be
|
||||
generated). If this is not defined, machine-specific attributes are
|
||||
supposed always to be compatible.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MERGE_DECL_ATTRIBUTES]
|
||||
:end-before: [TARGET_MERGE_DECL_ATTRIBUTES]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SET_DEFAULT_TYPE_ATTRIBUTES (tree type)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VALID_DLLIMPORT_ATTRIBUTE_P]
|
||||
:end-before: [TARGET_VALID_DLLIMPORT_ATTRIBUTE_P]
|
||||
|
||||
.. hook-start:TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
|
||||
|
||||
If defined, this target hook is a function which assigns default attributes to
|
||||
the newly defined :samp:`{type}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_MERGE_TYPE_ATTRIBUTES (tree type1, tree type2)
|
||||
|
||||
.. hook-start:TARGET_MERGE_TYPE_ATTRIBUTES
|
||||
|
||||
Define this target hook if the merging of type attributes needs special
|
||||
handling. If defined, the result is a list of the combined
|
||||
``TYPE_ATTRIBUTES`` of :samp:`{type1}` and :samp:`{type2}`. It is assumed
|
||||
that ``comptypes`` has already been called and returned 1. This
|
||||
function may call ``merge_attributes`` to handle machine-independent
|
||||
merging.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_MERGE_DECL_ATTRIBUTES (tree olddecl, tree newdecl)
|
||||
|
||||
.. hook-start:TARGET_MERGE_DECL_ATTRIBUTES
|
||||
|
||||
Define this target hook if the merging of decl attributes needs special
|
||||
handling. If defined, the result is a list of the combined
|
||||
``DECL_ATTRIBUTES`` of :samp:`{olddecl}` and :samp:`{newdecl}`.
|
||||
:samp:`{newdecl}` is a duplicate declaration of :samp:`{olddecl}`. Examples of
|
||||
when this is needed are when one attribute overrides another, or when an
|
||||
attribute is nullified by a subsequent definition. This function may
|
||||
call ``merge_attributes`` to handle machine-independent merging.
|
||||
|
||||
.. index:: TARGET_DLLIMPORT_DECL_ATTRIBUTES
|
||||
|
||||
If the only target-specific handling you require is :samp:`dllimport`
|
||||
for Microsoft Windows targets, you should define the macro
|
||||
``TARGET_DLLIMPORT_DECL_ATTRIBUTES`` to ``1``. The compiler
|
||||
will then define a function called
|
||||
``merge_dllimport_decl_attributes`` which can then be defined as
|
||||
the expansion of ``TARGET_MERGE_DECL_ATTRIBUTES``. You can also
|
||||
add ``handle_dll_attribute`` in the attribute table for your port
|
||||
to perform initial processing of the :samp:`dllimport` and
|
||||
:samp:`dllexport` attributes. This is done in :samp:`i386/cygwin.h` and
|
||||
:samp:`i386/i386.cc`, for example.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_VALID_DLLIMPORT_ATTRIBUTE_P (const_tree decl)
|
||||
|
||||
.. hook-start:TARGET_VALID_DLLIMPORT_ATTRIBUTE_P
|
||||
|
||||
:samp:`{decl}` is a variable or function with ``__attribute__((dllimport))``
|
||||
specified. Use this hook if the target needs to add extra validation
|
||||
checks to ``handle_dll_attribute``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: TARGET_DECLSPEC
|
||||
|
||||
@ -118,202 +58,76 @@ be documented in :samp:`extend.texi`.
|
||||
of ``__declspec`` is via a built-in macro, but you should not rely
|
||||
on this implementation detail.
|
||||
|
||||
.. function:: void TARGET_INSERT_ATTRIBUTES (tree node, tree *attr_ptr)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_INSERT_ATTRIBUTES]
|
||||
:end-before: [TARGET_INSERT_ATTRIBUTES]
|
||||
|
||||
.. hook-start:TARGET_INSERT_ATTRIBUTES
|
||||
|
||||
Define this target hook if you want to be able to add attributes to a decl
|
||||
when it is being created. This is normally useful for back ends which
|
||||
wish to implement a pragma by using the attributes which correspond to
|
||||
the pragma's effect. The :samp:`{node}` argument is the decl which is being
|
||||
created. The :samp:`{attr_ptr}` argument is a pointer to the attribute list
|
||||
for this decl. The list itself should not be modified, since it may be
|
||||
shared with other decls, but attributes may be chained on the head of
|
||||
the list and ``*attr_ptr`` modified to point to the new
|
||||
attributes, or a copy of the list may be made if further changes are
|
||||
needed.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HANDLE_GENERIC_ATTRIBUTE]
|
||||
:end-before: [TARGET_HANDLE_GENERIC_ATTRIBUTE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_HANDLE_GENERIC_ATTRIBUTE (tree *node, tree name, tree args, int flags, bool *no_add_attrs)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P]
|
||||
:end-before: [TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P]
|
||||
|
||||
.. hook-start:TARGET_HANDLE_GENERIC_ATTRIBUTE
|
||||
|
||||
Define this target hook if you want to be able to perform additional
|
||||
target-specific processing of an attribute which is handled generically
|
||||
by a front end. The arguments are the same as those which are passed to
|
||||
attribute handlers. So far this only affects the :samp:`{noinit}` and
|
||||
:samp:`{section}` attribute.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_VALID_ATTRIBUTE_P]
|
||||
:end-before: [TARGET_OPTION_VALID_ATTRIBUTE_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P (const_tree fndecl)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_SAVE]
|
||||
:end-before: [TARGET_OPTION_SAVE]
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
|
||||
|
||||
.. index:: inlining
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_RESTORE]
|
||||
:end-before: [TARGET_OPTION_RESTORE]
|
||||
|
||||
This target hook returns ``true`` if it is OK to inline :samp:`{fndecl}`
|
||||
into the current function, despite its having target-specific
|
||||
attributes, ``false`` otherwise. By default, if a function has a
|
||||
target specific attribute attached to it, it will not be inlined.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_POST_STREAM_IN]
|
||||
:end-before: [TARGET_OPTION_POST_STREAM_IN]
|
||||
|
||||
.. function:: bool TARGET_OPTION_VALID_ATTRIBUTE_P (tree fndecl, tree name, tree args, int flags)
|
||||
|
||||
.. hook-start:TARGET_OPTION_VALID_ATTRIBUTE_P
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_PRINT]
|
||||
:end-before: [TARGET_OPTION_PRINT]
|
||||
|
||||
This hook is called to parse ``attribute(target("..."))``, which
|
||||
allows setting target-specific options on individual functions.
|
||||
These function-specific options may differ
|
||||
from the options specified on the command line. The hook should return
|
||||
``true`` if the options are valid.
|
||||
|
||||
The hook should set the ``DECL_FUNCTION_SPECIFIC_TARGET`` field in
|
||||
the function declaration to hold a pointer to a target-specific
|
||||
``struct cl_target_option`` structure.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_PRAGMA_PARSE]
|
||||
:end-before: [TARGET_OPTION_PRAGMA_PARSE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_OPTION_SAVE (struct cl_target_option *ptr, struct gcc_options *opts, struct gcc_options *opts_set)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_OVERRIDE]
|
||||
:end-before: [TARGET_OPTION_OVERRIDE]
|
||||
|
||||
.. hook-start:TARGET_OPTION_SAVE
|
||||
|
||||
This hook is called to save any additional target-specific information
|
||||
in the ``struct cl_target_option`` structure for function-specific
|
||||
options from the ``struct gcc_options`` structure.
|
||||
See :ref:`option-file-format`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_FUNCTION_VERSIONS]
|
||||
:end-before: [TARGET_OPTION_FUNCTION_VERSIONS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_OPTION_RESTORE (struct gcc_options *opts, struct gcc_options *opts_set, struct cl_target_option *ptr)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CAN_INLINE_P]
|
||||
:end-before: [TARGET_CAN_INLINE_P]
|
||||
|
||||
.. hook-start:TARGET_OPTION_RESTORE
|
||||
|
||||
This hook is called to restore any additional target-specific
|
||||
information in the ``struct cl_target_option`` structure for
|
||||
function-specific options to the ``struct gcc_options`` structure.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_UPDATE_IPA_FN_TARGET_INFO]
|
||||
:end-before: [TARGET_UPDATE_IPA_FN_TARGET_INFO]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_OPTION_POST_STREAM_IN (struct cl_target_option *ptr)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_NEED_IPA_FN_TARGET_INFO]
|
||||
:end-before: [TARGET_NEED_IPA_FN_TARGET_INFO]
|
||||
|
||||
.. hook-start:TARGET_OPTION_POST_STREAM_IN
|
||||
|
||||
This hook is called to update target-specific information in the
|
||||
``struct cl_target_option`` structure after it is streamed in from
|
||||
LTO bytecode.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_OPTION_PRINT (FILE *file, int indent, struct cl_target_option *ptr)
|
||||
|
||||
.. hook-start:TARGET_OPTION_PRINT
|
||||
|
||||
This hook is called to print any additional target-specific
|
||||
information in the ``struct cl_target_option`` structure for
|
||||
function-specific options.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_OPTION_PRAGMA_PARSE (tree args, tree pop_target)
|
||||
|
||||
.. hook-start:TARGET_OPTION_PRAGMA_PARSE
|
||||
|
||||
This target hook parses the options for ``#pragma GCC target``, which
|
||||
sets the target-specific options for functions that occur later in the
|
||||
input stream. The options accepted should be the same as those handled by the
|
||||
``TARGET_OPTION_VALID_ATTRIBUTE_P`` hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_OPTION_OVERRIDE (void)
|
||||
|
||||
.. hook-start:TARGET_OPTION_OVERRIDE
|
||||
|
||||
Sometimes certain combinations of command options do not make sense on
|
||||
a particular target machine. You can override the hook
|
||||
``TARGET_OPTION_OVERRIDE`` to take account of this. This hooks is called
|
||||
once just after all the command options have been parsed.
|
||||
|
||||
Don't use this hook to turn on various extra optimizations for
|
||||
:option:`-O`. That is what ``TARGET_OPTION_OPTIMIZATION`` is for.
|
||||
|
||||
If you need to do something whenever the optimization level is
|
||||
changed via the optimize attribute or pragma, see
|
||||
``TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE``
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_OPTION_FUNCTION_VERSIONS (tree decl1, tree decl2)
|
||||
|
||||
.. hook-start:TARGET_OPTION_FUNCTION_VERSIONS
|
||||
|
||||
This target hook returns ``true`` if :samp:`{DECL1}` and :samp:`{DECL2}` are
|
||||
versions of the same function. :samp:`{DECL1}` and :samp:`{DECL2}` are function
|
||||
versions if and only if they have the same function signature and
|
||||
different target specific attributes, that is, they are compiled for
|
||||
different target machines.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CAN_INLINE_P (tree caller, tree callee)
|
||||
|
||||
.. hook-start:TARGET_CAN_INLINE_P
|
||||
|
||||
This target hook returns ``false`` if the :samp:`{caller}` function
|
||||
cannot inline :samp:`{callee}`, based on target specific information. By
|
||||
default, inlining is not allowed if the callee function has function
|
||||
specific target options and the caller does not use the same options.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_UPDATE_IPA_FN_TARGET_INFO (unsigned int& info, const gimple* stmt)
|
||||
|
||||
.. hook-start:TARGET_UPDATE_IPA_FN_TARGET_INFO
|
||||
|
||||
Allow target to analyze all gimple statements for the given function to
|
||||
record and update some target specific information for inlining. A typical
|
||||
example is that a caller with one isa feature disabled is normally not
|
||||
allowed to inline a callee with that same isa feature enabled even which is
|
||||
attributed by always_inline, but with the conservative analysis on all
|
||||
statements of the callee if we are able to guarantee the callee does not
|
||||
exploit any instructions from the mismatch isa feature, it would be safe to
|
||||
allow the caller to inline the callee.
|
||||
:samp:`{info}` is one ``unsigned int`` value to record information in which
|
||||
one set bit indicates one corresponding feature is detected in the analysis,
|
||||
:samp:`{stmt}` is the statement being analyzed. Return true if target still
|
||||
need to analyze the subsequent statements, otherwise return false to stop
|
||||
subsequent analysis.
|
||||
The default version of this hook returns false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_NEED_IPA_FN_TARGET_INFO (const_tree decl, unsigned int& info)
|
||||
|
||||
.. hook-start:TARGET_NEED_IPA_FN_TARGET_INFO
|
||||
|
||||
Allow target to check early whether it is necessary to analyze all gimple
|
||||
statements in the given function to update target specific information for
|
||||
inlining. See hook ``update_ipa_fn_target_info`` for usage example of
|
||||
target specific information. This hook is expected to be invoked ahead of
|
||||
the iterating with hook ``update_ipa_fn_target_info``.
|
||||
:samp:`{decl}` is the function being analyzed, :samp:`{info}` is the same as what
|
||||
in hook ``update_ipa_fn_target_info``, target can do one time update
|
||||
into :samp:`{info}` without iterating for some case. Return true if target
|
||||
decides to analyze all gimple statements to collect information, otherwise
|
||||
return false.
|
||||
The default version of this hook returns false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_RELAYOUT_FUNCTION (tree fndecl)
|
||||
|
||||
.. hook-start:TARGET_RELAYOUT_FUNCTION
|
||||
|
||||
This target hook fixes function :samp:`{fndecl}` after attributes are processed.
|
||||
Default does nothing. On ARM, the default function's alignment is updated
|
||||
with the attribute target.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_RELAYOUT_FUNCTION]
|
||||
:end-before: [TARGET_RELAYOUT_FUNCTION]
|
||||
|
@ -54,11 +54,10 @@ region.
|
||||
``INCOMING_RETURN_ADDR_RTX`` and ``OBJECT_FORMAT_ELF``),
|
||||
GCC will provide a default definition of 1.
|
||||
|
||||
.. function:: enum unwind_info_type TARGET_EXCEPT_UNWIND_INFO (struct gcc_options *opts)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_EXCEPT_UNWIND_INFO]
|
||||
:end-before: [TARGET_EXCEPT_UNWIND_INFO]
|
||||
|
||||
.. hook-start:TARGET_EXCEPT_UNWIND_INFO
|
||||
|
||||
.. hook-end
|
||||
|
||||
This hook defines the mechanism that will be used for exception handling
|
||||
by the target. If the target has ABI specified unwind tables, the hook
|
||||
@ -84,11 +83,10 @@ region.
|
||||
``DWARF2_UNWIND_INFO`` depends on command-line options, the target
|
||||
must define this hook so that :samp:`{opts}` is used correctly.
|
||||
|
||||
.. c:var:: bool TARGET_UNWIND_TABLES_DEFAULT
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_UNWIND_TABLES_DEFAULT]
|
||||
:end-before: [TARGET_UNWIND_TABLES_DEFAULT]
|
||||
|
||||
.. hook-start:TARGET_UNWIND_TABLES_DEFAULT
|
||||
|
||||
.. hook-end
|
||||
|
||||
This variable should be set to ``true`` if the target ABI requires unwinding
|
||||
tables even when exceptions are not used. It must not be modified by
|
||||
@ -117,72 +115,31 @@ region.
|
||||
minimum alignment otherwise. See :ref:`dwarf`. Only applicable if
|
||||
the target supports DWARF 2 frame unwind information.
|
||||
|
||||
.. c:var:: bool TARGET_TERMINATE_DW2_EH_FRAME_INFO
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_TERMINATE_DW2_EH_FRAME_INFO]
|
||||
:end-before: [TARGET_TERMINATE_DW2_EH_FRAME_INFO]
|
||||
|
||||
.. hook-start:TARGET_TERMINATE_DW2_EH_FRAME_INFO
|
||||
|
||||
Contains the value true if the target should add a zero word onto the
|
||||
end of a Dwarf-2 frame info section when used for exception handling.
|
||||
Default value is false if ``EH_FRAME_SECTION_NAME`` is defined, and
|
||||
true otherwise.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_DWARF_REGISTER_SPAN]
|
||||
:end-before: [TARGET_DWARF_REGISTER_SPAN]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx TARGET_DWARF_REGISTER_SPAN (rtx reg)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_DWARF_FRAME_REG_MODE]
|
||||
:end-before: [TARGET_DWARF_FRAME_REG_MODE]
|
||||
|
||||
.. hook-start:TARGET_DWARF_REGISTER_SPAN
|
||||
|
||||
Given a register, this hook should return a parallel of registers to
|
||||
represent where to find the register pieces. Define this hook if the
|
||||
register and its mode are represented in Dwarf in non-contiguous
|
||||
locations, or if the register should be represented in more than one
|
||||
register in Dwarf. Otherwise, this hook should return ``NULL_RTX``.
|
||||
If not defined, the default is to return ``NULL_RTX``.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_INIT_DWARF_REG_SIZES_EXTRA]
|
||||
:end-before: [TARGET_INIT_DWARF_REG_SIZES_EXTRA]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: machine_mode TARGET_DWARF_FRAME_REG_MODE (int regno)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_TTYPE]
|
||||
:end-before: [TARGET_ASM_TTYPE]
|
||||
|
||||
.. hook-start:TARGET_DWARF_FRAME_REG_MODE
|
||||
|
||||
Given a register, this hook should return the mode which the
|
||||
corresponding Dwarf frame register should have. This is normally
|
||||
used to return a smaller mode than the raw mode to prevent call
|
||||
clobbered parts of a register altering the frame register size
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_INIT_DWARF_REG_SIZES_EXTRA (tree address)
|
||||
|
||||
.. hook-start:TARGET_INIT_DWARF_REG_SIZES_EXTRA
|
||||
|
||||
If some registers are represented in Dwarf-2 unwind information in
|
||||
multiple pieces, define this hook to fill in information about the
|
||||
sizes of those pieces in the table used by the unwinder at runtime.
|
||||
It will be called by ``expand_builtin_init_dwarf_reg_sizes`` after
|
||||
filling in a single size corresponding to each hard register;
|
||||
:samp:`{address}` is the address of the table.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ASM_TTYPE (rtx sym)
|
||||
|
||||
.. hook-start:TARGET_ASM_TTYPE
|
||||
|
||||
This hook is used to output a reference from a frame unwinding table to
|
||||
the type_info object identified by :samp:`{sym}`. It should return ``true``
|
||||
if the reference was output. Returning ``false`` will cause the
|
||||
reference to be output using the normal Dwarf2 routines.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_ARM_EABI_UNWINDER
|
||||
|
||||
.. hook-start:TARGET_ARM_EABI_UNWINDER
|
||||
|
||||
This flag should be set to ``true`` on targets that use an ARM EABI
|
||||
based unwinding library, and ``false`` on other targets. This effects
|
||||
the format of unwinding tables, and how the unwinder in entered after
|
||||
running a cleanup. The default is ``false``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ARM_EABI_UNWINDER]
|
||||
:end-before: [TARGET_ARM_EABI_UNWINDER]
|
||||
|
@ -71,55 +71,25 @@ and termination functions:
|
||||
of objects. If zero, the compiler will issue an error message upon
|
||||
encountering an ``init_priority`` attribute.
|
||||
|
||||
.. c:var:: bool TARGET_HAVE_CTORS_DTORS
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_HAVE_CTORS_DTORS]
|
||||
:end-before: [TARGET_HAVE_CTORS_DTORS]
|
||||
|
||||
.. hook-start:TARGET_HAVE_CTORS_DTORS
|
||||
|
||||
This value is true if the target supports some 'native' method of
|
||||
collecting constructors and destructors to be run at startup and exit.
|
||||
It is false if we must use :command:`collect2`.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_DTORS_FROM_CXA_ATEXIT]
|
||||
:end-before: [TARGET_DTORS_FROM_CXA_ATEXIT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_DTORS_FROM_CXA_ATEXIT
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_CONSTRUCTOR]
|
||||
:end-before: [TARGET_ASM_CONSTRUCTOR]
|
||||
|
||||
.. hook-start:TARGET_DTORS_FROM_CXA_ATEXIT
|
||||
|
||||
This value is true if the target wants destructors to be queued to be
|
||||
run from __cxa_atexit. If this is the case then, for each priority level,
|
||||
a new constructor will be entered that registers the destructors for that
|
||||
level with __cxa_atexit (and there will be no destructors emitted).
|
||||
It is false the method implied by ``have_ctors_dtors`` is used.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_DESTRUCTOR]
|
||||
:end-before: [TARGET_ASM_DESTRUCTOR]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_CONSTRUCTOR (rtx symbol, int priority)
|
||||
|
||||
.. hook-start:TARGET_ASM_CONSTRUCTOR
|
||||
|
||||
If defined, a function that outputs assembler code to arrange to call
|
||||
the function referenced by :samp:`{symbol}` at initialization time.
|
||||
|
||||
Assume that :samp:`{symbol}` is a ``SYMBOL_REF`` for a function taking
|
||||
no arguments and with no return value. If the target supports initialization
|
||||
priorities, :samp:`{priority}` is a value between 0 and ``MAX_INIT_PRIORITY`` ;
|
||||
otherwise it must be ``DEFAULT_INIT_PRIORITY``.
|
||||
|
||||
If this macro is not defined by the target, a suitable default will
|
||||
be chosen if (1) the target supports arbitrary section names, (2) the
|
||||
target defines ``CTORS_SECTION_ASM_OP``, or (3) ``USE_COLLECT2``
|
||||
is not defined.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_DESTRUCTOR (rtx symbol, int priority)
|
||||
|
||||
.. hook-start:TARGET_ASM_DESTRUCTOR
|
||||
|
||||
This is like ``TARGET_ASM_CONSTRUCTOR`` but used for termination
|
||||
functions rather than initialization functions.
|
||||
|
||||
.. hook-end
|
||||
|
||||
If ``TARGET_HAVE_CTORS_DTORS`` is true, the initialization routine
|
||||
generated for the generated object file will have static linkage.
|
||||
|
@ -199,23 +199,10 @@ This is about outputting labels.
|
||||
You may wish to use ``ASM_OUTPUT_TYPE_DIRECTIVE`` and/or
|
||||
``ASM_OUTPUT_SIZE_DIRECTIVE`` in the definition of this macro.
|
||||
|
||||
.. function:: void TARGET_ASM_DECLARE_CONSTANT_NAME (FILE *file, const char *name, const_tree expr, HOST_WIDE_INT size)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_DECLARE_CONSTANT_NAME]
|
||||
:end-before: [TARGET_ASM_DECLARE_CONSTANT_NAME]
|
||||
|
||||
.. hook-start:TARGET_ASM_DECLARE_CONSTANT_NAME
|
||||
|
||||
A target hook to output to the stdio stream :samp:`{file}` any text necessary
|
||||
for declaring the name :samp:`{name}` of a constant which is being defined. This
|
||||
target hook is responsible for outputting the label definition (perhaps using
|
||||
``assemble_label``). The argument :samp:`{exp}` is the value of the constant,
|
||||
and :samp:`{size}` is the size of the constant in bytes. The :samp:`{name}`
|
||||
will be an internal label.
|
||||
|
||||
The default version of this target hook, define the :samp:`{name}` in the
|
||||
usual manner as a label (by means of ``assemble_label``).
|
||||
|
||||
You may wish to use ``ASM_OUTPUT_TYPE_DIRECTIVE`` in this target hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ASM_DECLARE_REGISTER_GLOBAL (stream, decl, regno, name)
|
||||
|
||||
@ -240,41 +227,20 @@ This is about outputting labels.
|
||||
You may wish to use ``ASM_OUTPUT_SIZE_DIRECTIVE`` and/or
|
||||
``ASM_OUTPUT_MEASURED_SIZE`` in the definition of this macro.
|
||||
|
||||
.. function:: void TARGET_ASM_GLOBALIZE_LABEL (FILE *stream, const char *name)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_GLOBALIZE_LABEL]
|
||||
:end-before: [TARGET_ASM_GLOBALIZE_LABEL]
|
||||
|
||||
.. hook-start:TARGET_ASM_GLOBALIZE_LABEL
|
||||
|
||||
This target hook is a function to output to the stdio stream
|
||||
:samp:`{stream}` some commands that will make the label :samp:`{name}` global;
|
||||
that is, available for reference from other files.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_GLOBALIZE_DECL_NAME]
|
||||
:end-before: [TARGET_ASM_GLOBALIZE_DECL_NAME]
|
||||
|
||||
The default implementation relies on a proper definition of
|
||||
``GLOBAL_ASM_OP``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_ASSEMBLE_UNDEFINED_DECL]
|
||||
:end-before: [TARGET_ASM_ASSEMBLE_UNDEFINED_DECL]
|
||||
|
||||
.. function:: void TARGET_ASM_GLOBALIZE_DECL_NAME (FILE *stream, tree decl)
|
||||
|
||||
.. hook-start:TARGET_ASM_GLOBALIZE_DECL_NAME
|
||||
|
||||
This target hook is a function to output to the stdio stream
|
||||
:samp:`{stream}` some commands that will make the name associated with :samp:`{decl}`
|
||||
global; that is, available for reference from other files.
|
||||
|
||||
The default implementation uses the TARGET_ASM_GLOBALIZE_LABEL target hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_ASSEMBLE_UNDEFINED_DECL (FILE *stream, const char *name, const_tree decl)
|
||||
|
||||
.. hook-start:TARGET_ASM_ASSEMBLE_UNDEFINED_DECL
|
||||
|
||||
This target hook is a function to output to the stdio stream
|
||||
:samp:`{stream}` some commands that will declare the name associated with
|
||||
:samp:`{decl}` which is not defined in the current translation unit. Most
|
||||
assemblers do not require anything to be output in this case.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ASM_WEAKEN_LABEL (stream, name)
|
||||
|
||||
@ -345,15 +311,10 @@ This is about outputting labels.
|
||||
setting the ``DECL_ONE_ONLY`` flag is enough to mark a declaration to
|
||||
be emitted as one-only.
|
||||
|
||||
.. function:: void TARGET_ASM_ASSEMBLE_VISIBILITY (tree decl, int visibility)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_ASSEMBLE_VISIBILITY]
|
||||
:end-before: [TARGET_ASM_ASSEMBLE_VISIBILITY]
|
||||
|
||||
.. hook-start:TARGET_ASM_ASSEMBLE_VISIBILITY
|
||||
|
||||
This target hook is a function to output to :samp:`{asm_out_file}` some
|
||||
commands that will make the symbol(s) associated with :samp:`{decl}` have
|
||||
hidden, protected or internal visibility as specified by :samp:`{visibility}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: TARGET_WEAK_NOT_IN_ARCHIVE_TOC
|
||||
|
||||
@ -385,25 +346,15 @@ This is about outputting labels.
|
||||
This macro need not be defined if it does not need to output anything.
|
||||
The GNU assembler and most Unix assemblers don't require anything.
|
||||
|
||||
.. function:: void TARGET_ASM_EXTERNAL_LIBCALL (rtx symref)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_EXTERNAL_LIBCALL]
|
||||
:end-before: [TARGET_ASM_EXTERNAL_LIBCALL]
|
||||
|
||||
.. hook-start:TARGET_ASM_EXTERNAL_LIBCALL
|
||||
|
||||
This target hook is a function to output to :samp:`{asm_out_file}` an assembler
|
||||
pseudo-op to declare a library function name external. The name of the
|
||||
library function is given by :samp:`{symref}`, which is a ``symbol_ref``.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_MARK_DECL_PRESERVED]
|
||||
:end-before: [TARGET_ASM_MARK_DECL_PRESERVED]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_MARK_DECL_PRESERVED (const char *symbol)
|
||||
|
||||
.. hook-start:TARGET_ASM_MARK_DECL_PRESERVED
|
||||
|
||||
This target hook is a function to output to :samp:`{asm_out_file}` an assembler
|
||||
directive to annotate :samp:`{symbol}` as used. The Darwin target uses the
|
||||
.no_dead_code_strip directive.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ASM_OUTPUT_LABELREF (stream, name)
|
||||
|
||||
@ -413,17 +364,10 @@ This is about outputting labels.
|
||||
is customary on your operating system, as it is in most Berkeley Unix
|
||||
systems. This macro is used in ``assemble_name``.
|
||||
|
||||
.. function:: tree TARGET_MANGLE_ASSEMBLER_NAME (const char *name)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_MANGLE_ASSEMBLER_NAME]
|
||||
:end-before: [TARGET_MANGLE_ASSEMBLER_NAME]
|
||||
|
||||
.. hook-start:TARGET_MANGLE_ASSEMBLER_NAME
|
||||
|
||||
Given a symbol :samp:`{name}`, perform same mangling as ``varasm.cc`` 's
|
||||
``assemble_name``, but in memory rather than to a file stream, returning
|
||||
result as an ``IDENTIFIER_NODE``. Required for correct LTO symtabs. The
|
||||
default implementation calls the ``TARGET_STRIP_NAME_ENCODING`` hook and
|
||||
then prepends the ``USER_LABEL_PREFIX``, if any.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ASM_OUTPUT_SYMBOL_REF (stream, sym)
|
||||
|
||||
@ -443,26 +387,10 @@ This is about outputting labels.
|
||||
when it is necessary to output a label differently when its address is
|
||||
being taken.
|
||||
|
||||
.. function:: void TARGET_ASM_INTERNAL_LABEL (FILE *stream, const char *prefix, unsigned long labelno)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_INTERNAL_LABEL]
|
||||
:end-before: [TARGET_ASM_INTERNAL_LABEL]
|
||||
|
||||
.. hook-start:TARGET_ASM_INTERNAL_LABEL
|
||||
|
||||
A function to output to the stdio stream :samp:`{stream}` a label whose
|
||||
name is made from the string :samp:`{prefix}` and the number :samp:`{labelno}`.
|
||||
|
||||
It is absolutely essential that these labels be distinct from the labels
|
||||
used for user-level functions and variables. Otherwise, certain programs
|
||||
will have name conflicts with internal labels.
|
||||
|
||||
It is desirable to exclude internal labels from the symbol table of the
|
||||
object file. Most assemblers have a naming convention for labels that
|
||||
should be excluded; on many systems, the letter :samp:`L` at the
|
||||
beginning of a label has this effect. You should find out what
|
||||
convention your system uses, and follow it.
|
||||
|
||||
The default version of this function utilizes ``ASM_GENERATE_INTERNAL_LABEL``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ASM_OUTPUT_DEBUG_LABEL (stream, prefix, num)
|
||||
|
||||
|
@ -91,22 +91,10 @@ This describes assembler instruction output.
|
||||
|
||||
If this macro is not defined, it is equivalent to a null statement.
|
||||
|
||||
.. function:: void TARGET_ASM_FINAL_POSTSCAN_INSN (FILE *file, rtx_insn *insn, rtx *opvec, int noperands)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FINAL_POSTSCAN_INSN]
|
||||
:end-before: [TARGET_ASM_FINAL_POSTSCAN_INSN]
|
||||
|
||||
.. hook-start:TARGET_ASM_FINAL_POSTSCAN_INSN
|
||||
|
||||
If defined, this target hook is a function which is executed just after the
|
||||
output of assembler code for :samp:`{insn}`, to change the mode of the assembler
|
||||
if necessary.
|
||||
|
||||
Here the argument :samp:`{opvec}` is the vector containing the operands
|
||||
extracted from :samp:`{insn}`, and :samp:`{noperands}` is the number of
|
||||
elements of the vector which contain meaningful data for this insn.
|
||||
The contents of this vector are what was used to convert the insn
|
||||
template into assembler code, so you can change the assembler mode
|
||||
by checking the contents of the vector.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: PRINT_OPERAND (stream, x, code)
|
||||
|
||||
|
@ -8,63 +8,25 @@
|
||||
Output of Data
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:var:: const char * TARGET_ASM_BYTE_OP
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_BYTE_OP]
|
||||
:end-before: [TARGET_ASM_BYTE_OP]
|
||||
|
||||
.. hook-start:TARGET_ASM_BYTE_OP
|
||||
|
||||
These hooks specify assembly directives for creating certain kinds
|
||||
of integer object. The ``TARGET_ASM_BYTE_OP`` directive creates a
|
||||
byte-sized object, the ``TARGET_ASM_ALIGNED_HI_OP`` one creates an
|
||||
aligned two-byte object, and so on. Any of the hooks may be
|
||||
``NULL``, indicating that no suitable directive is available.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_INTEGER]
|
||||
:end-before: [TARGET_ASM_INTEGER]
|
||||
|
||||
The compiler will print these strings at the start of a new line,
|
||||
followed immediately by the object's initial value. In most cases,
|
||||
the string should contain a tab, a pseudo-op, and then another tab.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_DECL_END]
|
||||
:end-before: [TARGET_ASM_DECL_END]
|
||||
|
||||
.. function:: bool TARGET_ASM_INTEGER (rtx x, unsigned int size, int aligned_p)
|
||||
|
||||
.. hook-start:TARGET_ASM_INTEGER
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA]
|
||||
:end-before: [TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA]
|
||||
|
||||
The ``assemble_integer`` function uses this hook to output an
|
||||
integer object. :samp:`{x}` is the object's value, :samp:`{size}` is its size
|
||||
in bytes and :samp:`{aligned_p}` indicates whether it is aligned. The
|
||||
function should return ``true`` if it was able to output the
|
||||
object. If it returns false, ``assemble_integer`` will try to
|
||||
split the object into smaller parts.
|
||||
|
||||
The default implementation of this hook will use the
|
||||
``TARGET_ASM_BYTE_OP`` family of strings, returning ``false``
|
||||
when the relevant string is ``NULL``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_DECL_END (void)
|
||||
|
||||
.. hook-start:TARGET_ASM_DECL_END
|
||||
|
||||
Define this hook if the target assembler requires a special marker to
|
||||
terminate an initialized variable declaration.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA (FILE *file, rtx x)
|
||||
|
||||
.. hook-start:TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
|
||||
|
||||
A target hook to recognize :samp:`{rtx}` patterns that ``output_addr_const``
|
||||
can't deal with, and output assembly code to :samp:`{file}` corresponding to
|
||||
the pattern :samp:`{x}`. This may be used to allow machine-dependent
|
||||
``UNSPEC`` s to appear within constants.
|
||||
|
||||
If target hook fails to recognize a pattern, it must return ``false``,
|
||||
so that a standard error message is printed. If it prints an error message
|
||||
itself, by calling, for example, ``output_operand_lossage``, it may just
|
||||
return ``true``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ASM_OUTPUT_ASCII (stream, ptr, len)
|
||||
|
||||
@ -155,15 +117,10 @@ Output of Data
|
||||
|
||||
.. c:var:: const char * TARGET_ASM_OPEN_PAREN
|
||||
|
||||
.. c:var:: const char * TARGET_ASM_CLOSE_PAREN
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_OPEN_PAREN]
|
||||
:end-before: [TARGET_ASM_OPEN_PAREN]
|
||||
|
||||
.. hook-start:TARGET_ASM_OPEN_PAREN
|
||||
|
||||
These target hooks are C string constants, describing the syntax in the
|
||||
assembler for grouping arithmetic expressions. If not overridden, they
|
||||
default to normal parentheses, which is correct for most assemblers.
|
||||
|
||||
.. hook-end
|
||||
|
||||
These macros are provided by :samp:`real.h` for writing the definitions
|
||||
of ``ASM_OUTPUT_DOUBLE`` and the like:
|
||||
|
@ -75,97 +75,41 @@ This concerns dispatch tables.
|
||||
If this macro is not defined, nothing special is output at the end of
|
||||
the jump-table.
|
||||
|
||||
.. function:: void TARGET_ASM_POST_CFI_STARTPROC (FILE *, tree)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_POST_CFI_STARTPROC]
|
||||
:end-before: [TARGET_ASM_POST_CFI_STARTPROC]
|
||||
|
||||
.. hook-start:TARGET_ASM_POST_CFI_STARTPROC
|
||||
|
||||
This target hook is used to emit assembly strings required by the target
|
||||
after the .cfi_startproc directive. The first argument is the file stream to
|
||||
write the strings to and the second argument is the function's declaration. The
|
||||
expected use is to add more .cfi_\* directives.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_EMIT_UNWIND_LABEL]
|
||||
:end-before: [TARGET_ASM_EMIT_UNWIND_LABEL]
|
||||
|
||||
The default is to not output any assembly strings.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_EMIT_EXCEPT_TABLE_LABEL]
|
||||
:end-before: [TARGET_ASM_EMIT_EXCEPT_TABLE_LABEL]
|
||||
|
||||
.. function:: void TARGET_ASM_EMIT_UNWIND_LABEL (FILE *stream, tree decl, int for_eh, int empty)
|
||||
|
||||
.. hook-start:TARGET_ASM_EMIT_UNWIND_LABEL
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_EMIT_EXCEPT_PERSONALITY]
|
||||
:end-before: [TARGET_ASM_EMIT_EXCEPT_PERSONALITY]
|
||||
|
||||
This target hook emits a label at the beginning of each FDE. It
|
||||
should be defined on targets where FDEs need special labels, and it
|
||||
should write the appropriate label, for the FDE associated with the
|
||||
function declaration :samp:`{decl}`, to the stdio stream :samp:`{stream}`.
|
||||
The third argument, :samp:`{for_eh}`, is a boolean: true if this is for an
|
||||
exception table. The fourth argument, :samp:`{empty}`, is a boolean:
|
||||
true if this is a placeholder label for an omitted FDE.
|
||||
|
||||
The default is that FDEs are not given nonlocal labels.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_UNWIND_EMIT]
|
||||
:end-before: [TARGET_ASM_UNWIND_EMIT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_EMIT_EXCEPT_TABLE_LABEL (FILE *stream)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT]
|
||||
:end-before: [TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT]
|
||||
|
||||
.. hook-start:TARGET_ASM_EMIT_EXCEPT_TABLE_LABEL
|
||||
|
||||
This target hook emits a label at the beginning of the exception table.
|
||||
It should be defined on targets where it is desirable for the table
|
||||
to be broken up according to function.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_UNWIND_EMIT_BEFORE_INSN]
|
||||
:end-before: [TARGET_ASM_UNWIND_EMIT_BEFORE_INSN]
|
||||
|
||||
The default is that no label is emitted.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_EMIT_EXCEPT_PERSONALITY (rtx personality)
|
||||
|
||||
.. hook-start:TARGET_ASM_EMIT_EXCEPT_PERSONALITY
|
||||
|
||||
If the target implements ``TARGET_ASM_UNWIND_EMIT``, this hook may be
|
||||
used to emit a directive to install a personality hook into the unwind
|
||||
info. This hook should not be used if dwarf2 unwind info is used.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_UNWIND_EMIT (FILE *stream, rtx_insn *insn)
|
||||
|
||||
.. hook-start:TARGET_ASM_UNWIND_EMIT
|
||||
|
||||
This target hook emits assembly directives required to unwind the
|
||||
given instruction. This is only used when ``TARGET_EXCEPT_UNWIND_INFO``
|
||||
returns ``UI_TARGET``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT (rtx origsymbol, bool pubvis)
|
||||
|
||||
.. hook-start:TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT
|
||||
|
||||
If necessary, modify personality and LSDA references to handle indirection.
|
||||
The original symbol is in ``origsymbol`` and if ``pubvis`` is true
|
||||
the symbol is visible outside the TU.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_ASM_UNWIND_EMIT_BEFORE_INSN
|
||||
|
||||
.. hook-start:TARGET_ASM_UNWIND_EMIT_BEFORE_INSN
|
||||
|
||||
True if the ``TARGET_ASM_UNWIND_EMIT`` hook should be called before
|
||||
the assembly for :samp:`{insn}` has been emitted, false if the hook should
|
||||
be called afterward.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ASM_SHOULD_RESTORE_CFA_STATE (void)
|
||||
|
||||
.. hook-start:TARGET_ASM_SHOULD_RESTORE_CFA_STATE
|
||||
|
||||
For DWARF-based unwind frames, two CFI instructions provide for save and
|
||||
restore of register state. GCC maintains the current frame address (CFA)
|
||||
separately from the register bank but the unwinder in libgcc preserves this
|
||||
state along with the registers (and this is expected by the code that writes
|
||||
the unwind frames). This hook allows the target to specify that the CFA data
|
||||
is not saved/restored along with the registers by the target unwinder so that
|
||||
suitable additional instructions should be emitted to restore it.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_SHOULD_RESTORE_CFA_STATE]
|
||||
:end-before: [TARGET_ASM_SHOULD_RESTORE_CFA_STATE]
|
||||
|
@ -16,56 +16,25 @@ This describes the overall framework of an assembly file.
|
||||
|
||||
.. index:: default_file_start
|
||||
|
||||
.. function:: void TARGET_ASM_FILE_START (void)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FILE_START]
|
||||
:end-before: [TARGET_ASM_FILE_START]
|
||||
|
||||
.. hook-start:TARGET_ASM_FILE_START
|
||||
|
||||
Output to ``asm_out_file`` any text which the assembler expects to
|
||||
find at the beginning of a file. The default behavior is controlled
|
||||
by two flags, documented below. Unless your target's assembler is
|
||||
quite unusual, if you override the default, you should call
|
||||
``default_file_start`` at some point in your target hook. This
|
||||
lets other target files rely on these variables.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FILE_START_APP_OFF]
|
||||
:end-before: [TARGET_ASM_FILE_START_APP_OFF]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_ASM_FILE_START_APP_OFF
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FILE_START_FILE_DIRECTIVE]
|
||||
:end-before: [TARGET_ASM_FILE_START_FILE_DIRECTIVE]
|
||||
|
||||
.. hook-start:TARGET_ASM_FILE_START_APP_OFF
|
||||
|
||||
If this flag is true, the text of the macro ``ASM_APP_OFF`` will be
|
||||
printed as the very first line in the assembly file, unless
|
||||
:option:`-fverbose-asm` is in effect. (If that macro has been defined
|
||||
to the empty string, this variable has no effect.) With the normal
|
||||
definition of ``ASM_APP_OFF``, the effect is to notify the GNU
|
||||
assembler that it need not bother stripping comments or extra
|
||||
whitespace from its input. This allows it to work a bit faster.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FILE_END]
|
||||
:end-before: [TARGET_ASM_FILE_END]
|
||||
|
||||
The default is false. You should not set it to true unless you have
|
||||
verified that your port does not generate any extra whitespace or
|
||||
comments that will cause GAS to issue errors in NO_APP mode.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_ASM_FILE_START_FILE_DIRECTIVE
|
||||
|
||||
.. hook-start:TARGET_ASM_FILE_START_FILE_DIRECTIVE
|
||||
|
||||
If this flag is true, ``output_file_directive`` will be called
|
||||
for the primary source file, immediately after printing
|
||||
``ASM_APP_OFF`` (if that is enabled). Most ELF assemblers expect
|
||||
this to be done. The default is false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_FILE_END (void)
|
||||
|
||||
.. hook-start:TARGET_ASM_FILE_END
|
||||
|
||||
Output to ``asm_out_file`` any text which the assembler expects
|
||||
to find at the end of a file. The default is to output nothing.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void file_end_indicate_exec_stack ()
|
||||
|
||||
@ -76,37 +45,20 @@ This describes the overall framework of an assembly file.
|
||||
need to do other things in that hook, have your hook function call
|
||||
this function.
|
||||
|
||||
.. function:: void TARGET_ASM_LTO_START (void)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_LTO_START]
|
||||
:end-before: [TARGET_ASM_LTO_START]
|
||||
|
||||
.. hook-start:TARGET_ASM_LTO_START
|
||||
|
||||
Output to ``asm_out_file`` any text which the assembler expects
|
||||
to find at the start of an LTO section. The default is to output
|
||||
nothing.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_LTO_END]
|
||||
:end-before: [TARGET_ASM_LTO_END]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_LTO_END (void)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_CODE_END]
|
||||
:end-before: [TARGET_ASM_CODE_END]
|
||||
|
||||
.. hook-start:TARGET_ASM_LTO_END
|
||||
|
||||
Output to ``asm_out_file`` any text which the assembler expects
|
||||
to find at the end of an LTO section. The default is to output
|
||||
nothing.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_CODE_END (void)
|
||||
|
||||
.. hook-start:TARGET_ASM_CODE_END
|
||||
|
||||
Output to ``asm_out_file`` any text which is needed before emitting
|
||||
unwind info and debug info at the end of a file. Some targets emit
|
||||
here PIC setup thunks that cannot be emitted at the end of file,
|
||||
because they couldn't have unwind info then. The default is to output
|
||||
nothing.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ASM_COMMENT_START
|
||||
|
||||
@ -138,28 +90,15 @@ This describes the overall framework of an assembly file.
|
||||
This macro need not be defined if the standard form of output
|
||||
for the file format in use is appropriate.
|
||||
|
||||
.. function:: void TARGET_ASM_OUTPUT_SOURCE_FILENAME (FILE *file, const char *name)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_OUTPUT_SOURCE_FILENAME]
|
||||
:end-before: [TARGET_ASM_OUTPUT_SOURCE_FILENAME]
|
||||
|
||||
.. hook-start:TARGET_ASM_OUTPUT_SOURCE_FILENAME
|
||||
|
||||
Output DWARF debugging information which indicates that filename
|
||||
:samp:`{name}` is the current source file to the stdio stream :samp:`{file}`.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_OUTPUT_IDENT]
|
||||
:end-before: [TARGET_ASM_OUTPUT_IDENT]
|
||||
|
||||
This target hook need not be defined if the standard form of output
|
||||
for the file format in use is appropriate.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_OUTPUT_IDENT (const char *name)
|
||||
|
||||
.. hook-start:TARGET_ASM_OUTPUT_IDENT
|
||||
|
||||
Output a string based on :samp:`{name}`, suitable for the :samp:`#ident`
|
||||
directive, or the equivalent directive or pragma in non-C-family languages.
|
||||
If this hook is not defined, nothing is output for the :samp:`#ident`
|
||||
directive.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: OUTPUT_QUOTED_STRING (stream, string)
|
||||
|
||||
@ -169,119 +108,51 @@ This describes the overall framework of an assembly file.
|
||||
the assembler source. So you can use it to canonicalize the format
|
||||
of the filename using this macro.
|
||||
|
||||
.. function:: void TARGET_ASM_NAMED_SECTION (const char *name, unsigned int flags, tree decl)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_NAMED_SECTION]
|
||||
:end-before: [TARGET_ASM_NAMED_SECTION]
|
||||
|
||||
.. hook-start:TARGET_ASM_NAMED_SECTION
|
||||
|
||||
Output assembly directives to switch to section :samp:`{name}`. The section
|
||||
should have attributes as specified by :samp:`{flags}`, which is a bit mask
|
||||
of the ``SECTION_*`` flags defined in :samp:`output.h`. If :samp:`{decl}`
|
||||
is non-NULL, it is the ``VAR_DECL`` or ``FUNCTION_DECL`` with which
|
||||
this section is associated.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_ELF_FLAGS_NUMERIC]
|
||||
:end-before: [TARGET_ASM_ELF_FLAGS_NUMERIC]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int flags, unsigned int *num)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FUNCTION_SECTION]
|
||||
:end-before: [TARGET_ASM_FUNCTION_SECTION]
|
||||
|
||||
.. hook-start:TARGET_ASM_ELF_FLAGS_NUMERIC
|
||||
|
||||
This hook can be used to encode ELF section flags for which no letter
|
||||
code has been defined in the assembler. It is called by
|
||||
``default_asm_named_section`` whenever the section flags need to be
|
||||
emitted in the assembler output. If the hook returns true, then the
|
||||
numerical value for ELF section flags should be calculated from
|
||||
:samp:`{flags}` and saved in :samp:`{*num}` ; the value is printed out instead of the
|
||||
normal sequence of letter codes. If the hook is not defined, or if it
|
||||
returns false, then :samp:`{num}` is ignored and the traditional letter sequence
|
||||
is emitted.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS]
|
||||
:end-before: [TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: section * TARGET_ASM_FUNCTION_SECTION (tree decl, enum node_frequency freq, bool startup, bool exit)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_HAVE_NAMED_SECTIONS]
|
||||
:end-before: [TARGET_HAVE_NAMED_SECTIONS]
|
||||
|
||||
.. hook-start:TARGET_ASM_FUNCTION_SECTION
|
||||
|
||||
Return preferred text (sub)section for function :samp:`{decl}`.
|
||||
Main purpose of this function is to separate cold, normal and hot
|
||||
functions. :samp:`{startup}` is true when function is known to be used only
|
||||
at startup (from static constructors or it is ``main()``).
|
||||
:samp:`{exit}` is true when function is known to be used only at exit
|
||||
(from static destructors).
|
||||
Return NULL if function should go to default text section.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS (FILE *file, tree decl, bool new_is_cold)
|
||||
|
||||
.. hook-start:TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
|
||||
|
||||
Used by the target to emit any assembler directives or additional
|
||||
labels needed when a function is partitioned between different
|
||||
sections. Output should be written to :samp:`{file}`. The function
|
||||
decl is available as :samp:`{decl}` and the new section is 'cold' if
|
||||
:samp:`{new_is_cold}` is ``true``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_HAVE_NAMED_SECTIONS
|
||||
|
||||
.. hook-start:TARGET_HAVE_NAMED_SECTIONS
|
||||
|
||||
.. hook-end
|
||||
|
||||
This flag is true if the target supports ``TARGET_ASM_NAMED_SECTION``.
|
||||
It must not be modified by command-line option processing.
|
||||
|
||||
.. _target_have_switchable_bss_sections:
|
||||
|
||||
.. c:var:: bool TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_HAVE_SWITCHABLE_BSS_SECTIONS]
|
||||
:end-before: [TARGET_HAVE_SWITCHABLE_BSS_SECTIONS]
|
||||
|
||||
.. hook-start:TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
|
||||
|
||||
This flag is true if we can create zeroed data by switching to a BSS
|
||||
section and then using ``ASM_OUTPUT_SKIP`` to allocate the space.
|
||||
This is true on most ELF targets.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SECTION_TYPE_FLAGS]
|
||||
:end-before: [TARGET_SECTION_TYPE_FLAGS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: unsigned int TARGET_SECTION_TYPE_FLAGS (tree decl, const char *name, int reloc)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_RECORD_GCC_SWITCHES]
|
||||
:end-before: [TARGET_ASM_RECORD_GCC_SWITCHES]
|
||||
|
||||
.. hook-start:TARGET_SECTION_TYPE_FLAGS
|
||||
|
||||
Choose a set of section attributes for use by ``TARGET_ASM_NAMED_SECTION``
|
||||
based on a variable or function decl, a section name, and whether or not the
|
||||
declaration's initializer may contain runtime relocations. :samp:`{decl}` may be
|
||||
null, in which case read-write data should be assumed.
|
||||
|
||||
The default version of this function handles choosing code vs data,
|
||||
read-only vs read-write data, and ``flag_pic``. You should only
|
||||
need to override this if your target has special flags that might be
|
||||
set via ``__attribute__``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_RECORD_GCC_SWITCHES (const char *)
|
||||
|
||||
.. hook-start:TARGET_ASM_RECORD_GCC_SWITCHES
|
||||
|
||||
Provides the target with the ability to record the gcc command line
|
||||
switches provided as argument.
|
||||
|
||||
By default this hook is set to NULL, but an example implementation is
|
||||
provided for ELF based targets. Called :samp:`{elf_record_gcc_switches}`,
|
||||
it records the switches as ASCII text inside a new, string mergeable
|
||||
section in the assembler output file. The name of the new section is
|
||||
provided by the ``TARGET_ASM_RECORD_GCC_SWITCHES_SECTION`` target
|
||||
hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_ASM_RECORD_GCC_SWITCHES_SECTION
|
||||
|
||||
.. hook-start:TARGET_ASM_RECORD_GCC_SWITCHES_SECTION
|
||||
|
||||
This is the name of the section that will be created by the example
|
||||
ELF implementation of the ``TARGET_ASM_RECORD_GCC_SWITCHES`` target
|
||||
hook.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_RECORD_GCC_SWITCHES_SECTION]
|
||||
:end-before: [TARGET_ASM_RECORD_GCC_SWITCHES_SECTION]
|
||||
|
@ -35,30 +35,10 @@ on the target machine.
|
||||
These macros are obsolete, new ports should use the target hook
|
||||
``TARGET_REGISTER_MOVE_COST`` instead.
|
||||
|
||||
.. function:: int TARGET_REGISTER_MOVE_COST (machine_mode mode, reg_class_t from, reg_class_t to)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_REGISTER_MOVE_COST]
|
||||
:end-before: [TARGET_REGISTER_MOVE_COST]
|
||||
|
||||
.. hook-start:TARGET_REGISTER_MOVE_COST
|
||||
|
||||
This target hook should return the cost of moving data of mode :samp:`{mode}`
|
||||
from a register in class :samp:`{from}` to one in class :samp:`{to}`. The classes
|
||||
are expressed using the enumeration values such as ``GENERAL_REGS``.
|
||||
A value of 2 is the default; other values are interpreted relative to
|
||||
that.
|
||||
|
||||
It is not required that the cost always equal 2 when :samp:`{from}` is the
|
||||
same as :samp:`{to}` ; on some machines it is expensive to move between
|
||||
registers if they are not general registers.
|
||||
|
||||
If reload sees an insn consisting of a single ``set`` between two
|
||||
hard registers, and if ``TARGET_REGISTER_MOVE_COST`` applied to their
|
||||
classes returns a value of 2, reload does not check to ensure that the
|
||||
constraints of the insn are met. Setting a cost of other than 2 will
|
||||
allow reload to verify that the constraints are met. You should do this
|
||||
if the :samp:`mov{m}` pattern's constraints do not allow such copying.
|
||||
|
||||
The default version of this function returns 2.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: MEMORY_MOVE_COST (mode, class, in)
|
||||
|
||||
@ -87,33 +67,10 @@ on the target machine.
|
||||
These macros are obsolete, new ports should use the target hook
|
||||
``TARGET_MEMORY_MOVE_COST`` instead.
|
||||
|
||||
.. function:: int TARGET_MEMORY_MOVE_COST (machine_mode mode, reg_class_t rclass, bool in)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MEMORY_MOVE_COST]
|
||||
:end-before: [TARGET_MEMORY_MOVE_COST]
|
||||
|
||||
.. hook-start:TARGET_MEMORY_MOVE_COST
|
||||
|
||||
This target hook should return the cost of moving data of mode :samp:`{mode}`
|
||||
between a register of class :samp:`{rclass}` and memory; :samp:`{in}` is ``false``
|
||||
if the value is to be written to memory, ``true`` if it is to be read in.
|
||||
This cost is relative to those in ``TARGET_REGISTER_MOVE_COST``.
|
||||
If moving between registers and memory is more expensive than between two
|
||||
registers, you should add this target hook to express the relative cost.
|
||||
|
||||
If you do not add this target hook, GCC uses a default cost of 4 plus
|
||||
the cost of copying via a secondary reload register, if one is
|
||||
needed. If your machine requires a secondary reload register to copy
|
||||
between memory and a register of :samp:`{rclass}` but the reload mechanism is
|
||||
more complex than copying via an intermediate, use this target hook to
|
||||
reflect the actual cost of the move.
|
||||
|
||||
GCC defines the function ``memory_move_secondary_cost`` if
|
||||
secondary reloads are needed. It computes the costs due to copying via
|
||||
a secondary register. If your machine copies from memory using a
|
||||
secondary register in the conventional way but the default base value of
|
||||
4 is not correct for your machine, use this target hook to add some other
|
||||
value to the result of that function. The arguments to that function
|
||||
are the same as to this target hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: BRANCH_COST (speed_p, predictable_p)
|
||||
|
||||
@ -144,26 +101,10 @@ ordinarily expect.
|
||||
may eliminate subsequent memory access if subsequent accesses occur to
|
||||
other fields in the same word of the structure, but to different bytes.
|
||||
|
||||
.. function:: bool TARGET_SLOW_UNALIGNED_ACCESS (machine_mode mode, unsigned int align)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SLOW_UNALIGNED_ACCESS]
|
||||
:end-before: [TARGET_SLOW_UNALIGNED_ACCESS]
|
||||
|
||||
.. hook-start:TARGET_SLOW_UNALIGNED_ACCESS
|
||||
|
||||
This hook returns true if memory accesses described by the
|
||||
:samp:`{mode}` and :samp:`{alignment}` parameters have a cost many times greater
|
||||
than aligned accesses, for example if they are emulated in a trap handler.
|
||||
This hook is invoked only for unaligned accesses, i.e. when
|
||||
``alignment < GET_MODE_ALIGNMENT (mode)``.
|
||||
|
||||
When this hook returns true, the compiler will act as if
|
||||
``STRICT_ALIGNMENT`` were true when generating code for block
|
||||
moves. This can cause significantly more instructions to be produced.
|
||||
Therefore, do not make this hook return true if unaligned accesses only
|
||||
add a cycle or two to the time for a memory access.
|
||||
|
||||
The hook must return true whenever ``STRICT_ALIGNMENT`` is true.
|
||||
The default implementation returns ``STRICT_ALIGNMENT``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: MOVE_RATIO (speed)
|
||||
|
||||
@ -181,69 +122,20 @@ ordinarily expect.
|
||||
|
||||
If you don't define this, a reasonable default is used.
|
||||
|
||||
.. function:: bool TARGET_USE_BY_PIECES_INFRASTRUCTURE_P (unsigned HOST_WIDE_INT size, unsigned int alignment, enum by_pieces_operation op, bool speed_p)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_USE_BY_PIECES_INFRASTRUCTURE_P]
|
||||
:end-before: [TARGET_USE_BY_PIECES_INFRASTRUCTURE_P]
|
||||
|
||||
.. hook-start:TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
|
||||
|
||||
GCC will attempt several strategies when asked to copy between
|
||||
two areas of memory, or to set, clear or store to memory, for example
|
||||
when copying a ``struct``. The ``by_pieces`` infrastructure
|
||||
implements such memory operations as a sequence of load, store or move
|
||||
insns. Alternate strategies are to expand the
|
||||
``cpymem`` or ``setmem`` optabs, to emit a library call, or to emit
|
||||
unit-by-unit, loop-based operations.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OVERLAP_OP_BY_PIECES_P]
|
||||
:end-before: [TARGET_OVERLAP_OP_BY_PIECES_P]
|
||||
|
||||
This target hook should return true if, for a memory operation with a
|
||||
given :samp:`{size}` and :samp:`{alignment}`, using the ``by_pieces``
|
||||
infrastructure is expected to result in better code generation.
|
||||
Both :samp:`{size}` and :samp:`{alignment}` are measured in terms of storage
|
||||
units.
|
||||
|
||||
The parameter :samp:`{op}` is one of: ``CLEAR_BY_PIECES``,
|
||||
``MOVE_BY_PIECES``, ``SET_BY_PIECES``, ``STORE_BY_PIECES`` or
|
||||
``COMPARE_BY_PIECES``. These describe the type of memory operation
|
||||
under consideration.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_COMPARE_BY_PIECES_BRANCH_RATIO]
|
||||
:end-before: [TARGET_COMPARE_BY_PIECES_BRANCH_RATIO]
|
||||
|
||||
The parameter :samp:`{speed_p}` is true if the code is currently being
|
||||
optimized for speed rather than size.
|
||||
|
||||
Returning true for higher values of :samp:`{size}` can improve code generation
|
||||
for speed if the target does not provide an implementation of the
|
||||
``cpymem`` or ``setmem`` standard names, if the ``cpymem`` or
|
||||
``setmem`` implementation would be more expensive than a sequence of
|
||||
insns, or if the overhead of a library call would dominate that of
|
||||
the body of the memory operation.
|
||||
|
||||
Returning true for higher values of ``size`` may also cause an increase
|
||||
in code size, for example where the number of insns emitted to perform a
|
||||
move would be greater than that of a library call.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_OVERLAP_OP_BY_PIECES_P (void)
|
||||
|
||||
.. hook-start:TARGET_OVERLAP_OP_BY_PIECES_P
|
||||
|
||||
This target hook should return true if when the ``by_pieces``
|
||||
infrastructure is used, an offset adjusted unaligned memory operation
|
||||
in the smallest integer mode for the last piece operation of a memory
|
||||
region can be generated to avoid doing more than one smaller operations.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_COMPARE_BY_PIECES_BRANCH_RATIO (machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_COMPARE_BY_PIECES_BRANCH_RATIO
|
||||
|
||||
When expanding a block comparison in MODE, gcc can try to reduce the
|
||||
number of branches at the expense of more memory operations. This hook
|
||||
allows the target to override the default choice. It should return the
|
||||
factor by which branches should be reduced over the plain expansion with
|
||||
one comparison per :samp:`{mode}` -sized piece. A port can also prevent a
|
||||
particular mode from being used for block comparisons by returning a
|
||||
negative number from this hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: MOVE_MAX_PIECES
|
||||
|
||||
@ -346,183 +238,46 @@ ordinarily expect.
|
||||
:samp:`fold_range_test ()` is optimal. This macro defaults to true if
|
||||
``BRANCH_COST`` is greater than or equal to the value 2.
|
||||
|
||||
.. function:: bool TARGET_OPTAB_SUPPORTED_P (int op, machine_mode mode1, machine_mode mode2, optimization_type opt_type)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTAB_SUPPORTED_P]
|
||||
:end-before: [TARGET_OPTAB_SUPPORTED_P]
|
||||
|
||||
.. hook-start:TARGET_OPTAB_SUPPORTED_P
|
||||
|
||||
Return true if the optimizers should use optab :samp:`{op}` with
|
||||
modes :samp:`{mode1}` and :samp:`{mode2}` for optimization type :samp:`{opt_type}`.
|
||||
The optab is known to have an associated :samp:`.md` instruction
|
||||
whose C condition is true. :samp:`{mode2}` is only meaningful for conversion
|
||||
optabs; for direct optabs it is a copy of :samp:`{mode1}`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_RTX_COSTS]
|
||||
:end-before: [TARGET_RTX_COSTS]
|
||||
|
||||
For example, when called with :samp:`{op}` equal to ``rint_optab`` and
|
||||
:samp:`{mode1}` equal to ``DFmode``, the hook should say whether the
|
||||
optimizers should use optab ``rintdf2``.
|
||||
|
||||
The default hook returns true for all inputs.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDRESS_COST]
|
||||
:end-before: [TARGET_ADDRESS_COST]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_RTX_COSTS (rtx x, machine_mode mode, int outer_code, int opno, int *total, bool speed)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_INSN_COST]
|
||||
:end-before: [TARGET_INSN_COST]
|
||||
|
||||
.. hook-start:TARGET_RTX_COSTS
|
||||
|
||||
This target hook describes the relative costs of RTL expressions.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MAX_NOCE_IFCVT_SEQ_COST]
|
||||
:end-before: [TARGET_MAX_NOCE_IFCVT_SEQ_COST]
|
||||
|
||||
The cost may depend on the precise form of the expression, which is
|
||||
available for examination in :samp:`{x}`, and the fact that :samp:`{x}` appears
|
||||
as operand :samp:`{opno}` of an expression with rtx code :samp:`{outer_code}`.
|
||||
That is, the hook can assume that there is some rtx :samp:`{y}` such
|
||||
that :samp:`GET_CODE ({y}) == {outer_code}` and such that
|
||||
either (a) :samp:`XEXP ({y}, {opno}) == {x}` or
|
||||
(b) :samp:`XVEC ({y}, {opno})` contains :samp:`{x}`.
|
||||
|
||||
:samp:`{mode}` is :samp:`{x}` 's machine mode, or for cases like ``const_int`` that
|
||||
do not have a mode, the mode in which :samp:`{x}` is used.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_NOCE_CONVERSION_PROFITABLE_P]
|
||||
:end-before: [TARGET_NOCE_CONVERSION_PROFITABLE_P]
|
||||
|
||||
In implementing this hook, you can use the construct
|
||||
``COSTS_N_INSNS (n)`` to specify a cost equal to :samp:`{n}` fast
|
||||
instructions.
|
||||
|
||||
On entry to the hook, ``*total`` contains a default estimate
|
||||
for the cost of the expression. The hook should modify this value as
|
||||
necessary. Traditionally, the default costs are ``COSTS_N_INSNS (5)``
|
||||
for multiplications, ``COSTS_N_INSNS (7)`` for division and modulus
|
||||
operations, and ``COSTS_N_INSNS (1)`` for all other operations.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_NEW_ADDRESS_PROFITABLE_P]
|
||||
:end-before: [TARGET_NEW_ADDRESS_PROFITABLE_P]
|
||||
|
||||
When optimizing for code size, i.e. when ``speed`` is
|
||||
false, this target hook should be used to estimate the relative
|
||||
size cost of an expression, again relative to ``COSTS_N_INSNS``.
|
||||
|
||||
The hook returns true when all subexpressions of :samp:`{x}` have been
|
||||
processed, and false when ``rtx_cost`` should recurse.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P]
|
||||
:end-before: [TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_ADDRESS_COST (rtx address, machine_mode mode, addr_space_t as, bool speed)
|
||||
|
||||
.. hook-start:TARGET_ADDRESS_COST
|
||||
|
||||
This hook computes the cost of an addressing mode that contains
|
||||
:samp:`{address}`. If not defined, the cost is computed from
|
||||
the :samp:`{address}` expression and the ``TARGET_RTX_COST`` hook.
|
||||
|
||||
For most CISC machines, the default cost is a good approximation of the
|
||||
true cost of the addressing mode. However, on RISC machines, all
|
||||
instructions normally have the same length and execution time. Hence
|
||||
all addresses will have equal costs.
|
||||
|
||||
In cases where more than one form of an address is known, the form with
|
||||
the lowest cost will be used. If multiple forms have the same, lowest,
|
||||
cost, the one that is the most complex will be used.
|
||||
|
||||
For example, suppose an address that is equal to the sum of a register
|
||||
and a constant is used twice in the same basic block. When this macro
|
||||
is not defined, the address will be computed in a register and memory
|
||||
references will be indirect through that register. On machines where
|
||||
the cost of the addressing mode containing the sum is no higher than
|
||||
that of a simple indirect reference, this will produce an additional
|
||||
instruction and possibly require an additional register. Proper
|
||||
specification of this macro eliminates this overhead for such machines.
|
||||
|
||||
This hook is never called with an invalid address.
|
||||
|
||||
On machines where an address involving more than one register is as
|
||||
cheap as an address computation involving only one register, defining
|
||||
``TARGET_ADDRESS_COST`` to reflect this can cause two registers to
|
||||
be live over a region of code where only one would have been if
|
||||
``TARGET_ADDRESS_COST`` were not defined in that manner. This effect
|
||||
should be considered in the definition of this macro. Equivalent costs
|
||||
should probably only be given to addresses with different numbers of
|
||||
registers on machines with lots of registers.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_INSN_COST (rtx_insn *insn, bool speed)
|
||||
|
||||
.. hook-start:TARGET_INSN_COST
|
||||
|
||||
This target hook describes the relative costs of RTL instructions.
|
||||
|
||||
In implementing this hook, you can use the construct
|
||||
``COSTS_N_INSNS (n)`` to specify a cost equal to :samp:`{n}` fast
|
||||
instructions.
|
||||
|
||||
When optimizing for code size, i.e. when ``speed`` is
|
||||
false, this target hook should be used to estimate the relative
|
||||
size cost of an expression, again relative to ``COSTS_N_INSNS``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: unsigned int TARGET_MAX_NOCE_IFCVT_SEQ_COST (edge e)
|
||||
|
||||
.. hook-start:TARGET_MAX_NOCE_IFCVT_SEQ_COST
|
||||
|
||||
This hook returns a value in the same units as ``TARGET_RTX_COSTS``,
|
||||
giving the maximum acceptable cost for a sequence generated by the RTL
|
||||
if-conversion pass when conditional execution is not available.
|
||||
The RTL if-conversion pass attempts to convert conditional operations
|
||||
that would require a branch to a series of unconditional operations and
|
||||
``movmodecc`` insns. This hook returns the maximum cost of the
|
||||
unconditional instructions and the ``movmodecc`` insns.
|
||||
RTL if-conversion is cancelled if the cost of the converted sequence
|
||||
is greater than the value returned by this hook.
|
||||
|
||||
``e`` is the edge between the basic block containing the conditional
|
||||
branch to the basic block which would be executed if the condition
|
||||
were true.
|
||||
|
||||
The default implementation of this hook uses the
|
||||
``max-rtl-if-conversion-[un]predictable`` parameters if they are set,
|
||||
and uses a multiple of ``BRANCH_COST`` otherwise.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_NOCE_CONVERSION_PROFITABLE_P (rtx_insn *seq, struct noce_if_info *if_info)
|
||||
|
||||
.. hook-start:TARGET_NOCE_CONVERSION_PROFITABLE_P
|
||||
|
||||
This hook returns true if the instruction sequence ``seq`` is a good
|
||||
candidate as a replacement for the if-convertible sequence described in
|
||||
``if_info``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_NEW_ADDRESS_PROFITABLE_P (rtx memref, rtx_insn * insn, rtx new_addr)
|
||||
|
||||
.. hook-start:TARGET_NEW_ADDRESS_PROFITABLE_P
|
||||
|
||||
Return ``true`` if it is profitable to replace the address in
|
||||
:samp:`{memref}` with :samp:`{new_addr}`. This allows targets to prevent the
|
||||
scheduler from undoing address optimizations. The instruction containing the
|
||||
memref is :samp:`{insn}`. The default implementation returns ``true``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P (void)
|
||||
|
||||
.. hook-start:TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
|
||||
|
||||
This predicate controls the use of the eager delay slot filler to disallow
|
||||
speculatively executed instructions being placed in delay slots. Targets
|
||||
such as certain MIPS architectures possess both branches with and without
|
||||
delay slots. As the eager delay slot filler can decrease performance,
|
||||
disabling it is beneficial when ordinary branches are available. Use of
|
||||
delay slot branches filled using the basic filler is often still desirable
|
||||
as the delay slot can hide a pipeline bubble.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: HOST_WIDE_INT TARGET_ESTIMATED_POLY_VALUE (poly_int64 val, poly_value_estimate_kind kind)
|
||||
|
||||
.. hook-start:TARGET_ESTIMATED_POLY_VALUE
|
||||
|
||||
Return an estimate of the runtime value of :samp:`{val}`, for use in
|
||||
things like cost calculations or profiling frequencies. :samp:`{kind}` is used
|
||||
to ask for the minimum, maximum, and likely estimates of the value through
|
||||
the ``POLY_VALUE_MIN``, ``POLY_VALUE_MAX`` and
|
||||
``POLY_VALUE_LIKELY`` values. The default
|
||||
implementation returns the lowest possible value of :samp:`{val}`.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ESTIMATED_POLY_VALUE]
|
||||
:end-before: [TARGET_ESTIMATED_POLY_VALUE]
|
||||
|
@ -191,65 +191,25 @@ if the target does not provide them.
|
||||
|
||||
This macro is irrelevant if there is no separate readonly data section.
|
||||
|
||||
.. function:: void TARGET_ASM_INIT_SECTIONS (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_INIT_SECTIONS]
|
||||
:end-before: [TARGET_ASM_INIT_SECTIONS]
|
||||
|
||||
.. hook-start:TARGET_ASM_INIT_SECTIONS
|
||||
|
||||
Define this hook if you need to do something special to set up the
|
||||
:samp:`varasm.cc` sections, or if your target has some special sections
|
||||
of its own that you need to create.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_RELOC_RW_MASK]
|
||||
:end-before: [TARGET_ASM_RELOC_RW_MASK]
|
||||
|
||||
GCC calls this hook after processing the command line, but before writing
|
||||
any assembly code, and before calling any of the section-returning hooks
|
||||
described below.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC]
|
||||
:end-before: [TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC]
|
||||
|
||||
.. function:: int TARGET_ASM_RELOC_RW_MASK (void)
|
||||
|
||||
.. hook-start:TARGET_ASM_RELOC_RW_MASK
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_SELECT_SECTION]
|
||||
:end-before: [TARGET_ASM_SELECT_SECTION]
|
||||
|
||||
Return a mask describing how relocations should be treated when
|
||||
selecting sections. Bit 1 should be set if global relocations
|
||||
should be placed in a read-write section; bit 0 should be set if
|
||||
local relocations should be placed in a read-write section.
|
||||
|
||||
The default version of this function returns 3 when :option:`-fpic`
|
||||
is in effect, and 0 otherwise. The hook is typically redefined
|
||||
when the target cannot support (some kinds of) dynamic relocations
|
||||
in read-only sections even in executables.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC (void)
|
||||
|
||||
.. hook-start:TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC
|
||||
|
||||
Return true to generate ADDR_DIF_VEC table
|
||||
or false to generate ADDR_VEC table for jumps in case of -fPIC.
|
||||
|
||||
The default version of this function returns true if flag_pic
|
||||
equals true and false otherwise
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: section * TARGET_ASM_SELECT_SECTION (tree exp, int reloc, unsigned HOST_WIDE_INT align)
|
||||
|
||||
.. hook-start:TARGET_ASM_SELECT_SECTION
|
||||
|
||||
Return the section into which :samp:`{exp}` should be placed. You can
|
||||
assume that :samp:`{exp}` is either a ``VAR_DECL`` node or a constant of
|
||||
some sort. :samp:`{reloc}` indicates whether the initial value of :samp:`{exp}`
|
||||
requires link-time relocations. Bit 0 is set when variable contains
|
||||
local relocations only, while bit 1 is set for global relocations.
|
||||
:samp:`{align}` is the constant alignment in bits.
|
||||
|
||||
The default version of this function takes care of putting read-only
|
||||
variables in ``readonly_data_section``.
|
||||
|
||||
See also :samp:`{USE_SELECT_SECTION_FOR_FUNCTIONS}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: USE_SELECT_SECTION_FOR_FUNCTIONS
|
||||
|
||||
@ -260,186 +220,66 @@ if the target does not provide them.
|
||||
function has been determined to be likely to be called, and nonzero if
|
||||
it is unlikely to be called.
|
||||
|
||||
.. function:: void TARGET_ASM_UNIQUE_SECTION (tree decl, int reloc)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_UNIQUE_SECTION]
|
||||
:end-before: [TARGET_ASM_UNIQUE_SECTION]
|
||||
|
||||
.. hook-start:TARGET_ASM_UNIQUE_SECTION
|
||||
|
||||
Build up a unique section name, expressed as a ``STRING_CST`` node,
|
||||
and assign it to :samp:`DECL_SECTION_NAME ({decl})`.
|
||||
As with ``TARGET_ASM_SELECT_SECTION``, :samp:`{reloc}` indicates whether
|
||||
the initial value of :samp:`{exp}` requires link-time relocations.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_FUNCTION_RODATA_SECTION]
|
||||
:end-before: [TARGET_ASM_FUNCTION_RODATA_SECTION]
|
||||
|
||||
The default version of this function appends the symbol name to the
|
||||
ELF section name that would normally be used for the symbol. For
|
||||
example, the function ``foo`` would be placed in ``.text.foo``.
|
||||
Whatever the actual target object format, this is often good enough.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_MERGEABLE_RODATA_PREFIX]
|
||||
:end-before: [TARGET_ASM_MERGEABLE_RODATA_PREFIX]
|
||||
|
||||
.. function:: section * TARGET_ASM_FUNCTION_RODATA_SECTION (tree decl, bool relocatable)
|
||||
|
||||
.. hook-start:TARGET_ASM_FUNCTION_RODATA_SECTION
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_TM_CLONE_TABLE_SECTION]
|
||||
:end-before: [TARGET_ASM_TM_CLONE_TABLE_SECTION]
|
||||
|
||||
Return the readonly data or reloc readonly data section associated with
|
||||
:samp:`DECL_SECTION_NAME ({decl})`. :samp:`{relocatable}` selects the latter
|
||||
over the former.
|
||||
The default version of this function selects ``.gnu.linkonce.r.name`` if
|
||||
the function's section is ``.gnu.linkonce.t.name``, ``.rodata.name``
|
||||
or ``.data.rel.ro.name`` if function is in ``.text.name``, and
|
||||
the normal readonly-data or reloc readonly data section otherwise.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_SELECT_RTX_SECTION]
|
||||
:end-before: [TARGET_ASM_SELECT_RTX_SECTION]
|
||||
|
||||
.. c:var:: const char * TARGET_ASM_MERGEABLE_RODATA_PREFIX
|
||||
|
||||
.. hook-start:TARGET_ASM_MERGEABLE_RODATA_PREFIX
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MANGLE_DECL_ASSEMBLER_NAME]
|
||||
:end-before: [TARGET_MANGLE_DECL_ASSEMBLER_NAME]
|
||||
|
||||
Usually, the compiler uses the prefix ``".rodata"`` to construct
|
||||
section names for mergeable constant data. Define this macro to override
|
||||
the string if a different section name should be used.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ENCODE_SECTION_INFO]
|
||||
:end-before: [TARGET_ENCODE_SECTION_INFO]
|
||||
|
||||
.. function:: section * TARGET_ASM_TM_CLONE_TABLE_SECTION (void)
|
||||
|
||||
.. hook-start:TARGET_ASM_TM_CLONE_TABLE_SECTION
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_STRIP_NAME_ENCODING]
|
||||
:end-before: [TARGET_STRIP_NAME_ENCODING]
|
||||
|
||||
Return the section that should be used for transactional memory clone
|
||||
tables.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_IN_SMALL_DATA_P]
|
||||
:end-before: [TARGET_IN_SMALL_DATA_P]
|
||||
|
||||
.. function:: section * TARGET_ASM_SELECT_RTX_SECTION (machine_mode mode, rtx x, unsigned HOST_WIDE_INT align)
|
||||
|
||||
.. hook-start:TARGET_ASM_SELECT_RTX_SECTION
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HAVE_SRODATA_SECTION]
|
||||
:end-before: [TARGET_HAVE_SRODATA_SECTION]
|
||||
|
||||
Return the section into which a constant :samp:`{x}`, of mode :samp:`{mode}`,
|
||||
should be placed. You can assume that :samp:`{x}` is some kind of
|
||||
constant in RTL. The argument :samp:`{mode}` is redundant except in the
|
||||
case of a ``const_int`` rtx. :samp:`{align}` is the constant alignment
|
||||
in bits.
|
||||
|
||||
The default version of this function takes care of putting symbolic
|
||||
constants in ``flag_pic`` mode in ``data_section`` and everything
|
||||
else in ``readonly_data_section``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PROFILE_BEFORE_PROLOGUE]
|
||||
:end-before: [TARGET_PROFILE_BEFORE_PROLOGUE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_MANGLE_DECL_ASSEMBLER_NAME (tree decl, tree id)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_BINDS_LOCAL_P]
|
||||
:end-before: [TARGET_BINDS_LOCAL_P]
|
||||
|
||||
.. hook-start:TARGET_MANGLE_DECL_ASSEMBLER_NAME
|
||||
|
||||
Define this hook if you need to postprocess the assembler name generated
|
||||
by target-independent code. The :samp:`{id}` provided to this hook will be
|
||||
the computed name (e.g., the macro ``DECL_NAME`` of the :samp:`{decl}` in C,
|
||||
or the mangled name of the :samp:`{decl}` in C++). The return value of the
|
||||
hook is an ``IDENTIFIER_NODE`` for the appropriate mangled name on
|
||||
your target system. The default implementation of this hook just
|
||||
returns the :samp:`{id}` provided.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ENCODE_SECTION_INFO (tree decl, rtx rtl, int new_decl_p)
|
||||
|
||||
.. hook-start:TARGET_ENCODE_SECTION_INFO
|
||||
|
||||
Define this hook if references to a symbol or a constant must be
|
||||
treated differently depending on something about the variable or
|
||||
function named by the symbol (such as what section it is in).
|
||||
|
||||
The hook is executed immediately after rtl has been created for
|
||||
:samp:`{decl}`, which may be a variable or function declaration or
|
||||
an entry in the constant pool. In either case, :samp:`{rtl}` is the
|
||||
rtl in question. Do *not* use ``DECL_RTL (decl)``
|
||||
in this hook; that field may not have been initialized yet.
|
||||
|
||||
In the case of a constant, it is safe to assume that the rtl is
|
||||
a ``mem`` whose address is a ``symbol_ref``. Most decls
|
||||
will also have this form, but that is not guaranteed. Global
|
||||
register variables, for instance, will have a ``reg`` for their
|
||||
rtl. (Normally the right thing to do with such unusual rtl is
|
||||
leave it alone.)
|
||||
|
||||
The :samp:`{new_decl_p}` argument will be true if this is the first time
|
||||
that ``TARGET_ENCODE_SECTION_INFO`` has been invoked on this decl. It will
|
||||
be false for subsequent invocations, which will happen for duplicate
|
||||
declarations. Whether or not anything must be done for the duplicate
|
||||
declaration depends on whether the hook examines ``DECL_ATTRIBUTES``.
|
||||
:samp:`{new_decl_p}` is always true when the hook is called for a constant.
|
||||
|
||||
.. index:: SYMBOL_REF_FLAG, in TARGET_ENCODE_SECTION_INFO
|
||||
|
||||
The usual thing for this hook to do is to record flags in the
|
||||
``symbol_ref``, using ``SYMBOL_REF_FLAG`` or ``SYMBOL_REF_FLAGS``.
|
||||
Historically, the name string was modified if it was necessary to
|
||||
encode more than one bit of information, but this practice is now
|
||||
discouraged; use ``SYMBOL_REF_FLAGS``.
|
||||
|
||||
The default definition of this hook, ``default_encode_section_info``
|
||||
in :samp:`varasm.cc`, sets a number of commonly-useful bits in
|
||||
``SYMBOL_REF_FLAGS``. Check whether the default does what you need
|
||||
before overriding it.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: const char * TARGET_STRIP_NAME_ENCODING (const char *name)
|
||||
|
||||
.. hook-start:TARGET_STRIP_NAME_ENCODING
|
||||
|
||||
Decode :samp:`{name}` and return the real name part, sans
|
||||
the characters that ``TARGET_ENCODE_SECTION_INFO``
|
||||
may have added.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_IN_SMALL_DATA_P (const_tree exp)
|
||||
|
||||
.. hook-start:TARGET_IN_SMALL_DATA_P
|
||||
|
||||
Returns true if :samp:`{exp}` should be placed into a 'small data' section.
|
||||
The default version of this hook always returns false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_HAVE_SRODATA_SECTION
|
||||
|
||||
.. hook-start:TARGET_HAVE_SRODATA_SECTION
|
||||
|
||||
Contains the value true if the target places read-only
|
||||
'small data' into a separate section. The default value is false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_PROFILE_BEFORE_PROLOGUE (void)
|
||||
|
||||
.. hook-start:TARGET_PROFILE_BEFORE_PROLOGUE
|
||||
|
||||
It returns true if target wants profile code emitted before prologue.
|
||||
|
||||
The default version of this hook use the target macro
|
||||
``PROFILE_BEFORE_PROLOGUE``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_BINDS_LOCAL_P (const_tree exp)
|
||||
|
||||
.. hook-start:TARGET_BINDS_LOCAL_P
|
||||
|
||||
Returns true if :samp:`{exp}` names an object for which name resolution
|
||||
rules must resolve to the current 'module' (dynamic shared library
|
||||
or executable image).
|
||||
|
||||
The default version of this hook implements the name resolution rules
|
||||
for ELF, which has a looser model of global name binding than other
|
||||
currently supported object file formats.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_HAVE_TLS
|
||||
|
||||
.. hook-start:TARGET_HAVE_TLS
|
||||
|
||||
Contains the value true if the target supports thread-local storage.
|
||||
The default value is false.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HAVE_TLS]
|
||||
:end-before: [TARGET_HAVE_TLS]
|
||||
|
@ -22,104 +22,51 @@ object. To access the TLS object, a lookup function is provided
|
||||
which, when given the address of the control object, will return the
|
||||
address of the current thread's instance of the TLS object.
|
||||
|
||||
.. c:var:: const char * TARGET_EMUTLS_GET_ADDRESS
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_GET_ADDRESS]
|
||||
:end-before: [TARGET_EMUTLS_GET_ADDRESS]
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_GET_ADDRESS
|
||||
|
||||
Contains the name of the helper function that uses a TLS control
|
||||
object to locate a TLS instance. The default causes libgcc's
|
||||
emulated TLS helper function to be used.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_REGISTER_COMMON]
|
||||
:end-before: [TARGET_EMUTLS_REGISTER_COMMON]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_EMUTLS_REGISTER_COMMON
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_VAR_SECTION]
|
||||
:end-before: [TARGET_EMUTLS_VAR_SECTION]
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_REGISTER_COMMON
|
||||
|
||||
Contains the name of the helper function that should be used at
|
||||
program startup to register TLS objects that are implicitly
|
||||
initialized to zero. If this is ``NULL``, all TLS objects will
|
||||
have explicit initializers. The default causes libgcc's emulated TLS
|
||||
registration function to be used.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_TMPL_SECTION]
|
||||
:end-before: [TARGET_EMUTLS_TMPL_SECTION]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_EMUTLS_VAR_SECTION
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_VAR_PREFIX]
|
||||
:end-before: [TARGET_EMUTLS_VAR_PREFIX]
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_VAR_SECTION
|
||||
|
||||
Contains the name of the section in which TLS control variables should
|
||||
be placed. The default of ``NULL`` allows these to be placed in
|
||||
any section.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_TMPL_PREFIX]
|
||||
:end-before: [TARGET_EMUTLS_TMPL_PREFIX]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_EMUTLS_TMPL_SECTION
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_VAR_FIELDS]
|
||||
:end-before: [TARGET_EMUTLS_VAR_FIELDS]
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_TMPL_SECTION
|
||||
|
||||
Contains the name of the section in which TLS initializers should be
|
||||
placed. The default of ``NULL`` allows these to be placed in any
|
||||
section.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_VAR_INIT]
|
||||
:end-before: [TARGET_EMUTLS_VAR_INIT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_EMUTLS_VAR_PREFIX
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_VAR_ALIGN_FIXED]
|
||||
:end-before: [TARGET_EMUTLS_VAR_ALIGN_FIXED]
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_VAR_PREFIX
|
||||
|
||||
Contains the prefix to be prepended to TLS control variable names.
|
||||
The default of ``NULL`` uses a target-specific prefix.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: const char * TARGET_EMUTLS_TMPL_PREFIX
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_TMPL_PREFIX
|
||||
|
||||
Contains the prefix to be prepended to TLS initializer objects. The
|
||||
default of ``NULL`` uses a target-specific prefix.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_EMUTLS_VAR_FIELDS (tree type, tree *name)
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_VAR_FIELDS
|
||||
|
||||
Specifies a function that generates the FIELD_DECLs for a TLS control
|
||||
object type. :samp:`{type}` is the RECORD_TYPE the fields are for and
|
||||
:samp:`{name}` should be filled with the structure tag, if the default of
|
||||
``__emutls_object`` is unsuitable. The default creates a type suitable
|
||||
for libgcc's emulated TLS function.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: tree TARGET_EMUTLS_VAR_INIT (tree var, tree decl, tree tmpl_addr)
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_VAR_INIT
|
||||
|
||||
Specifies a function that generates the CONSTRUCTOR to initialize a
|
||||
TLS control object. :samp:`{var}` is the TLS control object, :samp:`{decl}`
|
||||
is the TLS object and :samp:`{tmpl_addr}` is the address of the
|
||||
initializer. The default initializes libgcc's emulated TLS control object.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_EMUTLS_VAR_ALIGN_FIXED
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_VAR_ALIGN_FIXED
|
||||
|
||||
Specifies whether the alignment of TLS control variable objects is
|
||||
fixed and should not be increased as some backends may do to optimize
|
||||
single objects. The default is false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_EMUTLS_DEBUG_FORM_TLS_ADDRESS
|
||||
|
||||
.. hook-start:TARGET_EMUTLS_DEBUG_FORM_TLS_ADDRESS
|
||||
|
||||
Specifies whether a DWARF ``DW_OP_form_tls_address`` location descriptor
|
||||
may be used to describe emulated TLS control objects.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMUTLS_DEBUG_FORM_TLS_ADDRESS]
|
||||
:end-before: [TARGET_EMUTLS_DEBUG_FORM_TLS_ADDRESS]
|
||||
|
@ -76,117 +76,31 @@ below.
|
||||
|
||||
These machine description macros help implement varargs:
|
||||
|
||||
.. function:: rtx TARGET_EXPAND_BUILTIN_SAVEREGS (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EXPAND_BUILTIN_SAVEREGS]
|
||||
:end-before: [TARGET_EXPAND_BUILTIN_SAVEREGS]
|
||||
|
||||
.. hook-start:TARGET_EXPAND_BUILTIN_SAVEREGS
|
||||
|
||||
If defined, this hook produces the machine-specific code for a call to
|
||||
``__builtin_saveregs``. This code will be moved to the very
|
||||
beginning of the function, before any parameter access are made. The
|
||||
return value of this function should be an RTX that contains the value
|
||||
to use as the return of ``__builtin_saveregs``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SETUP_INCOMING_VARARGS]
|
||||
:end-before: [TARGET_SETUP_INCOMING_VARARGS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SETUP_INCOMING_VARARGS (cumulative_args_t args_so_far, const function_arg_info &arg, int *pretend_args_size, int second_time)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_STRICT_ARGUMENT_NAMING]
|
||||
:end-before: [TARGET_STRICT_ARGUMENT_NAMING]
|
||||
|
||||
.. hook-start:TARGET_SETUP_INCOMING_VARARGS
|
||||
|
||||
This target hook offers an alternative to using
|
||||
``__builtin_saveregs`` and defining the hook
|
||||
``TARGET_EXPAND_BUILTIN_SAVEREGS``. Use it to store the anonymous
|
||||
register arguments into the stack so that all the arguments appear to
|
||||
have been passed consecutively on the stack. Once this is done, you can
|
||||
use the standard implementation of varargs that works for machines that
|
||||
pass all their arguments on the stack.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CALL_ARGS]
|
||||
:end-before: [TARGET_CALL_ARGS]
|
||||
|
||||
The argument :samp:`{args_so_far}` points to the ``CUMULATIVE_ARGS`` data
|
||||
structure, containing the values that are obtained after processing the
|
||||
named arguments. The argument :samp:`{arg}` describes the last of these named
|
||||
arguments. The argument :samp:`{arg}` should not be used if the function type
|
||||
satisfies ``TYPE_NO_NAMED_ARGS_STDARG_P``, since in that case there are
|
||||
no named arguments and all arguments are accessed with ``va_arg``.
|
||||
|
||||
The target hook should do two things: first, push onto the stack all the
|
||||
argument registers *not* used for the named arguments, and second,
|
||||
store the size of the data thus pushed into the ``int`` -valued
|
||||
variable pointed to by :samp:`{pretend_args_size}`. The value that you
|
||||
store here will serve as additional offset for setting up the stack
|
||||
frame.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_END_CALL_ARGS]
|
||||
:end-before: [TARGET_END_CALL_ARGS]
|
||||
|
||||
Because you must generate code to push the anonymous arguments at
|
||||
compile time without knowing their data types,
|
||||
``TARGET_SETUP_INCOMING_VARARGS`` is only useful on machines that
|
||||
have just a single category of argument register and use it uniformly
|
||||
for all data types.
|
||||
|
||||
If the argument :samp:`{second_time}` is nonzero, it means that the
|
||||
arguments of the function are being analyzed for the second time. This
|
||||
happens for an inline function, which is not actually compiled until the
|
||||
end of the source file. The hook ``TARGET_SETUP_INCOMING_VARARGS`` should
|
||||
not generate any instructions in this case.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_STRICT_ARGUMENT_NAMING (cumulative_args_t ca)
|
||||
|
||||
.. hook-start:TARGET_STRICT_ARGUMENT_NAMING
|
||||
|
||||
Define this hook to return ``true`` if the location where a function
|
||||
argument is passed depends on whether or not it is a named argument.
|
||||
|
||||
This hook controls how the :samp:`{named}` argument to ``TARGET_FUNCTION_ARG``
|
||||
is set for varargs and stdarg functions. If this hook returns
|
||||
``true``, the :samp:`{named}` argument is always true for named
|
||||
arguments, and false for unnamed arguments. If it returns ``false``,
|
||||
but ``TARGET_PRETEND_OUTGOING_VARARGS_NAMED`` returns ``true``,
|
||||
then all arguments are treated as named. Otherwise, all named arguments
|
||||
except the last are treated as named.
|
||||
|
||||
You need not define this hook if it always returns ``false``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_CALL_ARGS (rtx, tree)
|
||||
|
||||
.. hook-start:TARGET_CALL_ARGS
|
||||
|
||||
While generating RTL for a function call, this target hook is invoked once
|
||||
for each argument passed to the function, either a register returned by
|
||||
``TARGET_FUNCTION_ARG`` or a memory location. It is called just
|
||||
before the point where argument registers are stored. The type of the
|
||||
function to be called is also passed as the second argument; it is
|
||||
``NULL_TREE`` for libcalls. The ``TARGET_END_CALL_ARGS`` hook is
|
||||
invoked just after the code to copy the return reg has been emitted.
|
||||
This functionality can be used to perform special setup of call argument
|
||||
registers if a target needs it.
|
||||
For functions without arguments, the hook is called once with ``pc_rtx``
|
||||
passed instead of an argument register.
|
||||
Most ports do not need to implement anything for this hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_END_CALL_ARGS (void)
|
||||
|
||||
.. hook-start:TARGET_END_CALL_ARGS
|
||||
|
||||
This target hook is invoked while generating RTL for a function call,
|
||||
just after the point where the return reg is copied into a pseudo. It
|
||||
signals that all the call argument and return registers for the just
|
||||
emitted call are now no longer in use.
|
||||
Most ports do not need to implement anything for this hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED (cumulative_args_t ca)
|
||||
|
||||
.. hook-start:TARGET_PRETEND_OUTGOING_VARARGS_NAMED
|
||||
|
||||
If you need to conditionally change ABIs so that one works with
|
||||
``TARGET_SETUP_INCOMING_VARARGS``, but the other works like neither
|
||||
``TARGET_SETUP_INCOMING_VARARGS`` nor ``TARGET_STRICT_ARGUMENT_NAMING`` was
|
||||
defined, then define this hook to return ``true`` if
|
||||
``TARGET_SETUP_INCOMING_VARARGS`` is used, ``false`` otherwise.
|
||||
Otherwise, you should not define this hook.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PRETEND_OUTGOING_VARARGS_NAMED]
|
||||
:end-before: [TARGET_PRETEND_OUTGOING_VARARGS_NAMED]
|
||||
|
@ -23,32 +23,15 @@ Here is an explanation of implicit calls to library routines.
|
||||
|
||||
.. index:: set_optab_libfunc, init_one_libfunc
|
||||
|
||||
.. function:: void TARGET_INIT_LIBFUNCS (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_INIT_LIBFUNCS]
|
||||
:end-before: [TARGET_INIT_LIBFUNCS]
|
||||
|
||||
.. hook-start:TARGET_INIT_LIBFUNCS
|
||||
|
||||
This hook should declare additional library routines or rename
|
||||
existing ones, using the functions ``set_optab_libfunc`` and
|
||||
``init_one_libfunc`` defined in :samp:`optabs.cc`.
|
||||
``init_optabs`` calls this macro after initializing all the normal
|
||||
library routines.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LIBFUNC_GNU_PREFIX]
|
||||
:end-before: [TARGET_LIBFUNC_GNU_PREFIX]
|
||||
|
||||
The default is to do nothing. Most ports don't need to define this hook.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:var:: bool TARGET_LIBFUNC_GNU_PREFIX
|
||||
|
||||
.. hook-start:TARGET_LIBFUNC_GNU_PREFIX
|
||||
|
||||
If false (the default), internal library routines start with two
|
||||
underscores. If set to true, these routines start with ``__gnu_``
|
||||
instead. E.g., ``__muldi3`` changes to ``__gnu_muldi3``. This
|
||||
currently only affects functions defined in :samp:`libgcc2.c`. If this
|
||||
is set to true, the :samp:`tm.h` file must also
|
||||
``#define LIBGCC2_GNU_PREFIX``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
|
||||
|
||||
@ -104,26 +87,15 @@ Here is an explanation of implicit calls to library routines.
|
||||
``errno`` may not actually be a variable.) If you don't define this
|
||||
macro, a reasonable default is used.
|
||||
|
||||
.. function:: bool TARGET_LIBC_HAS_FUNCTION (enum function_class fn_class, tree type)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LIBC_HAS_FUNCTION]
|
||||
:end-before: [TARGET_LIBC_HAS_FUNCTION]
|
||||
|
||||
.. hook-start:TARGET_LIBC_HAS_FUNCTION
|
||||
|
||||
This hook determines whether a function from a class of functions
|
||||
:samp:`{fn_class}` is present in the target C library. If :samp:`{type}` is NULL,
|
||||
the caller asks for support for all standard (float, double, long double)
|
||||
types. If :samp:`{type}` is non-NULL, the caller asks for support for a
|
||||
specific type.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LIBC_HAS_FAST_FUNCTION]
|
||||
:end-before: [TARGET_LIBC_HAS_FAST_FUNCTION]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_LIBC_HAS_FAST_FUNCTION (int fcode)
|
||||
|
||||
.. hook-start:TARGET_LIBC_HAS_FAST_FUNCTION
|
||||
|
||||
This hook determines whether a function from a class of functions
|
||||
``(enum function_class)``:samp:`{fcode}` has a fast implementation.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: NEXT_OBJC_RUNTIME
|
||||
|
||||
|
@ -146,18 +146,10 @@ languages, rather than to fundamental aspects of storage layout.
|
||||
always override this default with the options :option:`-fsigned-char`
|
||||
and :option:`-funsigned-char`.
|
||||
|
||||
.. function:: bool TARGET_DEFAULT_SHORT_ENUMS (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DEFAULT_SHORT_ENUMS]
|
||||
:end-before: [TARGET_DEFAULT_SHORT_ENUMS]
|
||||
|
||||
.. hook-start:TARGET_DEFAULT_SHORT_ENUMS
|
||||
|
||||
This target hook should return true if the compiler should give an
|
||||
``enum`` type only as many bytes as it takes to represent the range
|
||||
of possible values of that type. It should return false if all
|
||||
``enum`` types should be allocated like ``int``.
|
||||
|
||||
The default is to return false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: SIZE_TYPE
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -47,75 +47,31 @@ The following macros control mode switching optimizations:
|
||||
represented as numbers 0 ... N - 1. N is used to specify that no mode
|
||||
switch is needed / supplied.
|
||||
|
||||
.. function:: void TARGET_MODE_EMIT (int entity, int mode, int prev_mode, HARD_REG_SET regs_live)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MODE_EMIT]
|
||||
:end-before: [TARGET_MODE_EMIT]
|
||||
|
||||
.. hook-start:TARGET_MODE_EMIT
|
||||
|
||||
Generate one or more insns to set :samp:`{entity}` to :samp:`{mode}`.
|
||||
:samp:`{hard_reg_live}` is the set of hard registers live at the point where
|
||||
the insn(s) are to be inserted. :samp:`{prev_moxde}` indicates the mode
|
||||
to switch from. Sets of a lower numbered entity will be emitted before
|
||||
sets of a higher numbered entity to a mode of the same or lower priority.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MODE_NEEDED]
|
||||
:end-before: [TARGET_MODE_NEEDED]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_MODE_NEEDED (int entity, rtx_insn *insn)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MODE_AFTER]
|
||||
:end-before: [TARGET_MODE_AFTER]
|
||||
|
||||
.. hook-start:TARGET_MODE_NEEDED
|
||||
|
||||
:samp:`{entity}` is an integer specifying a mode-switched entity.
|
||||
If ``OPTIMIZE_MODE_SWITCHING`` is defined, you must define this macro
|
||||
to return an integer value not larger than the corresponding element
|
||||
in ``NUM_MODES_FOR_MODE_SWITCHING``, to denote the mode that :samp:`{entity}`
|
||||
must be switched into prior to the execution of :samp:`{insn}`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MODE_ENTRY]
|
||||
:end-before: [TARGET_MODE_ENTRY]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_MODE_AFTER (int entity, int mode, rtx_insn *insn)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MODE_EXIT]
|
||||
:end-before: [TARGET_MODE_EXIT]
|
||||
|
||||
.. hook-start:TARGET_MODE_AFTER
|
||||
|
||||
:samp:`{entity}` is an integer specifying a mode-switched entity.
|
||||
If this macro is defined, it is evaluated for every :samp:`{insn}` during mode
|
||||
switching. It determines the mode that an insn results
|
||||
in (if different from the incoming mode).
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_MODE_ENTRY (int entity)
|
||||
|
||||
.. hook-start:TARGET_MODE_ENTRY
|
||||
|
||||
If this macro is defined, it is evaluated for every :samp:`{entity}` that
|
||||
needs mode switching. It should evaluate to an integer, which is a mode
|
||||
that :samp:`{entity}` is assumed to be switched to at function entry.
|
||||
If ``TARGET_MODE_ENTRY`` is defined then ``TARGET_MODE_EXIT``
|
||||
must be defined.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_MODE_EXIT (int entity)
|
||||
|
||||
.. hook-start:TARGET_MODE_EXIT
|
||||
|
||||
If this macro is defined, it is evaluated for every :samp:`{entity}` that
|
||||
needs mode switching. It should evaluate to an integer, which is a mode
|
||||
that :samp:`{entity}` is assumed to be switched to at function exit.
|
||||
If ``TARGET_MODE_EXIT`` is defined then ``TARGET_MODE_ENTRY``
|
||||
must be defined.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_MODE_PRIORITY (int entity, int n)
|
||||
|
||||
.. hook-start:TARGET_MODE_PRIORITY
|
||||
|
||||
This macro specifies the order in which modes for :samp:`{entity}`
|
||||
are processed. 0 is the highest priority,
|
||||
``NUM_MODES_FOR_MODE_SWITCHING[entity] - 1`` the lowest.
|
||||
The value of the macro should be an integer designating a mode
|
||||
for :samp:`{entity}`. For any fixed :samp:`{entity}`, ``mode_priority``
|
||||
(:samp:`{entity}`, :samp:`{n}`) shall be a bijection in 0 ...
|
||||
``num_modes_for_mode_switching[entity] - 1``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MODE_PRIORITY]
|
||||
:end-before: [TARGET_MODE_PRIORITY]
|
||||
|
@ -10,54 +10,21 @@
|
||||
Parameters for Precompiled Header Validity Checking
|
||||
***************************************************
|
||||
|
||||
.. function:: void * TARGET_GET_PCH_VALIDITY (size_t *sz)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GET_PCH_VALIDITY]
|
||||
:end-before: [TARGET_GET_PCH_VALIDITY]
|
||||
|
||||
.. hook-start:TARGET_GET_PCH_VALIDITY
|
||||
|
||||
This hook returns a pointer to the data needed by
|
||||
``TARGET_PCH_VALID_P`` and sets
|
||||
:samp:`*{sz}` to the size of the data in bytes.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PCH_VALID_P]
|
||||
:end-before: [TARGET_PCH_VALID_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: const char * TARGET_PCH_VALID_P (const void *data, size_t sz)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CHECK_PCH_TARGET_FLAGS]
|
||||
:end-before: [TARGET_CHECK_PCH_TARGET_FLAGS]
|
||||
|
||||
.. hook-start:TARGET_PCH_VALID_P
|
||||
|
||||
This hook checks whether the options used to create a PCH file are
|
||||
compatible with the current settings. It returns ``NULL``
|
||||
if so and a suitable error message if not. Error messages will
|
||||
be presented to the user and must be localized using :samp:`_({msg})`.
|
||||
|
||||
:samp:`{data}` is the data that was returned by ``TARGET_GET_PCH_VALIDITY``
|
||||
when the PCH file was created and :samp:`{sz}` is the size of that data in bytes.
|
||||
It's safe to assume that the data was created by the same version of the
|
||||
compiler, so no format checking is needed.
|
||||
|
||||
The default definition of ``default_pch_valid_p`` should be
|
||||
suitable for most targets.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: const char * TARGET_CHECK_PCH_TARGET_FLAGS (int pch_flags)
|
||||
|
||||
.. hook-start:TARGET_CHECK_PCH_TARGET_FLAGS
|
||||
|
||||
If this hook is nonnull, the default implementation of
|
||||
``TARGET_PCH_VALID_P`` will use it to check for compatible values
|
||||
of ``target_flags``. :samp:`{pch_flags}` specifies the value that
|
||||
``target_flags`` had when the PCH file was created. The return
|
||||
value is the same as for ``TARGET_PCH_VALID_P``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_PREPARE_PCH_SAVE (void)
|
||||
|
||||
.. hook-start:TARGET_PREPARE_PCH_SAVE
|
||||
|
||||
Called before writing out a PCH file. If the target has some
|
||||
garbage-collected data that needs to be in a particular state on PCH loads,
|
||||
it can use this hook to enforce that state. Very few targets need
|
||||
to do anything here.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PREPARE_PCH_SAVE]
|
||||
:end-before: [TARGET_PREPARE_PCH_SAVE]
|
||||
|
@ -221,60 +221,15 @@ in many of the tables described below.
|
||||
looking for one that is valid, and will reload one or both registers
|
||||
only if neither labeling works.
|
||||
|
||||
.. function:: reg_class_t TARGET_PREFERRED_RENAME_CLASS (reg_class_t rclass)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PREFERRED_RENAME_CLASS]
|
||||
:end-before: [TARGET_PREFERRED_RENAME_CLASS]
|
||||
|
||||
.. hook-start:TARGET_PREFERRED_RENAME_CLASS
|
||||
|
||||
A target hook that places additional preference on the register
|
||||
class to use when it is necessary to rename a register in class
|
||||
:samp:`{rclass}` to another class, or perhaps :samp:`{NO_REGS}`, if no
|
||||
preferred register class is found or hook ``preferred_rename_class``
|
||||
is not implemented.
|
||||
Sometimes returning a more restrictive class makes better code. For
|
||||
example, on ARM, thumb-2 instructions using ``LO_REGS`` may be
|
||||
smaller than instructions using ``GENERIC_REGS``. By returning
|
||||
``LO_REGS`` from ``preferred_rename_class``, code size can
|
||||
be reduced.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PREFERRED_RELOAD_CLASS]
|
||||
:end-before: [TARGET_PREFERRED_RELOAD_CLASS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: reg_class_t TARGET_PREFERRED_RELOAD_CLASS (rtx x, reg_class_t rclass)
|
||||
|
||||
.. hook-start:TARGET_PREFERRED_RELOAD_CLASS
|
||||
|
||||
A target hook that places additional restrictions on the register class
|
||||
to use when it is necessary to copy value :samp:`{x}` into a register in class
|
||||
:samp:`{rclass}`. The value is a register class; perhaps :samp:`{rclass}`, or perhaps
|
||||
another, smaller class.
|
||||
|
||||
The default version of this hook always returns value of ``rclass`` argument.
|
||||
|
||||
Sometimes returning a more restrictive class makes better code. For
|
||||
example, on the 68000, when :samp:`{x}` is an integer constant that is in range
|
||||
for a :samp:`moveq` instruction, the value of this macro is always
|
||||
``DATA_REGS`` as long as :samp:`{rclass}` includes the data registers.
|
||||
Requiring a data register guarantees that a :samp:`moveq` will be used.
|
||||
|
||||
One case where ``TARGET_PREFERRED_RELOAD_CLASS`` must not return
|
||||
:samp:`{rclass}` is if :samp:`{x}` is a legitimate constant which cannot be
|
||||
loaded into some register class. By returning ``NO_REGS`` you can
|
||||
force :samp:`{x}` into a memory location. For example, rs6000 can load
|
||||
immediate values into general-purpose registers, but does not have an
|
||||
instruction for loading an immediate value into a floating-point
|
||||
register, so ``TARGET_PREFERRED_RELOAD_CLASS`` returns ``NO_REGS`` when
|
||||
:samp:`{x}` is a floating-point constant. If the constant can't be loaded
|
||||
into any kind of register, code generation will be better if
|
||||
``TARGET_LEGITIMATE_CONSTANT_P`` makes the constant illegitimate instead
|
||||
of using ``TARGET_PREFERRED_RELOAD_CLASS``.
|
||||
|
||||
If an insn has pseudos in it after register allocation, reload will go
|
||||
through the alternatives and call repeatedly ``TARGET_PREFERRED_RELOAD_CLASS``
|
||||
to find the best one. Returning ``NO_REGS``, in this case, makes
|
||||
reload add a ``!`` in front of the constraint: the x86 back-end uses
|
||||
this feature to discourage usage of 387 registers when math is done in
|
||||
the SSE registers (and vice versa).
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: PREFERRED_RELOAD_CLASS (x, class)
|
||||
|
||||
@ -313,20 +268,10 @@ in many of the tables described below.
|
||||
this feature to discourage usage of 387 registers when math is done in
|
||||
the SSE registers (and vice versa).
|
||||
|
||||
.. function:: reg_class_t TARGET_PREFERRED_OUTPUT_RELOAD_CLASS (rtx x, reg_class_t rclass)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PREFERRED_OUTPUT_RELOAD_CLASS]
|
||||
:end-before: [TARGET_PREFERRED_OUTPUT_RELOAD_CLASS]
|
||||
|
||||
.. hook-start:TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
|
||||
|
||||
Like ``TARGET_PREFERRED_RELOAD_CLASS``, but for output reloads instead of
|
||||
input reloads.
|
||||
|
||||
The default version of this hook always returns value of ``rclass``
|
||||
argument.
|
||||
|
||||
You can also use ``TARGET_PREFERRED_OUTPUT_RELOAD_CLASS`` to discourage
|
||||
reload from using some alternatives, like ``TARGET_PREFERRED_RELOAD_CLASS``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: LIMIT_RELOAD_CLASS (mode, class)
|
||||
|
||||
@ -344,103 +289,10 @@ in many of the tables described below.
|
||||
Don't define this macro unless the target machine has limitations which
|
||||
require the macro to do something nontrivial.
|
||||
|
||||
.. function:: reg_class_t TARGET_SECONDARY_RELOAD (bool in_p, rtx x, reg_class_t reload_class, machine_mode reload_mode, secondary_reload_info *sri)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SECONDARY_RELOAD]
|
||||
:end-before: [TARGET_SECONDARY_RELOAD]
|
||||
|
||||
.. hook-start:TARGET_SECONDARY_RELOAD
|
||||
|
||||
Many machines have some registers that cannot be copied directly to or
|
||||
from memory or even from other types of registers. An example is the
|
||||
:samp:`MQ` register, which on most machines, can only be copied to or
|
||||
from general registers, but not memory. Below, we shall be using the
|
||||
term 'intermediate register' when a move operation cannot be performed
|
||||
directly, but has to be done by copying the source into the intermediate
|
||||
register first, and then copying the intermediate register to the
|
||||
destination. An intermediate register always has the same mode as
|
||||
source and destination. Since it holds the actual value being copied,
|
||||
reload might apply optimizations to re-use an intermediate register
|
||||
and eliding the copy from the source when it can determine that the
|
||||
intermediate register still holds the required value.
|
||||
|
||||
Another kind of secondary reload is required on some machines which
|
||||
allow copying all registers to and from memory, but require a scratch
|
||||
register for stores to some memory locations (e.g., those with symbolic
|
||||
address on the RT, and those with certain symbolic address on the SPARC
|
||||
when compiling PIC). Scratch registers need not have the same mode
|
||||
as the value being copied, and usually hold a different value than
|
||||
that being copied. Special patterns in the md file are needed to
|
||||
describe how the copy is performed with the help of the scratch register;
|
||||
these patterns also describe the number, register class(es) and mode(s)
|
||||
of the scratch register(s).
|
||||
|
||||
In some cases, both an intermediate and a scratch register are required.
|
||||
|
||||
For input reloads, this target hook is called with nonzero :samp:`{in_p}`,
|
||||
and :samp:`{x}` is an rtx that needs to be copied to a register of class
|
||||
:samp:`{reload_class}` in :samp:`{reload_mode}`. For output reloads, this target
|
||||
hook is called with zero :samp:`{in_p}`, and a register of class :samp:`{reload_class}`
|
||||
needs to be copied to rtx :samp:`{x}` in :samp:`{reload_mode}`.
|
||||
|
||||
If copying a register of :samp:`{reload_class}` from/to :samp:`{x}` requires
|
||||
an intermediate register, the hook ``secondary_reload`` should
|
||||
return the register class required for this intermediate register.
|
||||
If no intermediate register is required, it should return NO_REGS.
|
||||
If more than one intermediate register is required, describe the one
|
||||
that is closest in the copy chain to the reload register.
|
||||
|
||||
If scratch registers are needed, you also have to describe how to
|
||||
perform the copy from/to the reload register to/from this
|
||||
closest intermediate register. Or if no intermediate register is
|
||||
required, but still a scratch register is needed, describe the
|
||||
copy from/to the reload register to/from the reload operand :samp:`{x}`.
|
||||
|
||||
You do this by setting ``sri->icode`` to the instruction code of a pattern
|
||||
in the md file which performs the move. Operands 0 and 1 are the output
|
||||
and input of this copy, respectively. Operands from operand 2 onward are
|
||||
for scratch operands. These scratch operands must have a mode, and a
|
||||
single-register-class
|
||||
|
||||
.. [later: or memory]
|
||||
|
||||
output constraint.
|
||||
|
||||
When an intermediate register is used, the ``secondary_reload``
|
||||
hook will be called again to determine how to copy the intermediate
|
||||
register to/from the reload operand :samp:`{x}`, so your hook must also
|
||||
have code to handle the register class of the intermediate operand.
|
||||
|
||||
.. [For later: maybe we'll allow multi-alternative reload patterns -
|
||||
|
||||
.. the port maintainer could name a mov<mode> pattern that has clobbers -
|
||||
|
||||
.. and match the constraints of input and output to determine the required
|
||||
|
||||
.. alternative. A restriction would be that constraints used to match
|
||||
|
||||
.. against reloads registers would have to be written as register class
|
||||
|
||||
.. constraints, or we need a new target macro / hook that tells us if an
|
||||
|
||||
.. arbitrary constraint can match an unknown register of a given class.
|
||||
|
||||
.. Such a macro / hook would also be useful in other places.]
|
||||
|
||||
:samp:`{x}` might be a pseudo-register or a ``subreg`` of a
|
||||
pseudo-register, which could either be in a hard register or in memory.
|
||||
Use ``true_regnum`` to find out; it will return -1 if the pseudo is
|
||||
in memory and the hard register number if it is in a register.
|
||||
|
||||
Scratch operands in memory (constraint ``"=m"`` / ``"=&m"``) are
|
||||
currently not supported. For the time being, you will have to continue
|
||||
to use ``TARGET_SECONDARY_MEMORY_NEEDED`` for that purpose.
|
||||
|
||||
``copy_cost`` also uses this target hook to find out how values are
|
||||
copied. If you want it to include some extra cost for the need to allocate
|
||||
(a) scratch register(s), set ``sri->extra_cost`` to the additional cost.
|
||||
Or if two dependent moves are supposed to have a lower cost than the sum
|
||||
of the individual moves due to expected fortuitous scheduling and/or special
|
||||
forwarding logic, you can set ``sri->extra_cost`` to a negative amount.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: SECONDARY_RELOAD_CLASS (class, mode, x)
|
||||
SECONDARY_INPUT_RELOAD_CLASS (class, mode, x)
|
||||
@ -502,19 +354,10 @@ in many of the tables described below.
|
||||
intermediate storage. This case often occurs between floating-point and
|
||||
general registers.
|
||||
|
||||
.. function:: bool TARGET_SECONDARY_MEMORY_NEEDED (machine_mode mode, reg_class_t class1, reg_class_t class2)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SECONDARY_MEMORY_NEEDED]
|
||||
:end-before: [TARGET_SECONDARY_MEMORY_NEEDED]
|
||||
|
||||
.. hook-start:TARGET_SECONDARY_MEMORY_NEEDED
|
||||
|
||||
Certain machines have the property that some registers cannot be copied
|
||||
to some other registers without using memory. Define this hook on
|
||||
those machines to return true if objects of mode :samp:`{m}` in registers
|
||||
of :samp:`{class1}` can only be copied to registers of class :samp:`{class2}` by
|
||||
storing a register of :samp:`{class1}` into memory and loading that memory
|
||||
location into a register of :samp:`{class2}`. The default definition returns
|
||||
false for all inputs.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: SECONDARY_MEMORY_NEEDED_RTX (mode)
|
||||
|
||||
@ -526,87 +369,25 @@ in many of the tables described below.
|
||||
Do not define this macro if you do not define
|
||||
``TARGET_SECONDARY_MEMORY_NEEDED``.
|
||||
|
||||
.. function:: machine_mode TARGET_SECONDARY_MEMORY_NEEDED_MODE (machine_mode mode)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SECONDARY_MEMORY_NEEDED_MODE]
|
||||
:end-before: [TARGET_SECONDARY_MEMORY_NEEDED_MODE]
|
||||
|
||||
.. hook-start:TARGET_SECONDARY_MEMORY_NEEDED_MODE
|
||||
|
||||
If ``TARGET_SECONDARY_MEMORY_NEEDED`` tells the compiler to use memory
|
||||
when moving between two particular registers of mode :samp:`{mode}`,
|
||||
this hook specifies the mode that the memory should have.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SELECT_EARLY_REMAT_MODES]
|
||||
:end-before: [TARGET_SELECT_EARLY_REMAT_MODES]
|
||||
|
||||
The default depends on ``TARGET_LRA_P``. Without LRA, the default
|
||||
is to use a word-sized mode for integral modes that are smaller than a
|
||||
a word. This is right thing to do on most machines because it ensures
|
||||
that all bits of the register are copied and prevents accesses to the
|
||||
registers in a narrower mode, which some machines prohibit for
|
||||
floating-point registers.
|
||||
|
||||
However, this default behavior is not correct on some machines, such as
|
||||
the DEC Alpha, that store short integers in floating-point registers
|
||||
differently than in integer registers. On those machines, the default
|
||||
widening will not work correctly and you must define this hook to
|
||||
suppress that widening in some cases. See the file :samp:`alpha.cc` for
|
||||
details.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CLASS_LIKELY_SPILLED_P]
|
||||
:end-before: [TARGET_CLASS_LIKELY_SPILLED_P]
|
||||
|
||||
With LRA, the default is to use :samp:`{mode}` unmodified.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CLASS_MAX_NREGS]
|
||||
:end-before: [TARGET_CLASS_MAX_NREGS]
|
||||
|
||||
.. function:: void TARGET_SELECT_EARLY_REMAT_MODES (sbitmap modes)
|
||||
|
||||
.. hook-start:TARGET_SELECT_EARLY_REMAT_MODES
|
||||
|
||||
On some targets, certain modes cannot be held in registers around a
|
||||
standard ABI call and are relatively expensive to spill to the stack.
|
||||
The early rematerialization pass can help in such cases by aggressively
|
||||
recomputing values after calls, so that they don't need to be spilled.
|
||||
|
||||
This hook returns the set of such modes by setting the associated bits
|
||||
in :samp:`{modes}`. The default implementation selects no modes, which has
|
||||
the effect of disabling the early rematerialization pass.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CLASS_LIKELY_SPILLED_P (reg_class_t rclass)
|
||||
|
||||
.. hook-start:TARGET_CLASS_LIKELY_SPILLED_P
|
||||
|
||||
A target hook which returns ``true`` if pseudos that have been assigned
|
||||
to registers of class :samp:`{rclass}` would likely be spilled because
|
||||
registers of :samp:`{rclass}` are needed for spill registers.
|
||||
|
||||
The default version of this target hook returns ``true`` if :samp:`{rclass}`
|
||||
has exactly one register and ``false`` otherwise. On most machines, this
|
||||
default should be used. For generally register-starved machines, such as
|
||||
i386, or machines with right register constraints, such as SH, this hook
|
||||
can be used to avoid excessive spilling.
|
||||
|
||||
This hook is also used by some of the global intra-procedural code
|
||||
transformations to throtle code motion, to avoid increasing register
|
||||
pressure.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: unsigned char TARGET_CLASS_MAX_NREGS (reg_class_t rclass, machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_CLASS_MAX_NREGS
|
||||
|
||||
A target hook returns the maximum number of consecutive registers
|
||||
of class :samp:`{rclass}` needed to hold a value of mode :samp:`{mode}`.
|
||||
|
||||
This is closely related to the macro ``TARGET_HARD_REGNO_NREGS``.
|
||||
In fact, the value returned by ``TARGET_CLASS_MAX_NREGS (rclass,
|
||||
mode)`` target hook should be the maximum value of
|
||||
``TARGET_HARD_REGNO_NREGS (regno, mode)`` for all :samp:`{regno}`
|
||||
values in the class :samp:`{rclass}`.
|
||||
|
||||
This target hook helps control the handling of multiple-word values
|
||||
in the reload pass.
|
||||
|
||||
The default version of this target hook returns the size of :samp:`{mode}`
|
||||
in words.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: CLASS_MAX_NREGS (class, mode)
|
||||
|
||||
@ -621,181 +402,61 @@ in many of the tables described below.
|
||||
This macro helps control the handling of multiple-word values
|
||||
in the reload pass.
|
||||
|
||||
.. function:: bool TARGET_CAN_CHANGE_MODE_CLASS (machine_mode from, machine_mode to, reg_class_t rclass)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CAN_CHANGE_MODE_CLASS]
|
||||
:end-before: [TARGET_CAN_CHANGE_MODE_CLASS]
|
||||
|
||||
.. hook-start:TARGET_CAN_CHANGE_MODE_CLASS
|
||||
|
||||
This hook returns true if it is possible to bitcast values held in
|
||||
registers of class :samp:`{rclass}` from mode :samp:`{from}` to mode :samp:`{to}`
|
||||
and if doing so preserves the low-order bits that are common to both modes.
|
||||
The result is only meaningful if :samp:`{rclass}` has registers that can hold
|
||||
both ``from`` and ``to``. The default implementation returns true.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS]
|
||||
:end-before: [TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS]
|
||||
|
||||
As an example of when such bitcasting is invalid, loading 32-bit integer or
|
||||
floating-point objects into floating-point registers on Alpha extends them
|
||||
to 64 bits. Therefore loading a 64-bit object and then storing it as a
|
||||
32-bit object does not store the low-order 32 bits, as would be the case
|
||||
for a normal register. Therefore, :samp:`alpha.h` defines
|
||||
``TARGET_CAN_CHANGE_MODE_CLASS`` to return:
|
||||
|
||||
.. code-block:: c++
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LRA_P]
|
||||
:end-before: [TARGET_LRA_P]
|
||||
|
||||
(GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
|
||||
|| !reg_classes_intersect_p (FLOAT_REGS, rclass))
|
||||
|
||||
Even if storing from a register in mode :samp:`{to}` would be valid,
|
||||
if both :samp:`{from}` and ``raw_reg_mode`` for :samp:`{rclass}` are wider
|
||||
than ``word_mode``, then we must prevent :samp:`{to}` narrowing the
|
||||
mode. This happens when the middle-end assumes that it can load
|
||||
or store pieces of an :samp:`{N}` -word pseudo, and that the pseudo will
|
||||
eventually be allocated to :samp:`{N}` ``word_mode`` hard registers.
|
||||
Failure to prevent this kind of mode change will result in the
|
||||
entire ``raw_reg_mode`` being modified instead of the partial
|
||||
value that the middle-end intended.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_REGISTER_PRIORITY]
|
||||
:end-before: [TARGET_REGISTER_PRIORITY]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: reg_class_t TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS (int, reg_class_t, reg_class_t)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_REGISTER_USAGE_LEVELING_P]
|
||||
:end-before: [TARGET_REGISTER_USAGE_LEVELING_P]
|
||||
|
||||
.. hook-start:TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
|
||||
|
||||
A target hook which can change allocno class for given pseudo from
|
||||
allocno and best class calculated by IRA.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DIFFERENT_ADDR_DISPLACEMENT_P]
|
||||
:end-before: [TARGET_DIFFERENT_ADDR_DISPLACEMENT_P]
|
||||
|
||||
The default version of this target hook always returns given class.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P]
|
||||
:end-before: [TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P]
|
||||
|
||||
.. function:: bool TARGET_LRA_P (void)
|
||||
|
||||
.. hook-start:TARGET_LRA_P
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT]
|
||||
:end-before: [TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT]
|
||||
|
||||
A target hook which returns true if we use LRA instead of reload pass.
|
||||
|
||||
The default version of this target hook returns true. New ports
|
||||
should use LRA, and existing ports are encouraged to convert.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_SPILL_CLASS]
|
||||
:end-before: [TARGET_SPILL_CLASS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_REGISTER_PRIORITY (int)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ADDITIONAL_ALLOCNO_CLASS_P]
|
||||
:end-before: [TARGET_ADDITIONAL_ALLOCNO_CLASS_P]
|
||||
|
||||
.. hook-start:TARGET_REGISTER_PRIORITY
|
||||
|
||||
A target hook which returns the register priority number to which the
|
||||
register :samp:`{hard_regno}` belongs to. The bigger the number, the
|
||||
more preferable the hard register usage (when all other conditions are
|
||||
the same). This hook can be used to prefer some hard register over
|
||||
others in LRA. For example, some x86-64 register usage needs
|
||||
additional prefix which makes instructions longer. The hook can
|
||||
return lower priority number for such registers make them less favorable
|
||||
and as result making the generated code smaller.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CSTORE_MODE]
|
||||
:end-before: [TARGET_CSTORE_MODE]
|
||||
|
||||
The default version of this target hook returns always zero.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_REGISTER_USAGE_LEVELING_P (void)
|
||||
|
||||
.. hook-start:TARGET_REGISTER_USAGE_LEVELING_P
|
||||
|
||||
A target hook which returns true if we need register usage leveling.
|
||||
That means if a few hard registers are equally good for the
|
||||
assignment, we choose the least used hard register. The register
|
||||
usage leveling may be profitable for some targets. Don't use the
|
||||
usage leveling for targets with conditional execution or targets
|
||||
with big register files as it hurts if-conversion and cross-jumping
|
||||
optimizations.
|
||||
|
||||
The default version of this target hook returns always false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_DIFFERENT_ADDR_DISPLACEMENT_P (void)
|
||||
|
||||
.. hook-start:TARGET_DIFFERENT_ADDR_DISPLACEMENT_P
|
||||
|
||||
A target hook which returns true if an address with the same structure
|
||||
can have different maximal legitimate displacement. For example, the
|
||||
displacement can depend on memory mode or on operand combinations in
|
||||
the insn.
|
||||
|
||||
The default version of this target hook returns always false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P (rtx subst)
|
||||
|
||||
.. hook-start:TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
|
||||
|
||||
A target hook which returns ``true`` if :samp:`{subst}` can't
|
||||
substitute safely pseudos with equivalent memory values during
|
||||
register allocation.
|
||||
The default version of this target hook returns ``false``.
|
||||
On most machines, this default should be used. For generally
|
||||
machines with non orthogonal register usage for addressing, such
|
||||
as SH, this hook can be used to avoid excessive spilling.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT (rtx *offset1, rtx *offset2, poly_int64 orig_offset, machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT
|
||||
|
||||
This hook tries to split address offset :samp:`{orig_offset}` into
|
||||
two parts: one that should be added to the base address to create
|
||||
a local anchor point, and an additional offset that can be applied
|
||||
to the anchor to address a value of mode :samp:`{mode}`. The idea is that
|
||||
the local anchor could be shared by other accesses to nearby locations.
|
||||
|
||||
The hook returns true if it succeeds, storing the offset of the
|
||||
anchor from the base in :samp:`{offset1}` and the offset of the final address
|
||||
from the anchor in :samp:`{offset2}`. The default implementation returns false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: reg_class_t TARGET_SPILL_CLASS (reg_class_t, machine_mode)
|
||||
|
||||
.. hook-start:TARGET_SPILL_CLASS
|
||||
|
||||
This hook defines a class of registers which could be used for spilling
|
||||
pseudos of the given mode and class, or ``NO_REGS`` if only memory
|
||||
should be used. Not defining this hook is equivalent to returning
|
||||
``NO_REGS`` for all inputs.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ADDITIONAL_ALLOCNO_CLASS_P (reg_class_t)
|
||||
|
||||
.. hook-start:TARGET_ADDITIONAL_ALLOCNO_CLASS_P
|
||||
|
||||
This hook should return ``true`` if given class of registers should
|
||||
be an allocno class in any way. Usually RA uses only one register
|
||||
class from all classes containing the same register set. In some
|
||||
complicated cases, you need to have two or more such classes as
|
||||
allocno ones for RA correct work. Not defining this hook is
|
||||
equivalent to returning ``false`` for all inputs.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: scalar_int_mode TARGET_CSTORE_MODE (enum insn_code icode)
|
||||
|
||||
.. hook-start:TARGET_CSTORE_MODE
|
||||
|
||||
This hook defines the machine mode to use for the boolean result of
|
||||
conditional store patterns. The ICODE argument is the instruction code
|
||||
for the cstore being performed. Not definiting this hook is the same
|
||||
as accepting the mode encoded into operand 0 of the cstore expander
|
||||
patterns.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_COMPUTE_PRESSURE_CLASSES (enum reg_class *pressure_classes)
|
||||
|
||||
.. hook-start:TARGET_COMPUTE_PRESSURE_CLASSES
|
||||
|
||||
A target hook which lets a backend compute the set of pressure classes to
|
||||
be used by those optimization passes which take register pressure into
|
||||
account, as opposed to letting IRA compute them. It returns the number of
|
||||
register classes stored in the array :samp:`{pressure_classes}`.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_COMPUTE_PRESSURE_CLASSES]
|
||||
:end-before: [TARGET_COMPUTE_PRESSURE_CLASSES]
|
||||
|
@ -91,104 +91,34 @@ Registers have various characteristics.
|
||||
|
||||
.. index:: call-used register, call-clobbered register, call-saved register
|
||||
|
||||
.. function:: const predefined_function_abi & TARGET_FNTYPE_ABI (const_tree type)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_FNTYPE_ABI]
|
||||
:end-before: [TARGET_FNTYPE_ABI]
|
||||
|
||||
.. hook-start:TARGET_FNTYPE_ABI
|
||||
|
||||
Return the ABI used by a function with type :samp:`{type}` ; see the
|
||||
definition of ``predefined_function_abi`` for details of the ABI
|
||||
descriptor. Targets only need to define this hook if they support
|
||||
interoperability between several ABIs in the same translation unit.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_INSN_CALLEE_ABI]
|
||||
:end-before: [TARGET_INSN_CALLEE_ABI]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: const predefined_function_abi & TARGET_INSN_CALLEE_ABI (const rtx_insn *insn)
|
||||
|
||||
.. hook-start:TARGET_INSN_CALLEE_ABI
|
||||
|
||||
This hook returns a description of the ABI used by the target of
|
||||
call instruction :samp:`{insn}` ; see the definition of
|
||||
``predefined_function_abi`` for details of the ABI descriptor.
|
||||
Only the global function ``insn_callee_abi`` should call this hook
|
||||
directly.
|
||||
|
||||
Targets only need to define this hook if they support
|
||||
interoperability between several ABIs in the same translation unit.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. index:: call-used register, call-clobbered register, call-saved register
|
||||
|
||||
.. function:: bool TARGET_HARD_REGNO_CALL_PART_CLOBBERED (unsigned int abi_id, unsigned int regno, machine_mode mode)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HARD_REGNO_CALL_PART_CLOBBERED]
|
||||
:end-before: [TARGET_HARD_REGNO_CALL_PART_CLOBBERED]
|
||||
|
||||
.. hook-start:TARGET_HARD_REGNO_CALL_PART_CLOBBERED
|
||||
|
||||
ABIs usually specify that calls must preserve the full contents
|
||||
of a particular register, or that calls can alter any part of a
|
||||
particular register. This information is captured by the target macro
|
||||
``CALL_REALLY_USED_REGISTERS``. However, some ABIs specify that calls
|
||||
must preserve certain bits of a particular register but can alter others.
|
||||
This hook should return true if this applies to at least one of the
|
||||
registers in :samp:`(reg:{mode}{regno})`, and if as a result the
|
||||
call would alter part of the :samp:`{mode}` value. For example, if a call
|
||||
preserves the low 32 bits of a 64-bit hard register :samp:`{regno}` but can
|
||||
clobber the upper 32 bits, this hook should return true for a 64-bit mode
|
||||
but false for a 32-bit mode.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_GET_MULTILIB_ABI_NAME]
|
||||
:end-before: [TARGET_GET_MULTILIB_ABI_NAME]
|
||||
|
||||
The value of :samp:`{abi_id}` comes from the ``predefined_function_abi``
|
||||
structure that describes the ABI of the call; see the definition of the
|
||||
structure for more details. If (as is usual) the target uses the same ABI
|
||||
for all functions in a translation unit, :samp:`{abi_id}` is always 0.
|
||||
|
||||
The default implementation returns false, which is correct
|
||||
for targets that don't have partly call-clobbered registers.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: const char * TARGET_GET_MULTILIB_ABI_NAME (void)
|
||||
|
||||
.. hook-start:TARGET_GET_MULTILIB_ABI_NAME
|
||||
|
||||
This hook returns name of multilib ABI name.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. index:: fixed_regs, call_used_regs, global_regs, reg_names, reg_class_contents
|
||||
|
||||
.. function:: void TARGET_CONDITIONAL_REGISTER_USAGE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CONDITIONAL_REGISTER_USAGE]
|
||||
:end-before: [TARGET_CONDITIONAL_REGISTER_USAGE]
|
||||
|
||||
.. hook-start:TARGET_CONDITIONAL_REGISTER_USAGE
|
||||
|
||||
This hook may conditionally modify five variables
|
||||
``fixed_regs``, ``call_used_regs``, ``global_regs``,
|
||||
``reg_names``, and ``reg_class_contents``, to take into account
|
||||
any dependence of these register sets on target flags. The first three
|
||||
of these are of type ``char []`` (interpreted as boolean vectors).
|
||||
``global_regs`` is a ``const char *[]``, and
|
||||
``reg_class_contents`` is a ``HARD_REG_SET``. Before the macro is
|
||||
called, ``fixed_regs``, ``call_used_regs``,
|
||||
``reg_class_contents``, and ``reg_names`` have been initialized
|
||||
from ``FIXED_REGISTERS``, ``CALL_USED_REGISTERS``,
|
||||
``REG_CLASS_CONTENTS``, and ``REGISTER_NAMES``, respectively.
|
||||
``global_regs`` has been cleared, and any :option:`-ffixed-reg`,
|
||||
:option:`-fcall-used-reg` and :option:`-fcall-saved-reg`
|
||||
command options have been applied.
|
||||
|
||||
.. index:: disabling certain registers, controlling register usage
|
||||
|
||||
If the usage of an entire class of registers depends on the target
|
||||
flags, you may indicate this to GCC by using this macro to modify
|
||||
``fixed_regs`` and ``call_used_regs`` to 1 for each of the
|
||||
registers in the classes which should not be used by GCC. Also make
|
||||
``define_register_constraint`` s return ``NO_REGS`` for constraints
|
||||
that shouldn't be used.
|
||||
|
||||
(However, if this class is not included in ``GENERAL_REGS`` and all
|
||||
of the insn patterns whose constraints permit this class are
|
||||
controlled by target switches, then GCC will automatically avoid using
|
||||
these registers when the target switches are opposed to them.)
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: INCOMING_REGNO (out)
|
||||
|
||||
@ -289,20 +219,10 @@ This section discusses the macros that describe which kinds of values
|
||||
(specifically, which machine modes) each register can hold, and how many
|
||||
consecutive registers are needed for a given mode.
|
||||
|
||||
.. function:: unsigned int TARGET_HARD_REGNO_NREGS (unsigned int regno, machine_mode mode)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HARD_REGNO_NREGS]
|
||||
:end-before: [TARGET_HARD_REGNO_NREGS]
|
||||
|
||||
.. hook-start:TARGET_HARD_REGNO_NREGS
|
||||
|
||||
This hook returns the number of consecutive hard registers, starting
|
||||
at register number :samp:`{regno}`, required to hold a value of mode
|
||||
:samp:`{mode}`. This hook must never return zero, even if a register
|
||||
cannot hold the requested mode - indicate that with
|
||||
``TARGET_HARD_REGNO_MODE_OK`` and/or
|
||||
``TARGET_CAN_CHANGE_MODE_CLASS`` instead.
|
||||
|
||||
The default definition returns the number of words in :samp:`{mode}`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: HARD_REGNO_NREGS_HAS_PADDING (regno, mode)
|
||||
|
||||
@ -340,67 +260,10 @@ consecutive registers are needed for a given mode.
|
||||
happens for example on SPARC 64-bit where the natural size of
|
||||
floating-point registers is still 32-bit.
|
||||
|
||||
.. function:: bool TARGET_HARD_REGNO_MODE_OK (unsigned int regno, machine_mode mode)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HARD_REGNO_MODE_OK]
|
||||
:end-before: [TARGET_HARD_REGNO_MODE_OK]
|
||||
|
||||
.. hook-start:TARGET_HARD_REGNO_MODE_OK
|
||||
|
||||
This hook returns true if it is permissible to store a value
|
||||
of mode :samp:`{mode}` in hard register number :samp:`{regno}` (or in several
|
||||
registers starting with that one). The default definition returns true
|
||||
unconditionally.
|
||||
|
||||
You need not include code to check for the numbers of fixed registers,
|
||||
because the allocation mechanism considers them to be always occupied.
|
||||
|
||||
.. index:: register pairs
|
||||
|
||||
On some machines, double-precision values must be kept in even/odd
|
||||
register pairs. You can implement that by defining this hook to reject
|
||||
odd register numbers for such modes.
|
||||
|
||||
The minimum requirement for a mode to be OK in a register is that the
|
||||
:samp:`mov{mode}` instruction pattern support moves between the
|
||||
register and other hard register in the same class and that moving a
|
||||
value into the register and back out not alter it.
|
||||
|
||||
Since the same instruction used to move ``word_mode`` will work for
|
||||
all narrower integer modes, it is not necessary on any machine for
|
||||
this hook to distinguish between these modes, provided you define
|
||||
patterns :samp:`movhi`, etc., to take advantage of this. This is
|
||||
useful because of the interaction between ``TARGET_HARD_REGNO_MODE_OK``
|
||||
and ``TARGET_MODES_TIEABLE_P`` ; it is very desirable for all integer
|
||||
modes to be tieable.
|
||||
|
||||
Many machines have special registers for floating point arithmetic.
|
||||
Often people assume that floating point machine modes are allowed only
|
||||
in floating point registers. This is not true. Any registers that
|
||||
can hold integers can safely *hold* a floating point machine
|
||||
mode, whether or not floating arithmetic can be done on it in those
|
||||
registers. Integer move instructions can be used to move the values.
|
||||
|
||||
On some machines, though, the converse is true: fixed-point machine
|
||||
modes may not go in floating registers. This is true if the floating
|
||||
registers normalize any value stored in them, because storing a
|
||||
non-floating value there would garble it. In this case,
|
||||
``TARGET_HARD_REGNO_MODE_OK`` should reject fixed-point machine modes in
|
||||
floating registers. But if the floating registers do not automatically
|
||||
normalize, if you can store any bit pattern in one and retrieve it
|
||||
unchanged without a trap, then any machine mode may go in a floating
|
||||
register, so you can define this hook to say so.
|
||||
|
||||
The primary significance of special floating registers is rather that
|
||||
they are the registers acceptable in floating point arithmetic
|
||||
instructions. However, this is of no concern to
|
||||
``TARGET_HARD_REGNO_MODE_OK``. You handle it by writing the proper
|
||||
constraints for those instructions.
|
||||
|
||||
On some machines, the floating registers are especially slow to access,
|
||||
so that it is better to store a value in a stack frame than in such a
|
||||
register if floating point arithmetic is not being done. As long as the
|
||||
floating registers are not in class ``GENERAL_REGS``, they will not
|
||||
be used unless some pattern's constraint asks for one.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: HARD_REGNO_RENAME_OK (from, to)
|
||||
|
||||
@ -413,40 +276,15 @@ consecutive registers are needed for a given mode.
|
||||
|
||||
The default is always nonzero.
|
||||
|
||||
.. function:: bool TARGET_MODES_TIEABLE_P (machine_mode mode1, machine_mode mode2)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MODES_TIEABLE_P]
|
||||
:end-before: [TARGET_MODES_TIEABLE_P]
|
||||
|
||||
.. hook-start:TARGET_MODES_TIEABLE_P
|
||||
|
||||
This hook returns true if a value of mode :samp:`{mode1}` is accessible
|
||||
in mode :samp:`{mode2}` without copying.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HARD_REGNO_SCRATCH_OK]
|
||||
:end-before: [TARGET_HARD_REGNO_SCRATCH_OK]
|
||||
|
||||
If ``TARGET_HARD_REGNO_MODE_OK (r, mode1)`` and
|
||||
``TARGET_HARD_REGNO_MODE_OK (r, mode2)`` are always
|
||||
the same for any :samp:`{r}`, then
|
||||
``TARGET_MODES_TIEABLE_P (mode1, mode2)``
|
||||
should be true. If they differ for any :samp:`{r}`, you should define
|
||||
this hook to return false unless some other mechanism ensures the
|
||||
accessibility of the value in a narrower mode.
|
||||
|
||||
You should define this hook to return true in as many cases as
|
||||
possible since doing so will allow GCC to perform better register
|
||||
allocation. The default definition returns true unconditionally.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_HARD_REGNO_SCRATCH_OK (unsigned int regno)
|
||||
|
||||
.. hook-start:TARGET_HARD_REGNO_SCRATCH_OK
|
||||
|
||||
This target hook should return ``true`` if it is OK to use a hard register
|
||||
:samp:`{regno}` as scratch reg in peephole2.
|
||||
|
||||
One common use of this macro is to prevent using of a register that
|
||||
is not saved by a prologue in an interrupt handler.
|
||||
|
||||
The default version of this hook always returns ``true``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: AVOID_CCMODE_COPIES
|
||||
|
||||
|
@ -67,22 +67,20 @@ Here are run-time target specifications.
|
||||
Variable extern int target_flagsThis variable is declared in :samp:`options.h`, which is included before
|
||||
any target-specific headers.
|
||||
|
||||
.. c:var:: int TARGET_DEFAULT_TARGET_FLAGS
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DEFAULT_TARGET_FLAGS]
|
||||
:end-before: [TARGET_DEFAULT_TARGET_FLAGS]
|
||||
|
||||
.. hook-start:TARGET_DEFAULT_TARGET_FLAGS
|
||||
|
||||
.. hook-end
|
||||
|
||||
This variable specifies the initial value of ``target_flags``.
|
||||
Its default setting is 0.
|
||||
|
||||
.. index:: optional hardware or system features, features, optional, in system conventions
|
||||
|
||||
.. function:: bool TARGET_HANDLE_OPTION (struct gcc_options *opts, struct gcc_options *opts_set, const struct cl_decoded_option *decoded, location_t loc)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HANDLE_OPTION]
|
||||
:end-before: [TARGET_HANDLE_OPTION]
|
||||
|
||||
.. hook-start:TARGET_HANDLE_OPTION
|
||||
|
||||
.. hook-end
|
||||
|
||||
This hook is called whenever the user specifies one of the
|
||||
target-specific options described by the :samp:`.opt` definition files
|
||||
@ -96,11 +94,10 @@ any target-specific headers.
|
||||
option was passed (``UNKNOWN_LOCATION`` except for options passed
|
||||
via attributes).
|
||||
|
||||
.. function:: bool TARGET_HANDLE_C_OPTION (size_t code, const char *arg, int value)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_HANDLE_C_OPTION]
|
||||
:end-before: [TARGET_HANDLE_C_OPTION]
|
||||
|
||||
.. hook-start:TARGET_HANDLE_C_OPTION
|
||||
|
||||
.. hook-end
|
||||
|
||||
This target hook is called whenever the user specifies one of the
|
||||
target-specific C language family options described by the :samp:`.opt`
|
||||
@ -114,76 +111,35 @@ any target-specific headers.
|
||||
only available in the C (and related language) front ends, then you
|
||||
should use ``TARGET_HANDLE_C_OPTION`` instead.
|
||||
|
||||
.. function:: tree TARGET_OBJC_CONSTRUCT_STRING_OBJECT (tree string)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OBJC_CONSTRUCT_STRING_OBJECT]
|
||||
:end-before: [TARGET_OBJC_CONSTRUCT_STRING_OBJECT]
|
||||
|
||||
.. hook-start:TARGET_OBJC_CONSTRUCT_STRING_OBJECT
|
||||
|
||||
Targets may provide a string object type that can be used within
|
||||
and between C, C++ and their respective Objective-C dialects.
|
||||
A string object might, for example, embed encoding and length information.
|
||||
These objects are considered opaque to the compiler and handled as references.
|
||||
An ideal implementation makes the composition of the string object
|
||||
match that of the Objective-C ``NSString`` (``NXString`` for GNUStep),
|
||||
allowing efficient interworking between C-only and Objective-C code.
|
||||
If a target implements string objects then this hook should return a
|
||||
reference to such an object constructed from the normal 'C' string
|
||||
representation provided in :samp:`{string}`.
|
||||
At present, the hook is used by Objective-C only, to obtain a
|
||||
common-format string object when the target provides one.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OBJC_DECLARE_UNRESOLVED_CLASS_REFERENCE]
|
||||
:end-before: [TARGET_OBJC_DECLARE_UNRESOLVED_CLASS_REFERENCE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_OBJC_DECLARE_UNRESOLVED_CLASS_REFERENCE (const char *classname)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OBJC_DECLARE_CLASS_DEFINITION]
|
||||
:end-before: [TARGET_OBJC_DECLARE_CLASS_DEFINITION]
|
||||
|
||||
.. hook-start:TARGET_OBJC_DECLARE_UNRESOLVED_CLASS_REFERENCE
|
||||
|
||||
Declare that Objective C class :samp:`{classname}` is referenced
|
||||
by the current TU.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_STRING_OBJECT_REF_TYPE_P]
|
||||
:end-before: [TARGET_STRING_OBJECT_REF_TYPE_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_OBJC_DECLARE_CLASS_DEFINITION (const char *classname)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CHECK_STRING_OBJECT_FORMAT_ARG]
|
||||
:end-before: [TARGET_CHECK_STRING_OBJECT_FORMAT_ARG]
|
||||
|
||||
.. hook-start:TARGET_OBJC_DECLARE_CLASS_DEFINITION
|
||||
|
||||
Declare that Objective C class :samp:`{classname}` is defined
|
||||
by the current TU.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE]
|
||||
:end-before: [TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_STRING_OBJECT_REF_TYPE_P (const_tree stringref)
|
||||
|
||||
.. hook-start:TARGET_STRING_OBJECT_REF_TYPE_P
|
||||
|
||||
If a target implements string objects then this hook should return
|
||||
``true`` if :samp:`{stringref}` is a valid reference to such an object.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_CHECK_STRING_OBJECT_FORMAT_ARG (tree format_arg, tree args_list)
|
||||
|
||||
.. hook-start:TARGET_CHECK_STRING_OBJECT_FORMAT_ARG
|
||||
|
||||
If a target implements string objects then this hook should
|
||||
provide a facility to check the function arguments in :samp:`{args_list}`
|
||||
against the format specifiers in :samp:`{format_arg}` where the type of
|
||||
:samp:`{format_arg}` is one recognized as a valid string reference type.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE (void)
|
||||
|
||||
.. hook-start:TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
|
||||
|
||||
This target function is similar to the hook ``TARGET_OPTION_OVERRIDE``
|
||||
but is called when the optimize level is changed via an attribute or
|
||||
pragma or when it is reset at the end of the code affected by the
|
||||
attribute or pragma. It is not called at the beginning of compilation
|
||||
when ``TARGET_OPTION_OVERRIDE`` is called so if you want to perform these
|
||||
actions then, you should have ``TARGET_OPTION_OVERRIDE`` call
|
||||
``TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: C_COMMON_OVERRIDE_OPTIONS
|
||||
|
||||
@ -193,11 +149,10 @@ any target-specific headers.
|
||||
used to alter option flag variables which only exist in those
|
||||
frontends.
|
||||
|
||||
.. c:var:: const struct default_options * TARGET_OPTION_OPTIMIZATION_TABLE
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_OPTIMIZATION_TABLE]
|
||||
:end-before: [TARGET_OPTION_OPTIMIZATION_TABLE]
|
||||
|
||||
.. hook-start:TARGET_OPTION_OPTIMIZATION_TABLE
|
||||
|
||||
.. hook-end
|
||||
|
||||
Some machines may desire to change what optimizations are performed for
|
||||
various optimization levels. This variable, if defined, describes
|
||||
@ -211,33 +166,15 @@ any target-specific headers.
|
||||
options are changed via ``#pragma GCC optimize`` or by using the
|
||||
``optimize`` attribute.
|
||||
|
||||
.. function:: void TARGET_OPTION_INIT_STRUCT (struct gcc_options *opts)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_OPTION_INIT_STRUCT]
|
||||
:end-before: [TARGET_OPTION_INIT_STRUCT]
|
||||
|
||||
.. hook-start:TARGET_OPTION_INIT_STRUCT
|
||||
|
||||
Set target-dependent initial values of fields in :samp:`{opts}`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_COMPUTE_MULTILIB]
|
||||
:end-before: [TARGET_COMPUTE_MULTILIB]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: const char * TARGET_COMPUTE_MULTILIB (const struct switchstr *switches, int n_switches, const char *multilib_dir, const char *multilib_defaults, const char *multilib_select, const char *multilib_matches, const char *multilib_exclusions, const char *multilib_reuse)
|
||||
|
||||
.. hook-start:TARGET_COMPUTE_MULTILIB
|
||||
|
||||
Some targets like RISC-V might have complicated multilib reuse rules which
|
||||
are hard to implement with the current multilib scheme. This hook allows
|
||||
targets to override the result from the built-in multilib mechanism.
|
||||
:samp:`{switches}` is the raw option list with :samp:`{n_switches}` items;
|
||||
:samp:`{multilib_dir}` is the multi-lib result which is computed by the built-in
|
||||
multi-lib mechanism;
|
||||
:samp:`{multilib_defaults}` is the default options list for multi-lib;
|
||||
:samp:`{multilib_select}` is the string containing the list of supported
|
||||
multi-libs, and the option checking list.
|
||||
:samp:`{multilib_matches}`, :samp:`{multilib_exclusions}`, and :samp:`{multilib_reuse}`
|
||||
are corresponding to :samp:`{MULTILIB_MATCHES}`, :samp:`{MULTILIB_EXCLUSIONS}`,
|
||||
and :samp:`{MULTILIB_REUSE}`.
|
||||
The default definition does nothing but return :samp:`{multilib_dir}` directly.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: SWITCHABLE_TARGET
|
||||
|
||||
@ -258,16 +195,6 @@ any target-specific headers.
|
||||
Define this macro to 1 if your target needs this facility. The default
|
||||
is 0.
|
||||
|
||||
.. function:: bool TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P (void)
|
||||
|
||||
.. hook-start:TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
|
||||
|
||||
Returns true if the target supports IEEE 754 floating-point exceptions
|
||||
and rounding modes, false otherwise. This is intended to relate to the
|
||||
``float`` and ``double`` types, but not necessarily ``long double``.
|
||||
By default, returns true if the ``adddf3`` instruction pattern is
|
||||
available and false otherwise, on the assumption that hardware floating
|
||||
point supports exceptions and rounding modes but software floating point
|
||||
does not.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P]
|
||||
:end-before: [TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P]
|
||||
|
@ -45,17 +45,10 @@ Here is the basic stack layout.
|
||||
Define this macro if successive arguments to a function occupy decreasing
|
||||
addresses on the stack.
|
||||
|
||||
.. function:: HOST_WIDE_INT TARGET_STARTING_FRAME_OFFSET (void)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_STARTING_FRAME_OFFSET]
|
||||
:end-before: [TARGET_STARTING_FRAME_OFFSET]
|
||||
|
||||
.. hook-start:TARGET_STARTING_FRAME_OFFSET
|
||||
|
||||
This hook returns the offset from the frame pointer to the first local
|
||||
variable slot to be allocated. If ``FRAME_GROWS_DOWNWARD``, it is the
|
||||
offset to *end* of the first slot allocated, otherwise it is the
|
||||
offset to *beginning* of the first slot allocated. The default
|
||||
implementation returns 0.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: STACK_ALIGNMENT_NEEDED
|
||||
|
||||
@ -122,17 +115,10 @@ Here is the basic stack layout.
|
||||
before we can access arbitrary stack frames. You will seldom need to
|
||||
define this macro. The default is to do nothing.
|
||||
|
||||
.. function:: rtx TARGET_BUILTIN_SETJMP_FRAME_VALUE (void)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_BUILTIN_SETJMP_FRAME_VALUE]
|
||||
:end-before: [TARGET_BUILTIN_SETJMP_FRAME_VALUE]
|
||||
|
||||
.. hook-start:TARGET_BUILTIN_SETJMP_FRAME_VALUE
|
||||
|
||||
This target hook should return an rtx that is used to store
|
||||
the address of the current frame into the built in ``setjmp`` buffer.
|
||||
The default value, ``virtual_stack_vars_rtx``, is correct for most
|
||||
machines. One reason you may need to define this target hook is if
|
||||
``hard_frame_pointer_rtx`` is the appropriate value on your machine.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: FRAME_ADDR_RTX (frameaddr)
|
||||
|
||||
@ -200,47 +186,15 @@ Here is the basic stack layout.
|
||||
and advertise when generating dwarf debug information, in absence of
|
||||
an explicit :option:`-gdwarf-version` option on the command line.
|
||||
|
||||
.. function:: void TARGET_DWARF_HANDLE_FRAME_UNSPEC (const char *label, rtx pattern, int index)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_DWARF_HANDLE_FRAME_UNSPEC]
|
||||
:end-before: [TARGET_DWARF_HANDLE_FRAME_UNSPEC]
|
||||
|
||||
.. hook-start:TARGET_DWARF_HANDLE_FRAME_UNSPEC
|
||||
|
||||
This target hook allows the backend to emit frame-related insns that
|
||||
contain UNSPECs or UNSPEC_VOLATILEs. The DWARF 2 call frame debugging
|
||||
info engine will invoke it on insns of the form
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_DWARF_POLY_INDETERMINATE_VALUE]
|
||||
:end-before: [TARGET_DWARF_POLY_INDETERMINATE_VALUE]
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
(set (reg) (unspec [...] UNSPEC_INDEX))
|
||||
|
||||
and
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
(set (reg) (unspec_volatile [...] UNSPECV_INDEX)).
|
||||
|
||||
to let the backend emit the call frame instructions. :samp:`{label}` is
|
||||
the CFI label attached to the insn, :samp:`{pattern}` is the pattern of
|
||||
the insn and :samp:`{index}` is ``UNSPEC_INDEX`` or ``UNSPECV_INDEX``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: unsigned int TARGET_DWARF_POLY_INDETERMINATE_VALUE (unsigned int i, unsigned int *factor, int *offset)
|
||||
|
||||
.. hook-start:TARGET_DWARF_POLY_INDETERMINATE_VALUE
|
||||
|
||||
Express the value of ``poly_int`` indeterminate :samp:`{i}` as a DWARF
|
||||
expression, with :samp:`{i}` counting from 1. Return the number of a DWARF
|
||||
register :samp:`{R}` and set :samp:`*{factor}` and :samp:`*{offset}` such
|
||||
that the value of the indeterminate is:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
value_of(R) / factor - offset
|
||||
|
||||
A target only needs to define this hook if it sets
|
||||
:samp:`NUM_POLY_INT_COEFFS` to a value greater than 1.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: INCOMING_FRAME_SP_OFFSET
|
||||
|
||||
|
@ -12,34 +12,10 @@ Eliminating Frame Pointer and Arg Pointer
|
||||
|
||||
This is about eliminating the frame pointer and arg pointer.
|
||||
|
||||
.. function:: bool TARGET_FRAME_POINTER_REQUIRED (void)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FRAME_POINTER_REQUIRED]
|
||||
:end-before: [TARGET_FRAME_POINTER_REQUIRED]
|
||||
|
||||
.. hook-start:TARGET_FRAME_POINTER_REQUIRED
|
||||
|
||||
This target hook should return ``true`` if a function must have and use
|
||||
a frame pointer. This target hook is called in the reload pass. If its return
|
||||
value is ``true`` the function will have a frame pointer.
|
||||
|
||||
This target hook can in principle examine the current function and decide
|
||||
according to the facts, but on most machines the constant ``false`` or the
|
||||
constant ``true`` suffices. Use ``false`` when the machine allows code
|
||||
to be generated with no frame pointer, and doing so saves some time or space.
|
||||
Use ``true`` when there is no possible advantage to avoiding a frame
|
||||
pointer.
|
||||
|
||||
In certain cases, the compiler does not know how to produce valid code
|
||||
without a frame pointer. The compiler recognizes those cases and
|
||||
automatically gives the function a frame pointer regardless of what
|
||||
``targetm.frame_pointer_required`` returns. You don't need to worry about
|
||||
them.
|
||||
|
||||
In a function that does not require a frame pointer, the frame pointer
|
||||
register can be allocated for ordinary usage, unless you mark it as a
|
||||
fixed register. See ``FIXED_REGISTERS`` for more information.
|
||||
|
||||
Default return value is ``false``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ELIMINABLE_REGS
|
||||
|
||||
@ -67,19 +43,10 @@ This is about eliminating the frame pointer and arg pointer.
|
||||
Note that the elimination of the argument pointer with the stack pointer is
|
||||
specified first since that is the preferred elimination.
|
||||
|
||||
.. function:: bool TARGET_CAN_ELIMINATE (const int from_reg, const int to_reg)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_CAN_ELIMINATE]
|
||||
:end-before: [TARGET_CAN_ELIMINATE]
|
||||
|
||||
.. hook-start:TARGET_CAN_ELIMINATE
|
||||
|
||||
This target hook should return ``true`` if the compiler is allowed to
|
||||
try to replace register number :samp:`{from_reg}` with register number
|
||||
:samp:`{to_reg}`. This target hook will usually be ``true``, since most of the
|
||||
cases preventing register elimination are things that the compiler already
|
||||
knows about.
|
||||
|
||||
Default return value is ``true``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: INITIAL_ELIMINATION_OFFSET (from_reg, to_reg, offset_var)
|
||||
|
||||
@ -88,15 +55,6 @@ This is about eliminating the frame pointer and arg pointer.
|
||||
such as the result of ``get_frame_size ()`` and the tables of
|
||||
registers ``df_regs_ever_live_p`` and ``call_used_regs``.
|
||||
|
||||
.. function:: void TARGET_COMPUTE_FRAME_LAYOUT (void)
|
||||
|
||||
.. hook-start:TARGET_COMPUTE_FRAME_LAYOUT
|
||||
|
||||
This target hook is called once each time the frame layout needs to be
|
||||
recalculated. The calculations can be cached by the target and can then
|
||||
be used by ``INITIAL_ELIMINATION_OFFSET`` instead of re-computing the
|
||||
layout on every invocation of that hook. This is particularly useful
|
||||
for targets that have an expensive frame layout function. Implementing
|
||||
this callback is optional.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_COMPUTE_FRAME_LAYOUT]
|
||||
:end-before: [TARGET_COMPUTE_FRAME_LAYOUT]
|
||||
|
@ -13,142 +13,30 @@ Function Entry and Exit
|
||||
This section describes the macros that output function entry
|
||||
(:dfn:`prologue`) and exit (:dfn:`epilogue`) code.
|
||||
|
||||
.. function:: void TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY (FILE *file, unsigned HOST_WIDE_INT patch_area_size, bool record_p)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY]
|
||||
:end-before: [TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY]
|
||||
|
||||
.. hook-start:TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
|
||||
|
||||
Generate a patchable area at the function start, consisting of
|
||||
:samp:`{patch_area_size}` NOP instructions. If the target supports named
|
||||
sections and if :samp:`{record_p}` is true, insert a pointer to the current
|
||||
location in the table of patchable functions. The default implementation
|
||||
of the hook places the table of pointers in the special section named
|
||||
``__patchable_function_entries``.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FUNCTION_PROLOGUE]
|
||||
:end-before: [TARGET_ASM_FUNCTION_PROLOGUE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_FUNCTION_PROLOGUE (FILE *file)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FUNCTION_END_PROLOGUE]
|
||||
:end-before: [TARGET_ASM_FUNCTION_END_PROLOGUE]
|
||||
|
||||
.. hook-start:TARGET_ASM_FUNCTION_PROLOGUE
|
||||
|
||||
If defined, a function that outputs the assembler code for entry to a
|
||||
function. The prologue is responsible for setting up the stack frame,
|
||||
initializing the frame pointer register, saving registers that must be
|
||||
saved, and allocating :samp:`{size}` additional bytes of storage for the
|
||||
local variables. :samp:`{file}` is a stdio stream to which the assembler
|
||||
code should be output.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FUNCTION_BEGIN_EPILOGUE]
|
||||
:end-before: [TARGET_ASM_FUNCTION_BEGIN_EPILOGUE]
|
||||
|
||||
The label for the beginning of the function need not be output by this
|
||||
macro. That has already been done when the macro is run.
|
||||
|
||||
.. index:: regs_ever_live
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_FUNCTION_EPILOGUE]
|
||||
:end-before: [TARGET_ASM_FUNCTION_EPILOGUE]
|
||||
|
||||
To determine which registers to save, the macro can refer to the array
|
||||
``regs_ever_live`` : element :samp:`{r}` is nonzero if hard register
|
||||
:samp:`{r}` is used anywhere within the function. This implies the function
|
||||
prologue should save register :samp:`{r}`, provided it is not one of the
|
||||
call-used registers. (``TARGET_ASM_FUNCTION_EPILOGUE`` must likewise use
|
||||
``regs_ever_live``.)
|
||||
|
||||
On machines that have 'register windows', the function entry code does
|
||||
not save on the stack the registers that are in the windows, even if
|
||||
they are supposed to be preserved by function calls; instead it takes
|
||||
appropriate steps to 'push' the register stack, if any non-call-used
|
||||
registers are used in the function.
|
||||
|
||||
.. index:: frame_pointer_needed
|
||||
|
||||
On machines where functions may or may not have frame-pointers, the
|
||||
function entry code must vary accordingly; it must set up the frame
|
||||
pointer if one is wanted, and not otherwise. To determine whether a
|
||||
frame pointer is in wanted, the macro can refer to the variable
|
||||
``frame_pointer_needed``. The variable's value will be 1 at run
|
||||
time in a function that needs a frame pointer. See :ref:`elimination`.
|
||||
|
||||
The function entry code is responsible for allocating any stack space
|
||||
required for the function. This stack space consists of the regions
|
||||
listed below. In most cases, these regions are allocated in the
|
||||
order listed, with the last listed region closest to the top of the
|
||||
stack (the lowest address if ``STACK_GROWS_DOWNWARD`` is defined, and
|
||||
the highest address if it is not defined). You can use a different order
|
||||
for a machine if doing so is more convenient or required for
|
||||
compatibility reasons. Except in cases where required by standard
|
||||
or by a debugger, there is no reason why the stack layout used by GCC
|
||||
need agree with that used by other compilers for a machine.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_FUNCTION_END_PROLOGUE (FILE *file)
|
||||
|
||||
.. hook-start:TARGET_ASM_FUNCTION_END_PROLOGUE
|
||||
|
||||
If defined, a function that outputs assembler code at the end of a
|
||||
prologue. This should be used when the function prologue is being
|
||||
emitted as RTL, and you have some extra assembler that needs to be
|
||||
emitted. See :ref:`prologue-instruction-pattern`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_FUNCTION_BEGIN_EPILOGUE (FILE *file)
|
||||
|
||||
.. hook-start:TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
|
||||
|
||||
If defined, a function that outputs assembler code at the start of an
|
||||
epilogue. This should be used when the function epilogue is being
|
||||
emitted as RTL, and you have some extra assembler that needs to be
|
||||
emitted. See :ref:`epilogue-instruction-pattern`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_ASM_FUNCTION_EPILOGUE (FILE *file)
|
||||
|
||||
.. hook-start:TARGET_ASM_FUNCTION_EPILOGUE
|
||||
|
||||
If defined, a function that outputs the assembler code for exit from a
|
||||
function. The epilogue is responsible for restoring the saved
|
||||
registers and stack pointer to their values when the function was
|
||||
called, and returning control to the caller. This macro takes the
|
||||
same argument as the macro ``TARGET_ASM_FUNCTION_PROLOGUE``, and the
|
||||
registers to restore are determined from ``regs_ever_live`` and
|
||||
``CALL_USED_REGISTERS`` in the same way.
|
||||
|
||||
On some machines, there is a single instruction that does all the work
|
||||
of returning from the function. On these machines, give that
|
||||
instruction the name :samp:`return` and do not define the macro
|
||||
``TARGET_ASM_FUNCTION_EPILOGUE`` at all.
|
||||
|
||||
Do not define a pattern named :samp:`return` if you want the
|
||||
``TARGET_ASM_FUNCTION_EPILOGUE`` to be used. If you want the target
|
||||
switches to control whether return instructions or epilogues are used,
|
||||
define a :samp:`return` pattern with a validity condition that tests the
|
||||
target switches appropriately. If the :samp:`return` pattern's validity
|
||||
condition is false, epilogues will be used.
|
||||
|
||||
On machines where functions may or may not have frame-pointers, the
|
||||
function exit code must vary accordingly. Sometimes the code for these
|
||||
two cases is completely different. To determine whether a frame pointer
|
||||
is wanted, the macro can refer to the variable
|
||||
``frame_pointer_needed``. The variable's value will be 1 when compiling
|
||||
a function that needs a frame pointer.
|
||||
|
||||
Normally, ``TARGET_ASM_FUNCTION_PROLOGUE`` and
|
||||
``TARGET_ASM_FUNCTION_EPILOGUE`` must treat leaf functions specially.
|
||||
The C variable ``current_function_is_leaf`` is nonzero for such a
|
||||
function. See :ref:`leaf-functions`.
|
||||
|
||||
On some machines, some functions pop their arguments on exit while
|
||||
others leave that for the caller to do. For example, the 68020 when
|
||||
given :option:`-mrtd` pops arguments in functions that take a fixed
|
||||
number of arguments.
|
||||
|
||||
.. index:: pops_args, crtl->args.pops_args
|
||||
|
||||
Your definition of the macro ``RETURN_POPS_ARGS`` decides which
|
||||
functions pop their own arguments. ``TARGET_ASM_FUNCTION_EPILOGUE``
|
||||
needs to know what was decided. The number of bytes of the current
|
||||
function's arguments that this function should pop is available in
|
||||
``crtl->args.pops_args``. See :ref:`scalar-return`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
*
|
||||
.. index:: pretend_args_size, crtl->args.pretend_args_size
|
||||
@ -206,60 +94,11 @@ This section describes the macros that output function entry
|
||||
used by the exception handling mechanism, and so should be considered live
|
||||
on entry to an exception edge.
|
||||
|
||||
.. function:: void TARGET_ASM_OUTPUT_MI_THUNK (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, tree function)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_OUTPUT_MI_THUNK]
|
||||
:end-before: [TARGET_ASM_OUTPUT_MI_THUNK]
|
||||
|
||||
.. hook-start:TARGET_ASM_OUTPUT_MI_THUNK
|
||||
|
||||
A function that outputs the assembler code for a thunk
|
||||
function, used to implement C++ virtual function calls with multiple
|
||||
inheritance. The thunk acts as a wrapper around a virtual function,
|
||||
adjusting the implicit object parameter before handing control off to
|
||||
the real function.
|
||||
|
||||
First, emit code to add the integer :samp:`{delta}` to the location that
|
||||
contains the incoming first argument. Assume that this argument
|
||||
contains a pointer, and is the one used to pass the ``this`` pointer
|
||||
in C++. This is the incoming argument *before* the function prologue,
|
||||
e.g. :samp:`%o0` on a sparc. The addition must preserve the values of
|
||||
all other incoming arguments.
|
||||
|
||||
Then, if :samp:`{vcall_offset}` is nonzero, an additional adjustment should be
|
||||
made after adding ``delta``. In particular, if :samp:`{p}` is the
|
||||
adjusted pointer, the following adjustment should be made:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
p += (*((ptrdiff_t **)p))[vcall_offset/sizeof(ptrdiff_t)]
|
||||
|
||||
After the additions, emit code to jump to :samp:`{function}`, which is a
|
||||
``FUNCTION_DECL``. This is a direct pure jump, not a call, and does
|
||||
not touch the return address. Hence returning from :samp:`{FUNCTION}` will
|
||||
return to whoever called the current :samp:`thunk`.
|
||||
|
||||
The effect must be as if :samp:`{function}` had been called directly with
|
||||
the adjusted first argument. This macro is responsible for emitting all
|
||||
of the code for a thunk function; ``TARGET_ASM_FUNCTION_PROLOGUE``
|
||||
and ``TARGET_ASM_FUNCTION_EPILOGUE`` are not invoked.
|
||||
|
||||
The :samp:`{thunk_fndecl}` is redundant. (:samp:`{delta}` and :samp:`{function}`
|
||||
have already been extracted from it.) It might possibly be useful on
|
||||
some targets, but probably not.
|
||||
|
||||
If you do not define this macro, the target-independent code in the C++
|
||||
front end will generate a less efficient heavyweight thunk that calls
|
||||
:samp:`{function}` instead of jumping to it. The generic approach does
|
||||
not support varargs.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ASM_CAN_OUTPUT_MI_THUNK (const_tree thunk_fndecl, HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, const_tree function)
|
||||
|
||||
.. hook-start:TARGET_ASM_CAN_OUTPUT_MI_THUNK
|
||||
|
||||
A function that returns true if TARGET_ASM_OUTPUT_MI_THUNK would be able
|
||||
to output the assembler code for the thunk function specified by the
|
||||
arguments it is passed, and false otherwise. In the latter case, the
|
||||
generic approach will be used by the C++ front end, with the limitations
|
||||
previously exposed.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ASM_CAN_OUTPUT_MI_THUNK]
|
||||
:end-before: [TARGET_ASM_CAN_OUTPUT_MI_THUNK]
|
||||
|
@ -48,14 +48,6 @@ These macros will help you generate code for profiling.
|
||||
Define this macro if the code for function profiling should come before
|
||||
the function prologue. Normally, the profiling code comes after.
|
||||
|
||||
.. function:: bool TARGET_KEEP_LEAF_WHEN_PROFILED (void)
|
||||
|
||||
.. hook-start:TARGET_KEEP_LEAF_WHEN_PROFILED
|
||||
|
||||
This target hook returns true if the target wants the leaf flag for
|
||||
the current function to stay true even if it calls mcount. This might
|
||||
make sense for targets using the leaf flag only to determine whether a
|
||||
stack frame needs to be generated or not and for which the call to
|
||||
mcount is generated before the function prologue.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_KEEP_LEAF_WHEN_PROFILED]
|
||||
:end-before: [TARGET_KEEP_LEAF_WHEN_PROFILED]
|
||||
|
@ -20,28 +20,10 @@ address`.
|
||||
This section describes how to control returning structure values in
|
||||
memory.
|
||||
|
||||
.. function:: bool TARGET_RETURN_IN_MEMORY (const_tree type, const_tree fntype)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_RETURN_IN_MEMORY]
|
||||
:end-before: [TARGET_RETURN_IN_MEMORY]
|
||||
|
||||
.. hook-start:TARGET_RETURN_IN_MEMORY
|
||||
|
||||
This target hook should return a nonzero value to say to return the
|
||||
function value in memory, just as large structures are always returned.
|
||||
Here :samp:`{type}` will be the data type of the value, and :samp:`{fntype}`
|
||||
will be the type of the function doing the returning, or ``NULL`` for
|
||||
libcalls.
|
||||
|
||||
Note that values of mode ``BLKmode`` must be explicitly handled
|
||||
by this function. Also, the option :option:`-fpcc-struct-return`
|
||||
takes effect regardless of this macro. On most systems, it is
|
||||
possible to leave the hook undefined; this causes a default
|
||||
definition to be used, whose value is the constant 1 for ``BLKmode``
|
||||
values, and 0 otherwise.
|
||||
|
||||
Do not use this hook to indicate that structures and unions should always
|
||||
be returned in memory. You should instead use ``DEFAULT_PCC_STRUCT_RETURN``
|
||||
to indicate this.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: DEFAULT_PCC_STRUCT_RETURN
|
||||
|
||||
@ -54,32 +36,10 @@ memory.
|
||||
|
||||
If not defined, this defaults to the value 1.
|
||||
|
||||
.. function:: rtx TARGET_STRUCT_VALUE_RTX (tree fndecl, int incoming)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_STRUCT_VALUE_RTX]
|
||||
:end-before: [TARGET_STRUCT_VALUE_RTX]
|
||||
|
||||
.. hook-start:TARGET_STRUCT_VALUE_RTX
|
||||
|
||||
This target hook should return the location of the structure value
|
||||
address (normally a ``mem`` or ``reg``), or 0 if the address is
|
||||
passed as an 'invisible' first argument. Note that :samp:`{fndecl}` may
|
||||
be ``NULL``, for libcalls. You do not need to define this target
|
||||
hook if the address is always passed as an 'invisible' first
|
||||
argument.
|
||||
|
||||
On some architectures the place where the structure value address
|
||||
is found by the called function is not the same place that the
|
||||
caller put it. This can be due to register windows, or it could
|
||||
be because the function prologue moves it to a different place.
|
||||
:samp:`{incoming}` is ``1`` or ``2`` when the location is needed in
|
||||
the context of the called function, and ``0`` in the context of
|
||||
the caller.
|
||||
|
||||
If :samp:`{incoming}` is nonzero and the address is to be found on the
|
||||
stack, return a ``mem`` which refers to the frame pointer. If
|
||||
:samp:`{incoming}` is ``2``, the result is being used to fetch the
|
||||
structure value address at the beginning of a function. If you need
|
||||
to emit adjusting code, you should do it at this point.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: PCC_STATIC_STRUCT_RETURN
|
||||
|
||||
@ -93,40 +53,21 @@ memory.
|
||||
This macro has effect in :option:`-fpcc-struct-return` mode, but it does
|
||||
nothing when you use :option:`-freg-struct-return` mode.
|
||||
|
||||
.. function:: fixed_size_mode TARGET_GET_RAW_RESULT_MODE (int regno)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_GET_RAW_RESULT_MODE]
|
||||
:end-before: [TARGET_GET_RAW_RESULT_MODE]
|
||||
|
||||
.. hook-start:TARGET_GET_RAW_RESULT_MODE
|
||||
|
||||
This target hook returns the mode to be used when accessing raw return
|
||||
registers in ``__builtin_return``. Define this macro if the value
|
||||
in :samp:`{reg_raw_mode}` is not correct.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_GET_RAW_ARG_MODE]
|
||||
:end-before: [TARGET_GET_RAW_ARG_MODE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: fixed_size_mode TARGET_GET_RAW_ARG_MODE (int regno)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_EMPTY_RECORD_P]
|
||||
:end-before: [TARGET_EMPTY_RECORD_P]
|
||||
|
||||
.. hook-start:TARGET_GET_RAW_ARG_MODE
|
||||
|
||||
This target hook returns the mode to be used when accessing raw argument
|
||||
registers in ``__builtin_apply_args``. Define this macro if the value
|
||||
in :samp:`{reg_raw_mode}` is not correct.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_EMPTY_RECORD_P (const_tree type)
|
||||
|
||||
.. hook-start:TARGET_EMPTY_RECORD_P
|
||||
|
||||
This target hook returns true if the type is an empty record. The default
|
||||
is to return ``false``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_WARN_PARAMETER_PASSING_ABI (cumulative_args_t ca, tree type)
|
||||
|
||||
.. hook-start:TARGET_WARN_PARAMETER_PASSING_ABI
|
||||
|
||||
This target hook warns about the change in empty class parameter passing
|
||||
ABI.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_WARN_PARAMETER_PASSING_ABI]
|
||||
:end-before: [TARGET_WARN_PARAMETER_PASSING_ABI]
|
||||
|
@ -13,52 +13,10 @@ How Scalar Function Values Are Returned
|
||||
This section discusses the macros that control returning scalars as
|
||||
values---values that can fit in registers.
|
||||
|
||||
.. function:: rtx TARGET_FUNCTION_VALUE (const_tree ret_type, const_tree fn_decl_or_type, bool outgoing)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_VALUE]
|
||||
:end-before: [TARGET_FUNCTION_VALUE]
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_VALUE
|
||||
|
||||
Define this to return an RTX representing the place where a function
|
||||
returns or receives a value of data type :samp:`{ret_type}`, a tree node
|
||||
representing a data type. :samp:`{fn_decl_or_type}` is a tree node
|
||||
representing ``FUNCTION_DECL`` or ``FUNCTION_TYPE`` of a
|
||||
function being called. If :samp:`{outgoing}` is false, the hook should
|
||||
compute the register in which the caller will see the return value.
|
||||
Otherwise, the hook should return an RTX representing the place where
|
||||
a function returns a value.
|
||||
|
||||
On many machines, only ``TYPE_MODE (ret_type)`` is relevant.
|
||||
(Actually, on most machines, scalar values are returned in the same
|
||||
place regardless of mode.) The value of the expression is usually a
|
||||
``reg`` RTX for the hard register where the return value is stored.
|
||||
The value can also be a ``parallel`` RTX, if the return value is in
|
||||
multiple places. See ``TARGET_FUNCTION_ARG`` for an explanation of the
|
||||
``parallel`` form. Note that the callee will populate every
|
||||
location specified in the ``parallel``, but if the first element of
|
||||
the ``parallel`` contains the whole return value, callers will use
|
||||
that element as the canonical location and ignore the others. The m68k
|
||||
port uses this type of ``parallel`` to return pointers in both
|
||||
:samp:`%a0` (the canonical location) and :samp:`%d0`.
|
||||
|
||||
If ``TARGET_PROMOTE_FUNCTION_RETURN`` returns true, you must apply
|
||||
the same promotion rules specified in ``PROMOTE_MODE`` if
|
||||
:samp:`{valtype}` is a scalar type.
|
||||
|
||||
If the precise function being called is known, :samp:`{func}` is a tree
|
||||
node (``FUNCTION_DECL``) for it; otherwise, :samp:`{func}` is a null
|
||||
pointer. This makes it possible to use a different value-returning
|
||||
convention for specific functions when all their calls are
|
||||
known.
|
||||
|
||||
Some target machines have 'register windows' so that the register in
|
||||
which a function returns its value is not the same as the one in which
|
||||
the caller sees the value. For such machines, you should return
|
||||
different RTX depending on :samp:`{outgoing}`.
|
||||
|
||||
``TARGET_FUNCTION_VALUE`` is not used for return values with
|
||||
aggregate data types, because these are returned in another way. See
|
||||
``TARGET_STRUCT_VALUE_RTX`` and related macros, below.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: FUNCTION_VALUE (valtype, func)
|
||||
|
||||
@ -75,20 +33,10 @@ values---values that can fit in registers.
|
||||
specially by the compiler and was not mentioned in the C code being
|
||||
compiled.
|
||||
|
||||
.. function:: rtx TARGET_LIBCALL_VALUE (machine_mode mode, const_rtx fun)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_LIBCALL_VALUE]
|
||||
:end-before: [TARGET_LIBCALL_VALUE]
|
||||
|
||||
.. hook-start:TARGET_LIBCALL_VALUE
|
||||
|
||||
Define this hook if the back-end needs to know the name of the libcall
|
||||
function in order to determine where the result should be returned.
|
||||
|
||||
The mode of the result is given by :samp:`{mode}` and the name of the called
|
||||
library function is given by :samp:`{fun}`. The hook should return an RTX
|
||||
representing the place where the library function result will be returned.
|
||||
|
||||
If this hook is not defined, then LIBCALL_VALUE will be used.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: FUNCTION_VALUE_REGNO_P (regno)
|
||||
|
||||
@ -111,24 +59,10 @@ values---values that can fit in registers.
|
||||
This macro has been deprecated. Use ``TARGET_FUNCTION_VALUE_REGNO_P``
|
||||
for a new target instead.
|
||||
|
||||
.. function:: bool TARGET_FUNCTION_VALUE_REGNO_P (const unsigned int regno)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_VALUE_REGNO_P]
|
||||
:end-before: [TARGET_FUNCTION_VALUE_REGNO_P]
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_VALUE_REGNO_P
|
||||
|
||||
A target hook that return ``true`` if :samp:`{regno}` is the number of a hard
|
||||
register in which the values of called function may come back.
|
||||
|
||||
A register whose use for returning values is limited to serving as the
|
||||
second of a pair (for a value of type ``double``, say) need not be
|
||||
recognized by this target hook.
|
||||
|
||||
If the machine has register windows, so that the caller and the called
|
||||
function use different registers for the return value, this target hook
|
||||
should recognize only the caller's register numbers.
|
||||
|
||||
If this hook is not defined, then FUNCTION_VALUE_REGNO_P will be used.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: APPLY_RESULT_SIZE
|
||||
|
||||
@ -136,31 +70,11 @@ values---values that can fit in registers.
|
||||
need more space than is implied by ``FUNCTION_VALUE_REGNO_P`` for
|
||||
saving and restoring an arbitrary return value.
|
||||
|
||||
.. c:var:: bool TARGET_OMIT_STRUCT_RETURN_REG
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_OMIT_STRUCT_RETURN_REG]
|
||||
:end-before: [TARGET_OMIT_STRUCT_RETURN_REG]
|
||||
|
||||
.. hook-start:TARGET_OMIT_STRUCT_RETURN_REG
|
||||
|
||||
Normally, when a function returns a structure by memory, the address
|
||||
is passed as an invisible pointer argument, but the compiler also
|
||||
arranges to return the address from the function like it would a normal
|
||||
pointer return value. Define this to true if that behavior is
|
||||
undesirable on your target.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_RETURN_IN_MSB (const_tree type)
|
||||
|
||||
.. hook-start:TARGET_RETURN_IN_MSB
|
||||
|
||||
This hook should return true if values of type :samp:`{type}` are returned
|
||||
at the most significant end of a register (in other words, if they are
|
||||
padded at the least significant end). You can assume that :samp:`{type}`
|
||||
is returned in a register; the caller is required to check this.
|
||||
|
||||
Note that the register provided by ``TARGET_FUNCTION_VALUE`` must
|
||||
be able to hold the complete return value. For example, if a 1-, 2-
|
||||
or 3-byte structure is returned at the most significant end of a
|
||||
4-byte register, ``TARGET_FUNCTION_VALUE`` should provide an
|
||||
``SImode`` rtx.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_RETURN_IN_MSB]
|
||||
:end-before: [TARGET_RETURN_IN_MSB]
|
||||
|
@ -10,17 +10,6 @@
|
||||
Miscellaneous register hooks
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. c:var:: bool TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
|
||||
|
||||
.. hook-start:TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
|
||||
|
||||
Set to true if each call that binds to a local definition explicitly
|
||||
clobbers or sets all non-fixed registers modified by performing the call.
|
||||
That is, by the call pattern itself, or by code that might be inserted by the
|
||||
linker (e.g. stubs, veneers, branch islands), but not including those
|
||||
modifiable by the callee. The affected registers may be mentioned explicitly
|
||||
in the call pattern, or included as clobbers in CALL_INSN_FUNCTION_USAGE.
|
||||
The default version of this hook is set to false. The purpose of this hook
|
||||
is to enable the fipa-ra optimization.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS]
|
||||
:end-before: [TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS]
|
||||
|
@ -14,164 +14,45 @@ This section describes the macros which let you control how various
|
||||
types of arguments are passed in registers or how they are arranged in
|
||||
the stack.
|
||||
|
||||
.. function:: rtx TARGET_FUNCTION_ARG (cumulative_args_t ca, const function_arg_info &arg)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_ARG]
|
||||
:end-before: [TARGET_FUNCTION_ARG]
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_ARG
|
||||
|
||||
Return an RTX indicating whether function argument :samp:`{arg}` is passed
|
||||
in a register and if so, which register. Argument :samp:`{ca}` summarizes all
|
||||
the previous arguments.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_MUST_PASS_IN_STACK]
|
||||
:end-before: [TARGET_MUST_PASS_IN_STACK]
|
||||
|
||||
The return value is usually either a ``reg`` RTX for the hard
|
||||
register in which to pass the argument, or zero to pass the argument
|
||||
on the stack.
|
||||
|
||||
The value of the expression can also be a ``parallel`` RTX. This is
|
||||
used when an argument is passed in multiple locations. The mode of the
|
||||
``parallel`` should be the mode of the entire argument. The
|
||||
``parallel`` holds any number of ``expr_list`` pairs; each one
|
||||
describes where part of the argument is passed. In each
|
||||
``expr_list`` the first operand must be a ``reg`` RTX for the hard
|
||||
register in which to pass this part of the argument, and the mode of the
|
||||
register RTX indicates how large this part of the argument is. The
|
||||
second operand of the ``expr_list`` is a ``const_int`` which gives
|
||||
the offset in bytes into the entire argument of where this part starts.
|
||||
As a special exception the first ``expr_list`` in the ``parallel``
|
||||
RTX may have a first operand of zero. This indicates that the entire
|
||||
argument is also stored on the stack.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_INCOMING_ARG]
|
||||
:end-before: [TARGET_FUNCTION_INCOMING_ARG]
|
||||
|
||||
The last time this hook is called, it is called with ``MODE ==
|
||||
VOIDmode``, and its result is passed to the ``call`` or ``call_value``
|
||||
pattern as operands 2 and 3 respectively.
|
||||
|
||||
.. index:: stdarg.h and register arguments
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_USE_PSEUDO_PIC_REG]
|
||||
:end-before: [TARGET_USE_PSEUDO_PIC_REG]
|
||||
|
||||
The usual way to make the ISO library :samp:`stdarg.h` work on a
|
||||
machine where some arguments are usually passed in registers, is to
|
||||
cause nameless arguments to be passed on the stack instead. This is
|
||||
done by making ``TARGET_FUNCTION_ARG`` return 0 whenever
|
||||
:samp:`{named}` is ``false``.
|
||||
|
||||
.. index:: TARGET_MUST_PASS_IN_STACK, and TARGET_FUNCTION_ARG, REG_PARM_STACK_SPACE, and TARGET_FUNCTION_ARG
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_INIT_PIC_REG]
|
||||
:end-before: [TARGET_INIT_PIC_REG]
|
||||
|
||||
You may use the hook ``targetm.calls.must_pass_in_stack``
|
||||
in the definition of this macro to determine if this argument is of a
|
||||
type that must be passed in the stack. If ``REG_PARM_STACK_SPACE``
|
||||
is not defined and ``TARGET_FUNCTION_ARG`` returns nonzero for such an
|
||||
argument, the compiler will abort. If ``REG_PARM_STACK_SPACE`` is
|
||||
defined, the argument will be computed in the stack and then loaded into
|
||||
a register.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ARG_PARTIAL_BYTES]
|
||||
:end-before: [TARGET_ARG_PARTIAL_BYTES]
|
||||
|
||||
.. function:: bool TARGET_MUST_PASS_IN_STACK (const function_arg_info &arg)
|
||||
|
||||
.. hook-start:TARGET_MUST_PASS_IN_STACK
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_PASS_BY_REFERENCE]
|
||||
:end-before: [TARGET_PASS_BY_REFERENCE]
|
||||
|
||||
This target hook should return ``true`` if we should not pass :samp:`{arg}`
|
||||
solely in registers. The file :samp:`expr.h` defines a
|
||||
definition that is usually appropriate, refer to :samp:`expr.h` for additional
|
||||
documentation.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_CALLEE_COPIES]
|
||||
:end-before: [TARGET_CALLEE_COPIES]
|
||||
|
||||
.. function:: rtx TARGET_FUNCTION_INCOMING_ARG (cumulative_args_t ca, const function_arg_info &arg)
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_INCOMING_ARG
|
||||
|
||||
Define this hook if the caller and callee on the target have different
|
||||
views of where arguments are passed. Also define this hook if there are
|
||||
functions that are never directly called, but are invoked by the hardware
|
||||
and which have nonstandard calling conventions.
|
||||
|
||||
In this case ``TARGET_FUNCTION_ARG`` computes the register in
|
||||
which the caller passes the value, and
|
||||
``TARGET_FUNCTION_INCOMING_ARG`` should be defined in a similar
|
||||
fashion to tell the function being called where the arguments will
|
||||
arrive.
|
||||
|
||||
``TARGET_FUNCTION_INCOMING_ARG`` can also return arbitrary address
|
||||
computation using hard register, which can be forced into a register,
|
||||
so that it can be used to pass special arguments.
|
||||
|
||||
If ``TARGET_FUNCTION_INCOMING_ARG`` is not defined,
|
||||
``TARGET_FUNCTION_ARG`` serves both purposes.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_USE_PSEUDO_PIC_REG (void)
|
||||
|
||||
.. hook-start:TARGET_USE_PSEUDO_PIC_REG
|
||||
|
||||
This hook should return 1 in case pseudo register should be created
|
||||
for pic_offset_table_rtx during function expand.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_INIT_PIC_REG (void)
|
||||
|
||||
.. hook-start:TARGET_INIT_PIC_REG
|
||||
|
||||
Perform a target dependent initialization of pic_offset_table_rtx.
|
||||
This hook is called at the start of register allocation.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: int TARGET_ARG_PARTIAL_BYTES (cumulative_args_t cum, const function_arg_info &arg)
|
||||
|
||||
.. hook-start:TARGET_ARG_PARTIAL_BYTES
|
||||
|
||||
This target hook returns the number of bytes at the beginning of an
|
||||
argument that must be put in registers. The value must be zero for
|
||||
arguments that are passed entirely in registers or that are entirely
|
||||
pushed on the stack.
|
||||
|
||||
On some machines, certain arguments must be passed partially in
|
||||
registers and partially in memory. On these machines, typically the
|
||||
first few words of arguments are passed in registers, and the rest
|
||||
on the stack. If a multi-word argument (a ``double`` or a
|
||||
structure) crosses that boundary, its first few words must be passed
|
||||
in registers and the rest must be pushed. This macro tells the
|
||||
compiler when this occurs, and how many bytes should go in registers.
|
||||
|
||||
``TARGET_FUNCTION_ARG`` for these arguments should return the first
|
||||
register to be used by the caller for this argument; likewise
|
||||
``TARGET_FUNCTION_INCOMING_ARG``, for the called function.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_PASS_BY_REFERENCE (cumulative_args_t cum, const function_arg_info &arg)
|
||||
|
||||
.. hook-start:TARGET_PASS_BY_REFERENCE
|
||||
|
||||
This target hook should return ``true`` if argument :samp:`{arg}` at the
|
||||
position indicated by :samp:`{cum}` should be passed by reference. This
|
||||
predicate is queried after target independent reasons for being
|
||||
passed by reference, such as ``TREE_ADDRESSABLE (arg.type)``.
|
||||
|
||||
If the hook returns true, a copy of that argument is made in memory and a
|
||||
pointer to the argument is passed instead of the argument itself.
|
||||
The pointer is passed in whatever way is appropriate for passing a pointer
|
||||
to that type.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_CALLEE_COPIES (cumulative_args_t cum, const function_arg_info &arg)
|
||||
|
||||
.. hook-start:TARGET_CALLEE_COPIES
|
||||
|
||||
The function argument described by the parameters to this hook is
|
||||
known to be passed by reference. The hook should return true if the
|
||||
function argument should be copied by the callee instead of copied
|
||||
by the caller.
|
||||
|
||||
For any argument for which the hook returns true, if it can be
|
||||
determined that the argument is not modified, then a copy need
|
||||
not be generated.
|
||||
|
||||
The default version of this hook always returns false.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: CUMULATIVE_ARGS
|
||||
|
||||
@ -241,52 +122,20 @@ the stack.
|
||||
|
||||
.. -mew 5feb93 i switched the order of the sentences. -mew 10feb93
|
||||
|
||||
.. function:: void TARGET_FUNCTION_ARG_ADVANCE (cumulative_args_t ca, const function_arg_info &arg)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_ARG_ADVANCE]
|
||||
:end-before: [TARGET_FUNCTION_ARG_ADVANCE]
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_ARG_ADVANCE
|
||||
|
||||
This hook updates the summarizer variable pointed to by :samp:`{ca}` to
|
||||
advance past argument :samp:`{arg}` in the argument list. Once this is done,
|
||||
the variable :samp:`{cum}` is suitable for analyzing the *following*
|
||||
argument with ``TARGET_FUNCTION_ARG``, etc.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_ARG_OFFSET]
|
||||
:end-before: [TARGET_FUNCTION_ARG_OFFSET]
|
||||
|
||||
This hook need not do anything if the argument in question was passed
|
||||
on the stack. The compiler knows how to track the amount of stack space
|
||||
used for arguments without any special help.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_ARG_PADDING]
|
||||
:end-before: [TARGET_FUNCTION_ARG_PADDING]
|
||||
|
||||
.. function:: HOST_WIDE_INT TARGET_FUNCTION_ARG_OFFSET (machine_mode mode, const_tree type)
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_ARG_OFFSET
|
||||
|
||||
This hook returns the number of bytes to add to the offset of an
|
||||
argument of type :samp:`{type}` and mode :samp:`{mode}` when passed in memory.
|
||||
This is needed for the SPU, which passes ``char`` and ``short``
|
||||
arguments in the preferred slot that is in the middle of the quad word
|
||||
instead of starting at the top. The default implementation returns 0.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: pad_direction TARGET_FUNCTION_ARG_PADDING (machine_mode mode, const_tree type)
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_ARG_PADDING
|
||||
|
||||
This hook determines whether, and in which direction, to pad out
|
||||
an argument of mode :samp:`{mode}` and type :samp:`{type}`. It returns
|
||||
``PAD_UPWARD`` to insert padding above the argument, ``PAD_DOWNWARD``
|
||||
to insert padding below the argument, or ``PAD_NONE`` to inhibit padding.
|
||||
|
||||
The *amount* of padding is not controlled by this hook, but by
|
||||
``TARGET_FUNCTION_ARG_ROUND_BOUNDARY``. It is always just enough
|
||||
to reach the next multiple of that boundary.
|
||||
|
||||
This hook has a default definition that is right for most systems.
|
||||
For little-endian machines, the default is to pad upward. For
|
||||
big-endian machines, the default is to pad downward for an argument of
|
||||
constant size shorter than an ``int``, and upward otherwise.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: PAD_VARARGS_DOWN
|
||||
|
||||
@ -307,26 +156,15 @@ the stack.
|
||||
a three byte aggregate may be passed in the high part of a register if so
|
||||
required.
|
||||
|
||||
.. function:: unsigned int TARGET_FUNCTION_ARG_BOUNDARY (machine_mode mode, const_tree type)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_ARG_BOUNDARY]
|
||||
:end-before: [TARGET_FUNCTION_ARG_BOUNDARY]
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_ARG_BOUNDARY
|
||||
|
||||
This hook returns the alignment boundary, in bits, of an argument
|
||||
with the specified mode and type. The default hook returns
|
||||
``PARM_BOUNDARY`` for all arguments.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_ARG_ROUND_BOUNDARY]
|
||||
:end-before: [TARGET_FUNCTION_ARG_ROUND_BOUNDARY]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: unsigned int TARGET_FUNCTION_ARG_ROUND_BOUNDARY (machine_mode mode, const_tree type)
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_ARG_ROUND_BOUNDARY
|
||||
|
||||
Normally, the size of an argument is rounded up to ``PARM_BOUNDARY``,
|
||||
which is the default value for this hook. You can define this hook to
|
||||
return a different value if an argument size must be rounded to a larger
|
||||
value.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: FUNCTION_ARG_REGNO_P (regno)
|
||||
|
||||
@ -337,297 +175,91 @@ the stack.
|
||||
used for this purpose since all function arguments are pushed on the
|
||||
stack.
|
||||
|
||||
.. function:: bool TARGET_SPLIT_COMPLEX_ARG (const_tree type)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SPLIT_COMPLEX_ARG]
|
||||
:end-before: [TARGET_SPLIT_COMPLEX_ARG]
|
||||
|
||||
.. hook-start:TARGET_SPLIT_COMPLEX_ARG
|
||||
|
||||
This hook should return true if parameter of type :samp:`{type}` are passed
|
||||
as two scalar parameters. By default, GCC will attempt to pack complex
|
||||
arguments into the target's word size. Some ABIs require complex arguments
|
||||
to be split and treated as their individual components. For example, on
|
||||
AIX64, complex floats should be passed in a pair of floating point
|
||||
registers, even though a complex float would fit in one 64-bit floating
|
||||
point register.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_BUILD_BUILTIN_VA_LIST]
|
||||
:end-before: [TARGET_BUILD_BUILTIN_VA_LIST]
|
||||
|
||||
The default value of this hook is ``NULL``, which is treated as always
|
||||
false.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ENUM_VA_LIST_P]
|
||||
:end-before: [TARGET_ENUM_VA_LIST_P]
|
||||
|
||||
.. function:: tree TARGET_BUILD_BUILTIN_VA_LIST (void)
|
||||
|
||||
.. hook-start:TARGET_BUILD_BUILTIN_VA_LIST
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FN_ABI_VA_LIST]
|
||||
:end-before: [TARGET_FN_ABI_VA_LIST]
|
||||
|
||||
This hook returns a type node for ``va_list`` for the target.
|
||||
The default version of the hook returns ``void*``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_CANONICAL_VA_LIST_TYPE]
|
||||
:end-before: [TARGET_CANONICAL_VA_LIST_TYPE]
|
||||
|
||||
.. function:: int TARGET_ENUM_VA_LIST_P (int idx, const char **pname, tree *ptree)
|
||||
|
||||
.. hook-start:TARGET_ENUM_VA_LIST_P
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_GIMPLIFY_VA_ARG_EXPR]
|
||||
:end-before: [TARGET_GIMPLIFY_VA_ARG_EXPR]
|
||||
|
||||
This target hook is used in function ``c_common_nodes_and_builtins``
|
||||
to iterate through the target specific builtin types for va_list. The
|
||||
variable :samp:`{idx}` is used as iterator. :samp:`{pname}` has to be a pointer
|
||||
to a ``const char *`` and :samp:`{ptree}` a pointer to a ``tree`` typed
|
||||
variable.
|
||||
The arguments :samp:`{pname}` and :samp:`{ptree}` are used to store the result of
|
||||
this macro and are set to the name of the va_list builtin type and its
|
||||
internal type.
|
||||
If the return value of this macro is zero, then there is no more element.
|
||||
Otherwise the :samp:`{IDX}` should be increased for the next call of this
|
||||
macro to iterate through all types.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_VALID_POINTER_MODE]
|
||||
:end-before: [TARGET_VALID_POINTER_MODE]
|
||||
|
||||
.. function:: tree TARGET_FN_ABI_VA_LIST (tree fndecl)
|
||||
|
||||
.. hook-start:TARGET_FN_ABI_VA_LIST
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_REF_MAY_ALIAS_ERRNO]
|
||||
:end-before: [TARGET_REF_MAY_ALIAS_ERRNO]
|
||||
|
||||
This hook returns the va_list type of the calling convention specified by
|
||||
:samp:`{fndecl}`.
|
||||
The default version of this hook returns ``va_list_type_node``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_TRANSLATE_MODE_ATTRIBUTE]
|
||||
:end-before: [TARGET_TRANSLATE_MODE_ATTRIBUTE]
|
||||
|
||||
.. function:: tree TARGET_CANONICAL_VA_LIST_TYPE (tree type)
|
||||
|
||||
.. hook-start:TARGET_CANONICAL_VA_LIST_TYPE
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SCALAR_MODE_SUPPORTED_P]
|
||||
:end-before: [TARGET_SCALAR_MODE_SUPPORTED_P]
|
||||
|
||||
This hook returns the va_list type of the calling convention specified by the
|
||||
type of :samp:`{type}`. If :samp:`{type}` is not a valid va_list type, it returns
|
||||
``NULL_TREE``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_VECTOR_MODE_SUPPORTED_P]
|
||||
:end-before: [TARGET_VECTOR_MODE_SUPPORTED_P]
|
||||
|
||||
.. function:: tree TARGET_GIMPLIFY_VA_ARG_EXPR (tree valist, tree type, gimple_seq *pre_p, gimple_seq *post_p)
|
||||
|
||||
.. hook-start:TARGET_GIMPLIFY_VA_ARG_EXPR
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_COMPATIBLE_VECTOR_TYPES_P]
|
||||
:end-before: [TARGET_COMPATIBLE_VECTOR_TYPES_P]
|
||||
|
||||
This hook performs target-specific gimplification of
|
||||
``VA_ARG_EXPR``. The first two parameters correspond to the
|
||||
arguments to ``va_arg`` ; the latter two are as in
|
||||
``gimplify.cc:gimplify_expr``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ARRAY_MODE]
|
||||
:end-before: [TARGET_ARRAY_MODE]
|
||||
|
||||
.. function:: bool TARGET_VALID_POINTER_MODE (scalar_int_mode mode)
|
||||
|
||||
.. hook-start:TARGET_VALID_POINTER_MODE
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_ARRAY_MODE_SUPPORTED_P]
|
||||
:end-before: [TARGET_ARRAY_MODE_SUPPORTED_P]
|
||||
|
||||
Define this to return nonzero if the port can handle pointers
|
||||
with machine mode :samp:`{mode}`. The default version of this
|
||||
hook returns true for both ``ptr_mode`` and ``Pmode``.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P]
|
||||
:end-before: [TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P]
|
||||
|
||||
.. function:: bool TARGET_REF_MAY_ALIAS_ERRNO (ao_ref *ref)
|
||||
|
||||
.. hook-start:TARGET_REF_MAY_ALIAS_ERRNO
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FLOATN_MODE]
|
||||
:end-before: [TARGET_FLOATN_MODE]
|
||||
|
||||
Define this to return nonzero if the memory reference :samp:`{ref}`
|
||||
may alias with the system C library errno location. The default
|
||||
version of this hook assumes the system C library errno location
|
||||
is either a declaration of type int or accessed by dereferencing
|
||||
a pointer to int.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FLOATN_BUILTIN_P]
|
||||
:end-before: [TARGET_FLOATN_BUILTIN_P]
|
||||
|
||||
.. function:: machine_mode TARGET_TRANSLATE_MODE_ATTRIBUTE (machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_TRANSLATE_MODE_ATTRIBUTE
|
||||
|
||||
Define this hook if during mode attribute processing, the port should
|
||||
translate machine_mode :samp:`{mode}` to another mode. For example, rs6000's
|
||||
``KFmode``, when it is the same as ``TFmode``.
|
||||
|
||||
The default version of the hook returns that mode that was passed in.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SCALAR_MODE_SUPPORTED_P (scalar_mode mode)
|
||||
|
||||
.. hook-start:TARGET_SCALAR_MODE_SUPPORTED_P
|
||||
|
||||
Define this to return nonzero if the port is prepared to handle
|
||||
insns involving scalar mode :samp:`{mode}`. For a scalar mode to be
|
||||
considered supported, all the basic arithmetic and comparisons
|
||||
must work.
|
||||
|
||||
The default version of this hook returns true for any mode
|
||||
required to handle the basic C types (as defined by the port).
|
||||
Included here are the double-word arithmetic supported by the
|
||||
code in :samp:`optabs.cc`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_VECTOR_MODE_SUPPORTED_P (machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_VECTOR_MODE_SUPPORTED_P
|
||||
|
||||
Define this to return nonzero if the port is prepared to handle
|
||||
insns involving vector mode :samp:`{mode}`. At the very least, it
|
||||
must have move patterns for this mode.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_COMPATIBLE_VECTOR_TYPES_P (const_tree type1, const_tree type2)
|
||||
|
||||
.. hook-start:TARGET_COMPATIBLE_VECTOR_TYPES_P
|
||||
|
||||
Return true if there is no target-specific reason for treating
|
||||
vector types :samp:`{type1}` and :samp:`{type2}` as distinct types. The caller
|
||||
has already checked for target-independent reasons, meaning that the
|
||||
types are known to have the same mode, to have the same number of elements,
|
||||
and to have what the caller considers to be compatible element types.
|
||||
|
||||
The main reason for defining this hook is to reject pairs of types
|
||||
that are handled differently by the target's calling convention.
|
||||
For example, when a new :samp:`{N}` -bit vector architecture is added
|
||||
to a target, the target may want to handle normal :samp:`{N}` -bit
|
||||
``VECTOR_TYPE`` arguments and return values in the same way as
|
||||
before, to maintain backwards compatibility. However, it may also
|
||||
provide new, architecture-specific ``VECTOR_TYPE`` s that are passed
|
||||
and returned in a more efficient way. It is then important to maintain
|
||||
a distinction between the 'normal' ``VECTOR_TYPE`` s and the new
|
||||
architecture-specific ones.
|
||||
|
||||
The default implementation returns true, which is correct for most targets.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: opt_machine_mode TARGET_ARRAY_MODE (machine_mode mode, unsigned HOST_WIDE_INT nelems)
|
||||
|
||||
.. hook-start:TARGET_ARRAY_MODE
|
||||
|
||||
Return the mode that GCC should use for an array that has
|
||||
:samp:`{nelems}` elements, with each element having mode :samp:`{mode}`.
|
||||
Return no mode if the target has no special requirements. In the
|
||||
latter case, GCC looks for an integer mode of the appropriate size
|
||||
if available and uses BLKmode otherwise. Usually the search for the
|
||||
integer mode is limited to ``MAX_FIXED_MODE_SIZE``, but the
|
||||
``TARGET_ARRAY_MODE_SUPPORTED_P`` hook allows a larger mode to be
|
||||
used in specific cases.
|
||||
|
||||
The main use of this hook is to specify that an array of vectors should
|
||||
also have a vector mode. The default implementation returns no mode.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_ARRAY_MODE_SUPPORTED_P (machine_mode mode, unsigned HOST_WIDE_INT nelems)
|
||||
|
||||
.. hook-start:TARGET_ARRAY_MODE_SUPPORTED_P
|
||||
|
||||
Return true if GCC should try to use a scalar mode to store an array
|
||||
of :samp:`{nelems}` elements, given that each element has mode :samp:`{mode}`.
|
||||
Returning true here overrides the usual ``MAX_FIXED_MODE`` limit
|
||||
and allows GCC to use any defined integer mode.
|
||||
|
||||
One use of this hook is to support vector load and store operations
|
||||
that operate on several homogeneous vectors. For example, ARM NEON
|
||||
has operations like:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
int8x8x3_t vld3_s8 (const int8_t *)
|
||||
|
||||
where the return type is defined as:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
typedef struct int8x8x3_t
|
||||
{
|
||||
int8x8_t val[3];
|
||||
} int8x8x3_t;
|
||||
|
||||
If this hook allows ``val`` to have a scalar mode, then
|
||||
``int8x8x3_t`` can have the same mode. GCC can then store
|
||||
``int8x8x3_t`` s in registers rather than forcing them onto the stack.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P (scalar_float_mode mode)
|
||||
|
||||
.. hook-start:TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
|
||||
|
||||
Define this to return nonzero if libgcc provides support for the
|
||||
floating-point mode :samp:`{mode}`, which is known to pass
|
||||
``TARGET_SCALAR_MODE_SUPPORTED_P``. The default version of this
|
||||
hook returns true for all of ``SFmode``, ``DFmode``,
|
||||
``XFmode`` and ``TFmode``, if such modes exist.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: opt_scalar_float_mode TARGET_FLOATN_MODE (int n, bool extended)
|
||||
|
||||
.. hook-start:TARGET_FLOATN_MODE
|
||||
|
||||
Define this to return the machine mode to use for the type
|
||||
``_Floatn``, if :samp:`{extended}` is false, or the type
|
||||
``_Floatnx``, if :samp:`{extended}` is true. If such a type is not
|
||||
supported, return ``opt_scalar_float_mode ()``. The default version of
|
||||
this hook returns ``SFmode`` for ``_Float32``, ``DFmode`` for
|
||||
``_Float64`` and ``_Float32x`` and ``TFmode`` for
|
||||
``_Float128``, if those modes exist and satisfy the requirements for
|
||||
those types and pass ``TARGET_SCALAR_MODE_SUPPORTED_P`` and
|
||||
``TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P`` ; for ``_Float64x``, it
|
||||
returns the first of ``XFmode`` and ``TFmode`` that exists and
|
||||
satisfies the same requirements; for other types, it returns
|
||||
``opt_scalar_float_mode ()``. The hook is only called for values
|
||||
of :samp:`{n}` and :samp:`{extended}` that are valid according to
|
||||
ISO/IEC TS 18661-3:2015; that is, :samp:`{n}` is one of 32, 64, 128, or,
|
||||
if :samp:`{extended}` is false, 16 or greater than 128 and a multiple of 32.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_FLOATN_BUILTIN_P (int func)
|
||||
|
||||
.. hook-start:TARGET_FLOATN_BUILTIN_P
|
||||
|
||||
Define this to return true if the ``_Floatn`` and
|
||||
``_Floatnx`` built-in functions should implicitly enable the
|
||||
built-in function without the ``__builtin_`` prefix in addition to the
|
||||
normal built-in function with the ``__builtin_`` prefix. The default is
|
||||
to only enable built-in functions without the ``__builtin_`` prefix for
|
||||
the GNU C langauge. In strict ANSI/ISO mode, the built-in function without
|
||||
the ``__builtin_`` prefix is not enabled. The argument ``FUNC`` is the
|
||||
``enum built_in_function`` id of the function to be enabled.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P (machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
|
||||
|
||||
Define this to return nonzero for machine modes for which the port has
|
||||
small register classes. If this target hook returns nonzero for a given
|
||||
:samp:`{mode}`, the compiler will try to minimize the lifetime of registers
|
||||
in :samp:`{mode}`. The hook may be called with ``VOIDmode`` as argument.
|
||||
In this case, the hook is expected to return nonzero if it returns nonzero
|
||||
for any mode.
|
||||
|
||||
On some machines, it is risky to let hard registers live across arbitrary
|
||||
insns. Typically, these machines have instructions that require values
|
||||
to be in specific registers (like an accumulator), and reload will fail
|
||||
if the required hard register is used for another purpose across such an
|
||||
insn.
|
||||
|
||||
Passes before reload do not know which hard registers will be used
|
||||
in an instruction, but the machine modes of the registers set or used in
|
||||
the instruction are already known. And for some machines, register
|
||||
classes are small for, say, integer registers but not for floating point
|
||||
registers. For example, the AMD x86-64 architecture requires specific
|
||||
registers for the legacy x86 integer instructions, but there are many
|
||||
SSE registers for floating point operations. On such targets, a good
|
||||
strategy may be to return nonzero from this hook for ``INTEGRAL_MODE_P``
|
||||
machine modes but zero for the SSE register classes.
|
||||
|
||||
The default version of this hook returns false for any mode. It is always
|
||||
safe to redefine this hook to return with a nonzero value. But if you
|
||||
unnecessarily define it, you will reduce the amount of optimizations
|
||||
that can be performed in some cases. If you do not define this hook
|
||||
to return a nonzero value when it is required, the compiler will run out
|
||||
of spill registers and print a fatal error message.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P]
|
||||
:end-before: [TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P]
|
||||
|
@ -14,33 +14,15 @@ The macros in this section control how arguments are passed
|
||||
on the stack. See the following section for other macros that
|
||||
control passing certain arguments in registers.
|
||||
|
||||
.. function:: bool TARGET_PROMOTE_PROTOTYPES (const_tree fntype)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_PROMOTE_PROTOTYPES]
|
||||
:end-before: [TARGET_PROMOTE_PROTOTYPES]
|
||||
|
||||
.. hook-start:TARGET_PROMOTE_PROTOTYPES
|
||||
|
||||
This target hook returns ``true`` if an argument declared in a
|
||||
prototype as an integral type smaller than ``int`` should actually be
|
||||
passed as an ``int``. In addition to avoiding errors in certain
|
||||
cases of mismatch, it also makes for better code on certain machines.
|
||||
The default is to not promote prototypes.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_PUSH_ARGUMENT]
|
||||
:end-before: [TARGET_PUSH_ARGUMENT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_PUSH_ARGUMENT (unsigned int npush)
|
||||
|
||||
.. hook-start:TARGET_PUSH_ARGUMENT
|
||||
|
||||
This target hook returns ``true`` if push instructions will be
|
||||
used to pass outgoing arguments. When the push instruction usage is
|
||||
optional, :samp:`{npush}` is nonzero to indicate the number of bytes to
|
||||
push. Otherwise, :samp:`{npush}` is zero. If the target machine does not
|
||||
have a push instruction or push instruction should be avoided,
|
||||
``false`` should be returned. That directs GCC to use an alternate
|
||||
strategy: to allocate the entire argument block and then store the
|
||||
arguments into it. If this target hook may return ``true``,
|
||||
``PUSH_ROUNDING`` must be defined.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: PUSH_ARGS_REVERSED
|
||||
|
||||
@ -135,47 +117,10 @@ control passing certain arguments in registers.
|
||||
suppresses this behavior and causes the parameter to be passed on the
|
||||
stack in its natural location.
|
||||
|
||||
.. function:: poly_int64 TARGET_RETURN_POPS_ARGS (tree fundecl, tree funtype, poly_int64 size)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_RETURN_POPS_ARGS]
|
||||
:end-before: [TARGET_RETURN_POPS_ARGS]
|
||||
|
||||
.. hook-start:TARGET_RETURN_POPS_ARGS
|
||||
|
||||
This target hook returns the number of bytes of its own arguments that
|
||||
a function pops on returning, or 0 if the function pops no arguments
|
||||
and the caller must therefore pop them all after the function returns.
|
||||
|
||||
:samp:`{fundecl}` is a C variable whose value is a tree node that describes
|
||||
the function in question. Normally it is a node of type
|
||||
``FUNCTION_DECL`` that describes the declaration of the function.
|
||||
From this you can obtain the ``DECL_ATTRIBUTES`` of the function.
|
||||
|
||||
:samp:`{funtype}` is a C variable whose value is a tree node that
|
||||
describes the function in question. Normally it is a node of type
|
||||
``FUNCTION_TYPE`` that describes the data type of the function.
|
||||
From this it is possible to obtain the data types of the value and
|
||||
arguments (if known).
|
||||
|
||||
When a call to a library function is being considered, :samp:`{fundecl}`
|
||||
will contain an identifier node for the library function. Thus, if
|
||||
you need to distinguish among various library functions, you can do so
|
||||
by their names. Note that 'library function' in this context means
|
||||
a function used to perform arithmetic, whose name is known specially
|
||||
in the compiler and was not mentioned in the C code being compiled.
|
||||
|
||||
:samp:`{size}` is the number of bytes of arguments passed on the
|
||||
stack. If a variable number of bytes is passed, it is zero, and
|
||||
argument popping will always be the responsibility of the calling function.
|
||||
|
||||
On the VAX, all functions always pop their arguments, so the definition
|
||||
of this macro is :samp:`{size}`. On the 68000, using the standard
|
||||
calling convention, no functions pop their arguments, so the value of
|
||||
the macro is always 0 in this case. But an alternative calling
|
||||
convention is available in which functions that take a fixed number of
|
||||
arguments pop them but other functions (such as ``printf``) pop
|
||||
nothing (the caller pops all). When this convention is in use,
|
||||
:samp:`{funtype}` is examined to determine whether a function takes a fixed
|
||||
number of arguments.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: CALL_POPS_ARGS (cum)
|
||||
|
||||
|
@ -10,51 +10,21 @@
|
||||
Permitting tail calls
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. function:: bool TARGET_FUNCTION_OK_FOR_SIBCALL (tree decl, tree exp)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_FUNCTION_OK_FOR_SIBCALL]
|
||||
:end-before: [TARGET_FUNCTION_OK_FOR_SIBCALL]
|
||||
|
||||
.. hook-start:TARGET_FUNCTION_OK_FOR_SIBCALL
|
||||
|
||||
True if it is OK to do sibling call optimization for the specified
|
||||
call expression :samp:`{exp}`. :samp:`{decl}` will be the called function,
|
||||
or ``NULL`` if this is an indirect call.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_EXTRA_LIVE_ON_ENTRY]
|
||||
:end-before: [TARGET_EXTRA_LIVE_ON_ENTRY]
|
||||
|
||||
It is not uncommon for limitations of calling conventions to prevent
|
||||
tail calls to functions outside the current unit of translation, or
|
||||
during PIC compilation. The hook is used to enforce these restrictions,
|
||||
as the ``sibcall`` md pattern cannot fail, or fall over to a
|
||||
'normal' call. The criteria for successful sibling call optimization
|
||||
may vary greatly between different architectures.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SET_UP_BY_PROLOGUE]
|
||||
:end-before: [TARGET_SET_UP_BY_PROLOGUE]
|
||||
|
||||
.. function:: void TARGET_EXTRA_LIVE_ON_ENTRY (bitmap regs)
|
||||
|
||||
.. hook-start:TARGET_EXTRA_LIVE_ON_ENTRY
|
||||
|
||||
Add any hard registers to :samp:`{regs}` that are live on entry to the
|
||||
function. This hook only needs to be defined to provide registers that
|
||||
cannot be found by examination of FUNCTION_ARG_REGNO_P, the callee saved
|
||||
registers, STATIC_CHAIN_INCOMING_REGNUM, STATIC_CHAIN_REGNUM,
|
||||
TARGET_STRUCT_VALUE_RTX, FRAME_POINTER_REGNUM, EH_USES,
|
||||
FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SET_UP_BY_PROLOGUE (struct hard_reg_set_container *)
|
||||
|
||||
.. hook-start:TARGET_SET_UP_BY_PROLOGUE
|
||||
|
||||
This hook should add additional registers that are computed by the prologue
|
||||
to the hard regset for shrink-wrapping optimization purposes.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_WARN_FUNC_RETURN (tree)
|
||||
|
||||
.. hook-start:TARGET_WARN_FUNC_RETURN
|
||||
|
||||
True if a function's return statements should be checked for matching
|
||||
the function's return type. This includes checking for falling off the end
|
||||
of a non-void function. Return false if no such check should be made.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_WARN_FUNC_RETURN]
|
||||
:end-before: [TARGET_WARN_FUNC_RETURN]
|
||||
|
@ -102,31 +102,10 @@ This discusses registers that address the stack frame.
|
||||
If the static chain is passed in memory, these macros should not be
|
||||
defined; instead, the ``TARGET_STATIC_CHAIN`` hook should be used.
|
||||
|
||||
.. function:: rtx TARGET_STATIC_CHAIN (const_tree fndecl_or_type, bool incoming_p)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_STATIC_CHAIN]
|
||||
:end-before: [TARGET_STATIC_CHAIN]
|
||||
|
||||
.. hook-start:TARGET_STATIC_CHAIN
|
||||
|
||||
This hook replaces the use of ``STATIC_CHAIN_REGNUM`` et al for
|
||||
targets that may use different static chain locations for different
|
||||
nested functions. This may be required if the target has function
|
||||
attributes that affect the calling conventions of the function and
|
||||
those calling conventions use different static chain locations.
|
||||
|
||||
The default version of this hook uses ``STATIC_CHAIN_REGNUM`` et al.
|
||||
|
||||
If the static chain is passed in memory, this hook should be used to
|
||||
provide rtx giving ``mem`` expressions that denote where they are stored.
|
||||
Often the ``mem`` expression as seen by the caller will be at an offset
|
||||
from the stack pointer and the ``mem`` expression as seen by the callee
|
||||
will be at an offset from the frame pointer.
|
||||
|
||||
.. index:: stack_pointer_rtx, frame_pointer_rtx, arg_pointer_rtx
|
||||
|
||||
The variables ``stack_pointer_rtx``, ``frame_pointer_rtx``, and
|
||||
``arg_pointer_rtx`` will have been initialized and should be used
|
||||
to refer to those items.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: DWARF_FRAME_REGISTERS
|
||||
|
||||
|
@ -31,63 +31,31 @@ code treats them abstractly, as a bit in an ``sbitmap``. These
|
||||
and ``shrink_wrap.components_for_bb`` hooks, and deallocated by the
|
||||
generic code.
|
||||
|
||||
.. function:: sbitmap TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS (void)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS]
|
||||
:end-before: [TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS]
|
||||
|
||||
.. hook-start:TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
|
||||
|
||||
This hook should return an ``sbitmap`` with the bits set for those
|
||||
components that can be separately shrink-wrapped in the current function.
|
||||
Return ``NULL`` if the current function should not get any separate
|
||||
shrink-wrapping.
|
||||
Don't define this hook if it would always return ``NULL``.
|
||||
If it is defined, the other hooks in this group have to be defined as well.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB]
|
||||
:end-before: [TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: sbitmap TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB (basic_block)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS]
|
||||
:end-before: [TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS]
|
||||
|
||||
.. hook-start:TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
|
||||
|
||||
This hook should return an ``sbitmap`` with the bits set for those
|
||||
components where either the prologue component has to be executed before
|
||||
the ``basic_block``, or the epilogue component after it, or both.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS]
|
||||
:end-before: [TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS (sbitmap components, edge e, sbitmap edge_components, bool is_prologue)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS]
|
||||
:end-before: [TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS]
|
||||
|
||||
.. hook-start:TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
|
||||
|
||||
This hook should clear the bits in the :samp:`{components}` bitmap for those
|
||||
components in :samp:`{edge_components}` that the target cannot handle on edge
|
||||
:samp:`{e}`, where :samp:`{is_prologue}` says if this is for a prologue or an
|
||||
epilogue instead.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS (sbitmap)
|
||||
|
||||
.. hook-start:TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
|
||||
|
||||
Emit prologue insns for the components indicated by the parameter.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS (sbitmap)
|
||||
|
||||
.. hook-start:TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
|
||||
|
||||
Emit epilogue insns for the components indicated by the parameter.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS (sbitmap)
|
||||
|
||||
.. hook-start:TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
|
||||
|
||||
Mark the components in the parameter as handled, so that the
|
||||
``prologue`` and ``epilogue`` named patterns know to ignore those
|
||||
components. The target code should not hang on to the ``sbitmap``, it
|
||||
will be deleted after this call.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS]
|
||||
:end-before: [TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS]
|
||||
|
@ -102,17 +102,6 @@ in the opposite case.
|
||||
GCC computed the default from the values of the above macros and you will
|
||||
normally not need to override that default.
|
||||
|
||||
.. function:: HOST_WIDE_INT TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE (void)
|
||||
|
||||
.. hook-start:TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE
|
||||
|
||||
Some targets have an ABI defined interval for which no probing needs to be done.
|
||||
When a probe does need to be done this same interval is used as the probe distance
|
||||
up when doing stack clash protection for alloca.
|
||||
On such targets this value can be set to override the default probing up interval.
|
||||
Define this variable to return nonzero if such a probe range is required or zero otherwise.
|
||||
Defining this hook also requires your functions which make use of alloca to have at least 8 byes
|
||||
of outgoing arguments. If this is not the case the stack will be corrupted.
|
||||
You need not define this macro if it would always have the value zero.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE]
|
||||
:end-before: [TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE]
|
||||
|
@ -10,66 +10,26 @@
|
||||
Stack smashing protection
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. function:: tree TARGET_STACK_PROTECT_GUARD (void)
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_STACK_PROTECT_GUARD]
|
||||
:end-before: [TARGET_STACK_PROTECT_GUARD]
|
||||
|
||||
.. hook-start:TARGET_STACK_PROTECT_GUARD
|
||||
|
||||
This hook returns a ``DECL`` node for the external variable to use
|
||||
for the stack protection guard. This variable is initialized by the
|
||||
runtime to some random value and is used to initialize the guard value
|
||||
that is placed at the top of the local stack frame. The type of this
|
||||
variable must be ``ptr_type_node``.
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_STACK_PROTECT_FAIL]
|
||||
:end-before: [TARGET_STACK_PROTECT_FAIL]
|
||||
|
||||
The default version of this hook creates a variable called
|
||||
:samp:`__stack_chk_guard`, which is normally defined in :samp:`libgcc2.c`.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_STACK_PROTECT_RUNTIME_ENABLED_P]
|
||||
:end-before: [TARGET_STACK_PROTECT_RUNTIME_ENABLED_P]
|
||||
|
||||
.. function:: tree TARGET_STACK_PROTECT_FAIL (void)
|
||||
|
||||
.. hook-start:TARGET_STACK_PROTECT_FAIL
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_SUPPORTS_SPLIT_STACK]
|
||||
:end-before: [TARGET_SUPPORTS_SPLIT_STACK]
|
||||
|
||||
This hook returns a ``CALL_EXPR`` that alerts the runtime that the
|
||||
stack protect guard variable has been modified. This expression should
|
||||
involve a call to a ``noreturn`` function.
|
||||
|
||||
The default version of this hook invokes a function called
|
||||
:samp:`__stack_chk_fail`, taking no arguments. This function is
|
||||
normally defined in :samp:`libgcc2.c`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_STACK_PROTECT_RUNTIME_ENABLED_P (void)
|
||||
|
||||
.. hook-start:TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
|
||||
|
||||
Returns true if the target wants GCC's default stack protect runtime support,
|
||||
otherwise return false. The default implementation always returns true.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_SUPPORTS_SPLIT_STACK (bool report, struct gcc_options *opts)
|
||||
|
||||
.. hook-start:TARGET_SUPPORTS_SPLIT_STACK
|
||||
|
||||
Whether this target supports splitting the stack when the options
|
||||
described in :samp:`{opts}` have been passed. This is called
|
||||
after options have been parsed, so the target may reject splitting
|
||||
the stack in some configurations. The default version of this hook
|
||||
returns false. If :samp:`{report}` is true, this function may issue a warning
|
||||
or error; if :samp:`{report}` is false, it must simply return a value
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: vec<const char *> TARGET_GET_VALID_OPTION_VALUES (int option_code, const char *prefix)
|
||||
|
||||
.. hook-start:TARGET_GET_VALID_OPTION_VALUES
|
||||
|
||||
The hook is used for options that have a non-trivial list of
|
||||
possible option values. OPTION_CODE is option code of opt_code
|
||||
enum type. PREFIX is used for bash completion and allows an implementation
|
||||
to return more specific completion based on the prefix. All string values
|
||||
should be allocated from heap memory and consumers should release them.
|
||||
The result will be pruned to cases with PREFIX if not NULL.
|
||||
|
||||
.. hook-end
|
||||
.. include:: ../tm.rst.in
|
||||
:start-after: [TARGET_GET_VALID_OPTION_VALUES]
|
||||
:end-before: [TARGET_GET_VALID_OPTION_VALUES]
|
||||
|
@ -121,61 +121,15 @@ See :ref:`run-time-target`.
|
||||
|
||||
Do not define this macro if it would never modify :samp:`{m}`.
|
||||
|
||||
.. function:: enum flt_eval_method TARGET_C_EXCESS_PRECISION (enum excess_precision_type type)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_C_EXCESS_PRECISION]
|
||||
:end-before: [TARGET_C_EXCESS_PRECISION]
|
||||
|
||||
.. hook-start:TARGET_C_EXCESS_PRECISION
|
||||
|
||||
Return a value, with the same meaning as the C99 macro
|
||||
``FLT_EVAL_METHOD`` that describes which excess precision should be
|
||||
applied. :samp:`{type}` is either ``EXCESS_PRECISION_TYPE_IMPLICIT``,
|
||||
``EXCESS_PRECISION_TYPE_FAST``,
|
||||
``EXCESS_PRECISION_TYPE_STANDARD``, or
|
||||
``EXCESS_PRECISION_TYPE_FLOAT16``. For
|
||||
``EXCESS_PRECISION_TYPE_IMPLICIT``, the target should return which
|
||||
precision and range operations will be implictly evaluated in regardless
|
||||
of the excess precision explicitly added. For
|
||||
``EXCESS_PRECISION_TYPE_STANDARD``,
|
||||
``EXCESS_PRECISION_TYPE_FLOAT16``, and
|
||||
``EXCESS_PRECISION_TYPE_FAST``, the target should return the
|
||||
explicit excess precision that should be added depending on the
|
||||
value set for :option:`-fexcess-precision=[standard|fast|16]`.
|
||||
Note that unpredictable explicit excess precision does not make sense,
|
||||
so a target should never return ``FLT_EVAL_METHOD_UNPREDICTABLE``
|
||||
when :samp:`{type}` is ``EXCESS_PRECISION_TYPE_STANDARD``,
|
||||
``EXCESS_PRECISION_TYPE_FLOAT16`` or
|
||||
``EXCESS_PRECISION_TYPE_FAST``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_PROMOTE_FUNCTION_MODE]
|
||||
:end-before: [TARGET_PROMOTE_FUNCTION_MODE]
|
||||
|
||||
Return a value, with the same meaning as the C99 macro
|
||||
``FLT_EVAL_METHOD`` that describes which excess precision should be
|
||||
applied.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: machine_mode TARGET_PROMOTE_FUNCTION_MODE (const_tree type, machine_mode mode, int *punsignedp, const_tree funtype, int for_return)
|
||||
|
||||
.. hook-start:TARGET_PROMOTE_FUNCTION_MODE
|
||||
|
||||
Like ``PROMOTE_MODE``, but it is applied to outgoing function arguments or
|
||||
function return values. The target hook should return the new mode
|
||||
and possibly change ``*punsignedp`` if the promotion should
|
||||
change signedness. This function is called only for scalar *or
|
||||
pointer* types.
|
||||
|
||||
:samp:`{for_return}` allows to distinguish the promotion of arguments and
|
||||
return values. If it is ``1``, a return value is being promoted and
|
||||
``TARGET_FUNCTION_VALUE`` must perform the same promotions done here.
|
||||
If it is ``2``, the returned mode should be that of the register in
|
||||
which an incoming parameter is copied, or the outgoing result is computed;
|
||||
then the hook should return the same mode as ``promote_mode``, though
|
||||
the signedness may be different.
|
||||
|
||||
:samp:`{type}` can be NULL when promoting function arguments of libcalls.
|
||||
|
||||
The default is to not promote arguments and return values. You can
|
||||
also define the hook to ``default_promote_function_mode_always_promote``
|
||||
if you would like to apply the same rules given by ``PROMOTE_MODE``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: PARM_BOUNDARY
|
||||
|
||||
@ -216,15 +170,10 @@ applied.
|
||||
bits. Note that this is not the biggest alignment that is supported,
|
||||
just the biggest alignment that, when violated, may cause a fault.
|
||||
|
||||
.. c:var:: HOST_WIDE_INT TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ABSOLUTE_BIGGEST_ALIGNMENT]
|
||||
:end-before: [TARGET_ABSOLUTE_BIGGEST_ALIGNMENT]
|
||||
|
||||
.. hook-start:TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
|
||||
|
||||
If defined, this target hook specifies the absolute biggest alignment
|
||||
that a type or variable can have on this machine, otherwise,
|
||||
``BIGGEST_ALIGNMENT`` is used.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: MALLOC_ABI_ALIGNMENT
|
||||
|
||||
@ -289,25 +238,15 @@ applied.
|
||||
On 32-bit ELF the largest supported section alignment in bits is
|
||||
:samp:`(0x80000000 * 8)`, but this is not representable on 32-bit hosts.
|
||||
|
||||
.. function:: void TARGET_LOWER_LOCAL_DECL_ALIGNMENT (tree decl)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LOWER_LOCAL_DECL_ALIGNMENT]
|
||||
:end-before: [TARGET_LOWER_LOCAL_DECL_ALIGNMENT]
|
||||
|
||||
.. hook-start:TARGET_LOWER_LOCAL_DECL_ALIGNMENT
|
||||
|
||||
Define this hook to lower alignment of local, parm or result
|
||||
decl :samp:`({decl})`.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_STATIC_RTX_ALIGNMENT]
|
||||
:end-before: [TARGET_STATIC_RTX_ALIGNMENT]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: HOST_WIDE_INT TARGET_STATIC_RTX_ALIGNMENT (machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_STATIC_RTX_ALIGNMENT
|
||||
|
||||
This hook returns the preferred alignment in bits for a
|
||||
statically-allocated rtx, such as a constant pool entry. :samp:`{mode}`
|
||||
is the mode of the rtx. The default implementation returns
|
||||
:samp:`GET_MODE_ALIGNMENT ({mode})`.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: DATA_ALIGNMENT (type, basic_align)
|
||||
|
||||
@ -333,22 +272,10 @@ applied.
|
||||
|
||||
If this macro is not defined, then :samp:`{basic_align}` is used.
|
||||
|
||||
.. function:: HOST_WIDE_INT TARGET_CONSTANT_ALIGNMENT (const_tree constant, HOST_WIDE_INT basic_align)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CONSTANT_ALIGNMENT]
|
||||
:end-before: [TARGET_CONSTANT_ALIGNMENT]
|
||||
|
||||
.. hook-start:TARGET_CONSTANT_ALIGNMENT
|
||||
|
||||
This hook returns the alignment in bits of a constant that is being
|
||||
placed in memory. :samp:`{constant}` is the constant and :samp:`{basic_align}`
|
||||
is the alignment that the object would ordinarily have.
|
||||
|
||||
The default definition just returns :samp:`{basic_align}`.
|
||||
|
||||
The typical use of this hook is to increase alignment for string
|
||||
constants to be word aligned so that ``strcpy`` calls that copy
|
||||
constants can be done inline. The function
|
||||
``constant_alignment_word_strings`` provides such a definition.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: LOCAL_ALIGNMENT (type, basic_align)
|
||||
|
||||
@ -364,17 +291,10 @@ applied.
|
||||
|
||||
If the value of this macro has a type, it should be an unsigned type.
|
||||
|
||||
.. function:: HOST_WIDE_INT TARGET_VECTOR_ALIGNMENT (const_tree type)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_VECTOR_ALIGNMENT]
|
||||
:end-before: [TARGET_VECTOR_ALIGNMENT]
|
||||
|
||||
.. hook-start:TARGET_VECTOR_ALIGNMENT
|
||||
|
||||
This hook can be used to define the alignment for a vector of type
|
||||
:samp:`{type}`, in order to comply with a platform ABI. The default is to
|
||||
require natural alignment for vector types. The alignment returned by
|
||||
this hook must be a power-of-two multiple of the default alignment of
|
||||
the vector element type.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: STACK_SLOT_ALIGNMENT (type, mode, basic_align)
|
||||
|
||||
@ -508,44 +428,20 @@ applied.
|
||||
Like ``PCC_BITFIELD_TYPE_MATTERS`` except that its effect is limited
|
||||
to aligning a bit-field within the structure.
|
||||
|
||||
.. function:: bool TARGET_ALIGN_ANON_BITFIELD (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ALIGN_ANON_BITFIELD]
|
||||
:end-before: [TARGET_ALIGN_ANON_BITFIELD]
|
||||
|
||||
.. hook-start:TARGET_ALIGN_ANON_BITFIELD
|
||||
|
||||
When ``PCC_BITFIELD_TYPE_MATTERS`` is true this hook will determine
|
||||
whether unnamed bitfields affect the alignment of the containing
|
||||
structure. The hook should return true if the structure should inherit
|
||||
the alignment requirements of an unnamed bitfield's type.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_NARROW_VOLATILE_BITFIELD]
|
||||
:end-before: [TARGET_NARROW_VOLATILE_BITFIELD]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_NARROW_VOLATILE_BITFIELD (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MEMBER_TYPE_FORCES_BLK]
|
||||
:end-before: [TARGET_MEMBER_TYPE_FORCES_BLK]
|
||||
|
||||
.. hook-start:TARGET_NARROW_VOLATILE_BITFIELD
|
||||
|
||||
This target hook should return ``true`` if accesses to volatile bitfields
|
||||
should use the narrowest mode possible. It should return ``false`` if
|
||||
these accesses should use the bitfield container type.
|
||||
|
||||
The default is ``false``.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_MEMBER_TYPE_FORCES_BLK (const_tree field, machine_mode mode)
|
||||
|
||||
.. hook-start:TARGET_MEMBER_TYPE_FORCES_BLK
|
||||
|
||||
Return true if a structure, union or array containing :samp:`{field}` should
|
||||
be accessed using ``BLKMODE``.
|
||||
|
||||
If :samp:`{field}` is the only field in the structure, :samp:`{mode}` is its
|
||||
mode, otherwise :samp:`{mode}` is VOIDmode. :samp:`{mode}` is provided in the
|
||||
case where structures of one field would require the structure's mode to
|
||||
retain the field's mode.
|
||||
|
||||
Normally, this is not needed.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: ROUND_TYPE_ALIGN (type, computed, specified)
|
||||
|
||||
@ -589,141 +485,46 @@ applied.
|
||||
You would most commonly define this macro if the ``allocate_stack``
|
||||
pattern needs to support both a 32- and a 64-bit mode.
|
||||
|
||||
.. function:: scalar_int_mode TARGET_LIBGCC_CMP_RETURN_MODE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LIBGCC_CMP_RETURN_MODE]
|
||||
:end-before: [TARGET_LIBGCC_CMP_RETURN_MODE]
|
||||
|
||||
.. hook-start:TARGET_LIBGCC_CMP_RETURN_MODE
|
||||
|
||||
This target hook should return the mode to be used for the return value
|
||||
of compare instructions expanded to libgcc calls. If not defined
|
||||
``word_mode`` is returned which is the right choice for a majority of
|
||||
targets.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_LIBGCC_SHIFT_COUNT_MODE]
|
||||
:end-before: [TARGET_LIBGCC_SHIFT_COUNT_MODE]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: scalar_int_mode TARGET_LIBGCC_SHIFT_COUNT_MODE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_UNWIND_WORD_MODE]
|
||||
:end-before: [TARGET_UNWIND_WORD_MODE]
|
||||
|
||||
.. hook-start:TARGET_LIBGCC_SHIFT_COUNT_MODE
|
||||
|
||||
This target hook should return the mode to be used for the shift count operand
|
||||
of shift instructions expanded to libgcc calls. If not defined
|
||||
``word_mode`` is returned which is the right choice for a majority of
|
||||
targets.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MS_BITFIELD_LAYOUT_P]
|
||||
:end-before: [TARGET_MS_BITFIELD_LAYOUT_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: scalar_int_mode TARGET_UNWIND_WORD_MODE (void)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_DECIMAL_FLOAT_SUPPORTED_P]
|
||||
:end-before: [TARGET_DECIMAL_FLOAT_SUPPORTED_P]
|
||||
|
||||
.. hook-start:TARGET_UNWIND_WORD_MODE
|
||||
|
||||
Return machine mode to be used for ``_Unwind_Word`` type.
|
||||
The default is to use ``word_mode``.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_FIXED_POINT_SUPPORTED_P]
|
||||
:end-before: [TARGET_FIXED_POINT_SUPPORTED_P]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_MS_BITFIELD_LAYOUT_P (const_tree record_type)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EXPAND_TO_RTL_HOOK]
|
||||
:end-before: [TARGET_EXPAND_TO_RTL_HOOK]
|
||||
|
||||
.. hook-start:TARGET_MS_BITFIELD_LAYOUT_P
|
||||
|
||||
This target hook returns ``true`` if bit-fields in the given
|
||||
:samp:`{record_type}` are to be laid out following the rules of Microsoft
|
||||
Visual C/C++, namely: (i) a bit-field won't share the same storage
|
||||
unit with the previous bit-field if their underlying types have
|
||||
different sizes, and the bit-field will be aligned to the highest
|
||||
alignment of the underlying types of itself and of the previous
|
||||
bit-field; (ii) a zero-sized bit-field will affect the alignment of
|
||||
the whole enclosing structure, even if it is unnamed; except that
|
||||
(iii) a zero-sized bit-field will be disregarded unless it follows
|
||||
another bit-field of nonzero size. If this hook returns ``true``,
|
||||
other macros that control bit-field layout are ignored.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_INSTANTIATE_DECLS]
|
||||
:end-before: [TARGET_INSTANTIATE_DECLS]
|
||||
|
||||
When a bit-field is inserted into a packed record, the whole size
|
||||
of the underlying type is used by one or more same-size adjacent
|
||||
bit-fields (that is, if its long:3, 32 bits is used in the record,
|
||||
and any additional adjacent long bit-fields are packed into the same
|
||||
chunk of 32 bits. However, if the size changes, a new field of that
|
||||
size is allocated). In an unpacked record, this is the same as using
|
||||
alignment, but not equivalent when packing.
|
||||
|
||||
If both MS bit-fields and :samp:`__attribute__((packed))` are used,
|
||||
the latter will take precedence. If :samp:`__attribute__((packed))` is
|
||||
used on a single field when MS bit-fields are in use, it will take
|
||||
precedence for that field, but the alignment of the rest of the structure
|
||||
may affect its placement.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_DECIMAL_FLOAT_SUPPORTED_P (void)
|
||||
|
||||
.. hook-start:TARGET_DECIMAL_FLOAT_SUPPORTED_P
|
||||
|
||||
Returns true if the target supports decimal floating point.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: bool TARGET_FIXED_POINT_SUPPORTED_P (void)
|
||||
|
||||
.. hook-start:TARGET_FIXED_POINT_SUPPORTED_P
|
||||
|
||||
Returns true if the target supports fixed-point arithmetic.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_EXPAND_TO_RTL_HOOK (void)
|
||||
|
||||
.. hook-start:TARGET_EXPAND_TO_RTL_HOOK
|
||||
|
||||
This hook is called just before expansion into rtl, allowing the target
|
||||
to perform additional initializations or analysis before the expansion.
|
||||
For example, the rs6000 port uses it to allocate a scratch stack slot
|
||||
for use in copying SDmode values between memory and floating point
|
||||
registers whenever the function being expanded has any SDmode
|
||||
usage.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_INSTANTIATE_DECLS (void)
|
||||
|
||||
.. hook-start:TARGET_INSTANTIATE_DECLS
|
||||
|
||||
This hook allows the backend to perform additional instantiations on rtl
|
||||
that are not actually in any insns yet, but will be later.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: const char * TARGET_MANGLE_TYPE (const_tree type)
|
||||
|
||||
.. hook-start:TARGET_MANGLE_TYPE
|
||||
|
||||
If your target defines any fundamental types, or any types your target
|
||||
uses should be mangled differently from the default, define this hook
|
||||
to return the appropriate encoding for these types as part of a C++
|
||||
mangled name. The :samp:`{type}` argument is the tree structure representing
|
||||
the type to be mangled. The hook may be applied to trees which are
|
||||
not target-specific fundamental types; it should return ``NULL``
|
||||
for all such types, as well as arguments it does not recognize. If the
|
||||
return value is not ``NULL``, it must point to a statically-allocated
|
||||
string constant.
|
||||
|
||||
Target-specific fundamental types might be new fundamental types or
|
||||
qualified versions of ordinary fundamental types. Encode new
|
||||
fundamental types as :samp:`u {n}{name}`, where :samp:`{name}`
|
||||
is the name used for the type in source code, and :samp:`{n}` is the
|
||||
length of :samp:`{name}` in decimal. Encode qualified versions of
|
||||
ordinary types as :samp:`U{n}{name}{code}`, where
|
||||
:samp:`{name}` is the name used for the type qualifier in source code,
|
||||
:samp:`{n}` is the length of :samp:`{name}` as above, and :samp:`{code}` is the
|
||||
code used to represent the unqualified version of this type. (See
|
||||
``write_builtin_type`` in :samp:`cp/mangle.cc` for the list of
|
||||
codes.) In both cases the spaces are for clarity; do not include any
|
||||
spaces in your string.
|
||||
|
||||
This hook is applied to types prior to typedef resolution. If the mangled
|
||||
name for a particular type depends only on that type's main variant, you
|
||||
can perform typedef resolution yourself using ``TYPE_MAIN_VARIANT``
|
||||
before mangling.
|
||||
|
||||
The default version of this hook always returns ``NULL``, which is
|
||||
appropriate for a target that does not define any new fundamental
|
||||
types.
|
||||
|
||||
.. hook-end
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_MANGLE_TYPE]
|
||||
:end-before: [TARGET_MANGLE_TYPE]
|
||||
|
@ -49,28 +49,10 @@ Define the following hook if your backend either implements ABI-specified
|
||||
descriptor support, or can use GCC's generic descriptor implementation
|
||||
for nested functions.
|
||||
|
||||
.. c:var:: int TARGET_CUSTOM_FUNCTION_DESCRIPTORS
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_CUSTOM_FUNCTION_DESCRIPTORS]
|
||||
:end-before: [TARGET_CUSTOM_FUNCTION_DESCRIPTORS]
|
||||
|
||||
.. hook-start:TARGET_CUSTOM_FUNCTION_DESCRIPTORS
|
||||
|
||||
If the target can use GCC's generic descriptor mechanism for nested
|
||||
functions, define this hook to a power of 2 representing an unused bit
|
||||
in function pointers which can be used to differentiate descriptors at
|
||||
run time. This value gives the number of bytes by which descriptor
|
||||
pointers are misaligned compared to function pointers. For example, on
|
||||
targets that require functions to be aligned to a 4-byte boundary, a
|
||||
value of either 1 or 2 is appropriate unless the architecture already
|
||||
reserves the bit for another purpose, such as on ARM.
|
||||
|
||||
Define this hook to 0 if the target implements ABI support for
|
||||
function descriptors in its standard calling sequence, like for example
|
||||
HPPA or IA-64.
|
||||
|
||||
Using descriptors for nested functions
|
||||
eliminates the need for trampolines that reside on the stack and require
|
||||
it to be made executable.
|
||||
|
||||
.. hook-end
|
||||
|
||||
The following macros tell GCC how to generate code to allocate and
|
||||
initialize an executable trampoline. You can also use this interface
|
||||
@ -94,21 +76,10 @@ proper offset from the start of the trampoline. On a RISC machine, it
|
||||
may be necessary to take out pieces of the address and store them
|
||||
separately.
|
||||
|
||||
.. function:: void TARGET_ASM_TRAMPOLINE_TEMPLATE (FILE *f)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_ASM_TRAMPOLINE_TEMPLATE]
|
||||
:end-before: [TARGET_ASM_TRAMPOLINE_TEMPLATE]
|
||||
|
||||
.. hook-start:TARGET_ASM_TRAMPOLINE_TEMPLATE
|
||||
|
||||
This hook is called by ``assemble_trampoline_template`` to output,
|
||||
on the stream :samp:`{f}`, assembler code for a block of data that contains
|
||||
the constant parts of a trampoline. This code should not include a
|
||||
label---the label is taken care of automatically.
|
||||
|
||||
If you do not define this hook, it means no template is needed
|
||||
for the target. Do not define this hook on systems where the block move
|
||||
code to copy the trampoline into place would be larger than the code
|
||||
to generate it on the spot.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. c:macro:: TRAMPOLINE_SECTION
|
||||
|
||||
@ -126,59 +97,20 @@ separately.
|
||||
If you don't define this macro, the value of ``FUNCTION_ALIGNMENT``
|
||||
is used for aligning trampolines.
|
||||
|
||||
.. function:: void TARGET_TRAMPOLINE_INIT (rtx m_tramp, tree fndecl, rtx static_chain)
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_TRAMPOLINE_INIT]
|
||||
:end-before: [TARGET_TRAMPOLINE_INIT]
|
||||
|
||||
.. hook-start:TARGET_TRAMPOLINE_INIT
|
||||
|
||||
This hook is called to initialize a trampoline.
|
||||
:samp:`{m_tramp}` is an RTX for the memory block for the trampoline; :samp:`{fndecl}`
|
||||
is the ``FUNCTION_DECL`` for the nested function; :samp:`{static_chain}` is an
|
||||
RTX for the static chain value that should be passed to the function
|
||||
when it is called.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_EMIT_CALL_BUILTIN___CLEAR_CACHE]
|
||||
:end-before: [TARGET_EMIT_CALL_BUILTIN___CLEAR_CACHE]
|
||||
|
||||
If the target defines ``TARGET_ASM_TRAMPOLINE_TEMPLATE``, then the
|
||||
first thing this hook should do is emit a block move into :samp:`{m_tramp}`
|
||||
from the memory block returned by ``assemble_trampoline_template``.
|
||||
Note that the block move need only cover the constant parts of the
|
||||
trampoline. If the target isolates the variable parts of the trampoline
|
||||
to the end, not all ``TRAMPOLINE_SIZE`` bytes need be copied.
|
||||
|
||||
If the target requires any other actions, such as flushing caches
|
||||
(possibly calling function maybe_emit_call_builtin___clear_cache) or
|
||||
enabling stack execution, these actions should be performed after
|
||||
initializing the trampoline proper.
|
||||
.. include:: tm.rst.in
|
||||
:start-after: [TARGET_TRAMPOLINE_ADJUST_ADDRESS]
|
||||
:end-before: [TARGET_TRAMPOLINE_ADJUST_ADDRESS]
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: void TARGET_EMIT_CALL_BUILTIN___CLEAR_CACHE (rtx begin, rtx end)
|
||||
|
||||
.. hook-start:TARGET_EMIT_CALL_BUILTIN___CLEAR_CACHE
|
||||
|
||||
On targets that do not define a ``clear_cache`` insn expander,
|
||||
but that define the ``CLEAR_CACHE_INSN`` macro,
|
||||
maybe_emit_call_builtin___clear_cache relies on this target hook
|
||||
to clear an address range in the instruction cache.
|
||||
|
||||
The default implementation calls the ``__clear_cache`` builtin,
|
||||
taking the assembler name from the builtin declaration. Overriding
|
||||
definitions may call alternate functions, with alternate calling
|
||||
conventions, or emit alternate RTX to perform the job.
|
||||
|
||||
.. hook-end
|
||||
|
||||
.. function:: rtx TARGET_TRAMPOLINE_ADJUST_ADDRESS (rtx addr)
|
||||
|
||||
.. hook-start:TARGET_TRAMPOLINE_ADJUST_ADDRESS
|
||||
|
||||
This hook should perform any machine-specific adjustment in
|
||||
the address of the trampoline. Its argument contains the address of the
|
||||
memory block that was passed to ``TARGET_TRAMPOLINE_INIT``. In case
|
||||
the address to be used for a function call should be different from the
|
||||
address at which the template was stored, the different address should
|
||||
be returned; otherwise :samp:`{addr}` should be returned unchanged.
|
||||
If this hook is not defined, :samp:`{addr}` will be used for function calls.
|
||||
|
||||
.. hook-end
|
||||
|
||||
Implementing trampolines is difficult on many machines because they have
|
||||
separate instruction and data caches. Writing into a stack location
|
||||
|
Loading…
x
Reference in New Issue
Block a user