diff options
author | alk3pInjection <webmaster@raspii.tech> | 2024-02-04 16:16:35 +0800 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2024-02-04 16:16:35 +0800 |
commit | abdaadbcae30fe0c9a66c7516798279fdfd97750 (patch) | |
tree | 00a54a6e25601e43876d03c1a4a12a749d4a914c /share/doc/gccint/Addressing-Modes.html |
https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
Change-Id: I7303388733328cd98ab9aa3c30236db67f2e9e9c
Diffstat (limited to 'share/doc/gccint/Addressing-Modes.html')
-rw-r--r-- | share/doc/gccint/Addressing-Modes.html | 783 |
1 files changed, 783 insertions, 0 deletions
diff --git a/share/doc/gccint/Addressing-Modes.html b/share/doc/gccint/Addressing-Modes.html new file mode 100644 index 0000000..c3a9c21 --- /dev/null +++ b/share/doc/gccint/Addressing-Modes.html @@ -0,0 +1,783 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<!-- Copyright (C) 1988-2023 Free Software Foundation, Inc. + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with the +Invariant Sections being "Funding Free Software", the Front-Cover +Texts being (a) (see below), and with the Back-Cover Texts being (b) +(see below). A copy of the license is included in the section entitled +"GNU Free Documentation License". + +(a) The FSF's Front-Cover Text is: + +A GNU Manual + +(b) The FSF's Back-Cover Text is: + +You have freedom to copy and modify this GNU Manual, like GNU + software. Copies published by the Free Software Foundation raise + funds for GNU development. --> +<!-- Created by GNU Texinfo 5.1, http://www.gnu.org/software/texinfo/ --> +<head> +<title>GNU Compiler Collection (GCC) Internals: Addressing Modes</title> + +<meta name="description" content="GNU Compiler Collection (GCC) Internals: Addressing Modes"> +<meta name="keywords" content="GNU Compiler Collection (GCC) Internals: Addressing Modes"> +<meta name="resource-type" content="document"> +<meta name="distribution" content="global"> +<meta name="Generator" content="makeinfo"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<link href="index.html#Top" rel="start" title="Top"> +<link href="Option-Index.html#Option-Index" rel="index" title="Option Index"> +<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents"> +<link href="Target-Macros.html#Target-Macros" rel="up" title="Target Macros"> +<link href="Anchored-Addresses.html#Anchored-Addresses" rel="next" title="Anchored Addresses"> +<link href="Library-Calls.html#Library-Calls" rel="previous" title="Library Calls"> +<style type="text/css"> +<!-- +a.summary-letter {text-decoration: none} +blockquote.smallquotation {font-size: smaller} +div.display {margin-left: 3.2em} +div.example {margin-left: 3.2em} +div.indentedblock {margin-left: 3.2em} +div.lisp {margin-left: 3.2em} +div.smalldisplay {margin-left: 3.2em} +div.smallexample {margin-left: 3.2em} +div.smallindentedblock {margin-left: 3.2em; font-size: smaller} +div.smalllisp {margin-left: 3.2em} +kbd {font-style:oblique} +pre.display {font-family: inherit} +pre.format {font-family: inherit} +pre.menu-comment {font-family: serif} +pre.menu-preformatted {font-family: serif} +pre.smalldisplay {font-family: inherit; font-size: smaller} +pre.smallexample {font-size: smaller} +pre.smallformat {font-family: inherit; font-size: smaller} +pre.smalllisp {font-size: smaller} +span.nocodebreak {white-space:nowrap} +span.nolinebreak {white-space:nowrap} +span.roman {font-family:serif; font-weight:normal} +span.sansserif {font-family:sans-serif; font-weight:normal} +ul.no-bullet {list-style: none} +--> +</style> + + +</head> + +<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000"> +<a name="Addressing-Modes"></a> +<div class="header"> +<p> +Next: <a href="Anchored-Addresses.html#Anchored-Addresses" accesskey="n" rel="next">Anchored Addresses</a>, Previous: <a href="Library-Calls.html#Library-Calls" accesskey="p" rel="previous">Library Calls</a>, Up: <a href="Target-Macros.html#Target-Macros" accesskey="u" rel="up">Target Macros</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p> +</div> +<hr> +<a name="Addressing-Modes-1"></a> +<h3 class="section">18.13 Addressing Modes</h3> +<a name="index-addressing-modes"></a> + +<p>This is about addressing modes. +</p> +<dl> +<dt><a name="index-HAVE_005fPRE_005fINCREMENT"></a>Macro: <strong>HAVE_PRE_INCREMENT</strong></dt> +<dt><a name="index-HAVE_005fPRE_005fDECREMENT"></a>Macro: <strong>HAVE_PRE_DECREMENT</strong></dt> +<dt><a name="index-HAVE_005fPOST_005fINCREMENT"></a>Macro: <strong>HAVE_POST_INCREMENT</strong></dt> +<dt><a name="index-HAVE_005fPOST_005fDECREMENT"></a>Macro: <strong>HAVE_POST_DECREMENT</strong></dt> +<dd><p>A C expression that is nonzero if the machine supports pre-increment, +pre-decrement, post-increment, or post-decrement addressing respectively. +</p></dd></dl> + +<dl> +<dt><a name="index-HAVE_005fPRE_005fMODIFY_005fDISP"></a>Macro: <strong>HAVE_PRE_MODIFY_DISP</strong></dt> +<dt><a name="index-HAVE_005fPOST_005fMODIFY_005fDISP"></a>Macro: <strong>HAVE_POST_MODIFY_DISP</strong></dt> +<dd><p>A C expression that is nonzero if the machine supports pre- or +post-address side-effect generation involving constants other than +the size of the memory operand. +</p></dd></dl> + +<dl> +<dt><a name="index-HAVE_005fPRE_005fMODIFY_005fREG"></a>Macro: <strong>HAVE_PRE_MODIFY_REG</strong></dt> +<dt><a name="index-HAVE_005fPOST_005fMODIFY_005fREG"></a>Macro: <strong>HAVE_POST_MODIFY_REG</strong></dt> +<dd><p>A C expression that is nonzero if the machine supports pre- or +post-address side-effect generation involving a register displacement. +</p></dd></dl> + +<dl> +<dt><a name="index-CONSTANT_005fADDRESS_005fP"></a>Macro: <strong>CONSTANT_ADDRESS_P</strong> <em>(<var>x</var>)</em></dt> +<dd><p>A C expression that is 1 if the RTX <var>x</var> is a constant which +is a valid address. On most machines the default definition of +<code>(CONSTANT_P (<var>x</var>) && GET_CODE (<var>x</var>) != CONST_DOUBLE)</code> +is acceptable, but a few machines are more restrictive as to which +constant addresses are supported. +</p></dd></dl> + +<dl> +<dt><a name="index-CONSTANT_005fP"></a>Macro: <strong>CONSTANT_P</strong> <em>(<var>x</var>)</em></dt> +<dd><p><code>CONSTANT_P</code>, which is defined by target-independent code, +accepts integer-values expressions whose values are not explicitly +known, such as <code>symbol_ref</code>, <code>label_ref</code>, and <code>high</code> +expressions and <code>const</code> arithmetic expressions, in addition to +<code>const_int</code> and <code>const_double</code> expressions. +</p></dd></dl> + +<dl> +<dt><a name="index-MAX_005fREGS_005fPER_005fADDRESS"></a>Macro: <strong>MAX_REGS_PER_ADDRESS</strong></dt> +<dd><p>A number, the maximum number of registers that can appear in a valid +memory address. Note that it is up to you to specify a value equal to +the maximum number that <code>TARGET_LEGITIMATE_ADDRESS_P</code> would ever +accept. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fLEGITIMATE_005fADDRESS_005fP"></a>Target Hook: <em>bool</em> <strong>TARGET_LEGITIMATE_ADDRESS_P</strong> <em>(machine_mode <var>mode</var>, rtx <var>x</var>, bool <var>strict</var>)</em></dt> +<dd><p>A function that returns whether <var>x</var> (an RTX) is a legitimate memory +address on the target machine for a memory operand of mode <var>mode</var>. +</p> +<p>Legitimate addresses are defined in two variants: a strict variant and a +non-strict one. The <var>strict</var> parameter chooses which variant is +desired by the caller. +</p> +<p>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 <code>reg_renumber</code> 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 <code>-1</code>. +</p> +<p>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. +</p> +<p>Normally, constant addresses which are the sum of a <code>symbol_ref</code> +and an integer are stored inside a <code>const</code> 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 <code>const</code> as legitimate. +</p> +<p>Usually <code>PRINT_OPERAND_ADDRESS</code> is not prepared to handle constant +sums that are not marked with <code>const</code>. It assumes that a naked +<code>plus</code> indicates indexing. If so, then you <em>must</em> reject such +naked constant sums as illegitimate addresses, so that none of them will +be given to <code>PRINT_OPERAND_ADDRESS</code>. +</p> +<a name="index-TARGET_005fENCODE_005fSECTION_005fINFO-and-address-validation"></a> +<p>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 <code>TARGET_ENCODE_SECTION_INFO</code> to store the information +into the <code>symbol_ref</code>, and then check for it here. When you see a +<code>const</code>, you will have to look inside it to find the +<code>symbol_ref</code> in order to determine the section. See <a href="Assembler-Format.html#Assembler-Format">Assembler Format</a>. +</p> +<a name="index-GO_005fIF_005fLEGITIMATE_005fADDRESS"></a> +<p>Some ports are still using a deprecated legacy substitute for +this hook, the <code>GO_IF_LEGITIMATE_ADDRESS</code> macro. This macro +has this syntax: +</p> +<div class="example"> +<pre class="example">#define GO_IF_LEGITIMATE_ADDRESS (<var>mode</var>, <var>x</var>, <var>label</var>) +</pre></div> + +<p>and should <code>goto <var>label</var></code> if the address <var>x</var> is a valid +address on the target machine for a memory operand of mode <var>mode</var>. +</p> +<a name="index-REG_005fOK_005fSTRICT"></a> +<p>Compiler source files that want to use the strict variant of this +macro define the macro <code>REG_OK_STRICT</code>. You should use an +<code>#ifdef REG_OK_STRICT</code> conditional to define the strict variant in +that case and the non-strict variant otherwise. +</p> +<p>Using the hook is usually simpler because it limits the number of +files that are recompiled when changes are made. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fMEM_005fCONSTRAINT"></a>Macro: <strong>TARGET_MEM_CONSTRAINT</strong></dt> +<dd><p>A single character to be used instead of the default <code>'m'</code> +character for general memory addresses. This defines the constraint +letter which matches the memory addresses accepted by +<code>TARGET_LEGITIMATE_ADDRESS_P</code>. Define this macro if you want to +support new address formats in your back end without changing the +semantics of the <code>'m'</code> constraint. This is necessary in order to +preserve functionality of inline assembly constructs using the +<code>'m'</code> constraint. +</p></dd></dl> + +<dl> +<dt><a name="index-FIND_005fBASE_005fTERM"></a>Macro: <strong>FIND_BASE_TERM</strong> <em>(<var>x</var>)</em></dt> +<dd><p>A C expression to determine the base term of address <var>x</var>, +or to provide a simplified version of <var>x</var> from which <samp>alias.cc</samp> +can easily find the base term. This macro is used in only two places: +<code>find_base_value</code> and <code>find_base_term</code> in <samp>alias.cc</samp>. +</p> +<p>It is always safe for this macro to not be defined. It exists so +that alias analysis can understand machine-dependent addresses. +</p> +<p>The typical use of this macro is to handle addresses containing +a label_ref or symbol_ref within an UNSPEC. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fLEGITIMIZE_005fADDRESS"></a>Target Hook: <em>rtx</em> <strong>TARGET_LEGITIMIZE_ADDRESS</strong> <em>(rtx <var>x</var>, rtx <var>oldx</var>, machine_mode <var>mode</var>)</em></dt> +<dd><p>This hook is given an invalid memory address <var>x</var> for an +operand of mode <var>mode</var> and should try to return a valid memory +address. +</p> +<a name="index-break_005fout_005fmemory_005frefs"></a> +<p><var>x</var> will always be the result of a call to <code>break_out_memory_refs</code>, +and <var>oldx</var> will be the operand that was given to that function to produce +<var>x</var>. +</p> +<p>The code of the hook should not alter the substructure of +<var>x</var>. If it transforms <var>x</var> into a more legitimate form, it +should return the new <var>x</var>. +</p> +<p>It is not necessary for this hook to come up with a legitimate address, +with the exception of native TLS addresses (see <a href="Emulated-TLS.html#Emulated-TLS">Emulated TLS</a>). +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 <var>x</var> if it cannot find +a valid way to legitimize the address. But often a machine-dependent +strategy can generate better code. +</p></dd></dl> + +<dl> +<dt><a name="index-LEGITIMIZE_005fRELOAD_005fADDRESS"></a>Macro: <strong>LEGITIMIZE_RELOAD_ADDRESS</strong> <em>(<var>x</var>, <var>mode</var>, <var>opnum</var>, <var>type</var>, <var>ind_levels</var>, <var>win</var>)</em></dt> +<dd><p>A C compound statement that attempts to replace <var>x</var>, which is an address +that needs reloading, with a valid memory address for an operand of mode +<var>mode</var>. <var>win</var> will be a C statement label elsewhere in the code. +It is not necessary to define this macro, but it might be useful for +performance reasons. +</p> +<p>For example, on the i386, it is sometimes possible to use a single +reload register instead of two by reloading a sum of two pseudo +registers into a register. On the other hand, for number of RISC +processors offsets are limited so that often an intermediate address +needs to be generated in order to address a stack slot. By defining +<code>LEGITIMIZE_RELOAD_ADDRESS</code> appropriately, the intermediate addresses +generated for adjacent some stack slots can be made identical, and thus +be shared. +</p> +<p><em>Note</em>: This macro should be used with caution. It is necessary +to know something of how reload works in order to effectively use this, +and it is quite easy to produce macros that build in too much knowledge +of reload internals. +</p> +<p><em>Note</em>: This macro must be able to reload an address created by a +previous invocation of this macro. If it fails to handle such addresses +then the compiler may generate incorrect code or abort. +</p> +<a name="index-push_005freload"></a> +<p>The macro definition should use <code>push_reload</code> to indicate parts that +need reloading; <var>opnum</var>, <var>type</var> and <var>ind_levels</var> are usually +suitable to be passed unaltered to <code>push_reload</code>. +</p> +<p>The code generated by this macro must not alter the substructure of +<var>x</var>. If it transforms <var>x</var> into a more legitimate form, it +should assign <var>x</var> (which will always be a C variable) a new value. +This also applies to parts that you change indirectly by calling +<code>push_reload</code>. +</p> +<a name="index-strict_005fmemory_005faddress_005fp"></a> +<p>The macro definition may use <code>strict_memory_address_p</code> to test if +the address has become legitimate. +</p> +<a name="index-copy_005frtx"></a> +<p>If you want to change only a part of <var>x</var>, one standard way of doing +this is to use <code>copy_rtx</code>. Note, however, that it unshares only a +single level of rtl. Thus, if the part to be changed is not at the +top level, you’ll need to replace first the top level. +It is not necessary for this macro to come up with a legitimate +address; but often a machine-dependent strategy can generate better code. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fMODE_005fDEPENDENT_005fADDRESS_005fP"></a>Target Hook: <em>bool</em> <strong>TARGET_MODE_DEPENDENT_ADDRESS_P</strong> <em>(const_rtx <var>addr</var>, addr_space_t <var>addrspace</var>)</em></dt> +<dd><p>This hook returns <code>true</code> if memory address <var>addr</var> in address +space <var>addrspace</var> 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. +</p> +<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. +</p> +<p>You may assume that <var>addr</var> is a valid address for the machine. +</p> +<p>The default version of this hook returns <code>false</code>. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fLEGITIMATE_005fCONSTANT_005fP"></a>Target Hook: <em>bool</em> <strong>TARGET_LEGITIMATE_CONSTANT_P</strong> <em>(machine_mode <var>mode</var>, rtx <var>x</var>)</em></dt> +<dd><p>This hook returns true if <var>x</var> is a legitimate constant for a +<var>mode</var>-mode immediate operand on the target machine. You can assume that +<var>x</var> satisfies <code>CONSTANT_P</code>, so you need not check this. +</p> +<p>The default definition returns true. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fPRECOMPUTE_005fTLS_005fP"></a>Target Hook: <em>bool</em> <strong>TARGET_PRECOMPUTE_TLS_P</strong> <em>(machine_mode <var>mode</var>, rtx <var>x</var>)</em></dt> +<dd><p>This hook returns true if <var>x</var> 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 <var>x</var> satisfies <code>CONSTANT_P</code>, so you need not +check this. +</p> +<p>The default definition returns false. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fDELEGITIMIZE_005fADDRESS"></a>Target Hook: <em>rtx</em> <strong>TARGET_DELEGITIMIZE_ADDRESS</strong> <em>(rtx <var>x</var>)</em></dt> +<dd><p>This hook is used to undo the possibly obfuscating effects of the +<code>LEGITIMIZE_ADDRESS</code> and <code>LEGITIMIZE_RELOAD_ADDRESS</code> target +macros. Some backend implementations of these macros wrap symbol +references inside an <code>UNSPEC</code> rtx to represent PIC or similar +addressing modes. This target hook allows GCC’s optimizers to understand +the semantics of these opaque <code>UNSPEC</code>s by converting them back +into their original form. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fCONST_005fNOT_005fOK_005fFOR_005fDEBUG_005fP"></a>Target Hook: <em>bool</em> <strong>TARGET_CONST_NOT_OK_FOR_DEBUG_P</strong> <em>(rtx <var>x</var>)</em></dt> +<dd><p>This hook should return true if <var>x</var> should not be emitted into +debug sections. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fCANNOT_005fFORCE_005fCONST_005fMEM"></a>Target Hook: <em>bool</em> <strong>TARGET_CANNOT_FORCE_CONST_MEM</strong> <em>(machine_mode <var>mode</var>, rtx <var>x</var>)</em></dt> +<dd><p>This hook should return true if <var>x</var> is of a form that cannot (or +should not) be spilled to the constant pool. <var>mode</var> is the mode +of <var>x</var>. +</p> +<p>The default version of this hook returns false. +</p> +<p>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. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fUSE_005fBLOCKS_005fFOR_005fCONSTANT_005fP"></a>Target Hook: <em>bool</em> <strong>TARGET_USE_BLOCKS_FOR_CONSTANT_P</strong> <em>(machine_mode <var>mode</var>, const_rtx <var>x</var>)</em></dt> +<dd><p>This hook should return true if pool entries for constant <var>x</var> can +be placed in an <code>object_block</code> structure. <var>mode</var> is the mode +of <var>x</var>. +</p> +<p>The default version returns false for all constants. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fUSE_005fBLOCKS_005fFOR_005fDECL_005fP"></a>Target Hook: <em>bool</em> <strong>TARGET_USE_BLOCKS_FOR_DECL_P</strong> <em>(const_tree <var>decl</var>)</em></dt> +<dd><p>This hook should return true if pool entries for <var>decl</var> should +be placed in an <code>object_block</code> structure. +</p> +<p>The default version returns true for all decls. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fBUILTIN_005fRECIPROCAL"></a>Target Hook: <em>tree</em> <strong>TARGET_BUILTIN_RECIPROCAL</strong> <em>(tree <var>fndecl</var>)</em></dt> +<dd><p>This hook should return the DECL of a function that implements the +reciprocal of the machine-specific builtin function <var>fndecl</var>, or +<code>NULL_TREE</code> if such a function is not available. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fBUILTIN_005fMASK_005fFOR_005fLOAD"></a>Target Hook: <em>tree</em> <strong>TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD</strong> <em>(void)</em></dt> +<dd><p>This hook should return the DECL of a function <var>f</var> that given an +address <var>addr</var> as an argument returns a mask <var>m</var> that can be +used to extract from two vectors the relevant data that resides in +<var>addr</var> in case <var>addr</var> is not properly aligned. +</p> +<p>The autovectorizer, when vectorizing a load operation from an address +<var>addr</var> that may be unaligned, will generate two vector loads from +the two aligned addresses around <var>addr</var>. It then generates a +<code>REALIGN_LOAD</code> operation to extract the relevant data from the +two loaded vectors. The first two arguments to <code>REALIGN_LOAD</code>, +<var>v1</var> and <var>v2</var>, are the two vectors, each of size <var>VS</var>, and +the third argument, <var>OFF</var>, defines how the data will be extracted +from these two vectors: if <var>OFF</var> is 0, then the returned vector is +<var>v2</var>; otherwise, the returned vector is composed from the last +<var>VS</var>-<var>OFF</var> elements of <var>v1</var> concatenated to the first +<var>OFF</var> elements of <var>v2</var>. +</p> +<p>If this hook is defined, the autovectorizer will generate a call +to <var>f</var> (using the DECL tree that this hook returns) and will +use the return value of <var>f</var> as the argument <var>OFF</var> to +<code>REALIGN_LOAD</code>. Therefore, the mask <var>m</var> returned by <var>f</var> +should comply with the semantics expected by <code>REALIGN_LOAD</code> +described above. +If this hook is not defined, then <var>addr</var> will be used as +the argument <var>OFF</var> to <code>REALIGN_LOAD</code>, in which case the low +log2(<var>VS</var>) - 1 bits of <var>addr</var> will be considered. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fBUILTIN_005fVECTORIZATION_005fCOST"></a>Target Hook: <em>int</em> <strong>TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST</strong> <em>(enum vect_cost_for_stmt <var>type_of_cost</var>, tree <var>vectype</var>, int <var>misalign</var>)</em></dt> +<dd><p>Returns cost of different scalar or vector statements for vectorization cost model. +For vector memory operations the cost may depend on type (<var>vectype</var>) and +misalignment value (<var>misalign</var>). +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fPREFERRED_005fVECTOR_005fALIGNMENT"></a>Target Hook: <em>poly_uint64</em> <strong>TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT</strong> <em>(const_tree <var>type</var>)</em></dt> +<dd><p>This hook returns the preferred alignment in bits for accesses to +vectors of type <var>type</var> in vectorized code. This might be less than +or greater than the ABI-defined value returned by +<code>TARGET_VECTOR_ALIGNMENT</code>. It can be equal to the alignment of +a single element, in which case the vectorizer will not try to optimize +for alignment. +</p> +<p>The default hook returns <code>TYPE_ALIGN (<var>type</var>)</code>, which is +correct for most targets. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fVECTOR_005fALIGNMENT_005fREACHABLE"></a>Target Hook: <em>bool</em> <strong>TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE</strong> <em>(const_tree <var>type</var>, bool <var>is_packed</var>)</em></dt> +<dd><p>Return true if vector alignment is reachable (by peeling N iterations) +for the given scalar type <var>type</var>. <var>is_packed</var> is false if the scalar +access using <var>type</var> is known to be naturally aligned. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fVEC_005fPERM_005fCONST"></a>Target Hook: <em>bool</em> <strong>TARGET_VECTORIZE_VEC_PERM_CONST</strong> <em>(machine_mode <var>mode</var>, machine_mode <var>op_mode</var>, rtx <var>output</var>, rtx <var>in0</var>, rtx <var>in1</var>, const vec_perm_indices <var>&sel</var>)</em></dt> +<dd><p>This hook is used to test whether the target can permute up to two +vectors of mode <var>op_mode</var> using the permutation vector <code>sel</code>, +producing a vector of mode <var>mode</var>. The hook is also used to emit such +a permutation. +</p> +<p>When the hook is being used to test whether the target supports a permutation, +<var>in0</var>, <var>in1</var>, and <var>out</var> are all null. When the hook is being used +to emit a permutation, <var>in0</var> and <var>in1</var> are the source vectors of mode +<var>op_mode</var> and <var>out</var> is the destination vector of mode <var>mode</var>. +<var>in1</var> is the same as <var>in0</var> if <var>sel</var> describes a permutation on one +vector instead of two. +</p> +<p>Return true if the operation is possible, emitting instructions for it +if rtxes are provided. +</p> +<a name="index-vec_005fpermm-instruction-pattern-1"></a> +<p>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 <var>vec_perm<var>mode</var></var> +instruction pattern. There is no need for the hook to handle these two +implementation approaches itself. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fPREFERRED_005fDIV_005fAS_005fSHIFTS_005fOVER_005fMULT"></a>Target Hook: <em>bool</em> <strong>TARGET_VECTORIZE_PREFERRED_DIV_AS_SHIFTS_OVER_MULT</strong> <em>(const_tree <var>type</var>)</em></dt> +<dd><p>Sometimes it is possible to implement a vector division using a sequence +of two addition-shift pairs, giving four instructions in total. +Return true if taking this approach for <var>vectype</var> is likely +to be better than using a sequence involving highpart multiplication. +Default is false if <code>can_mult_highpart_p</code>, otherwise true. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fBUILTIN_005fVECTORIZED_005fFUNCTION"></a>Target Hook: <em>tree</em> <strong>TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION</strong> <em>(unsigned <var>code</var>, tree <var>vec_type_out</var>, tree <var>vec_type_in</var>)</em></dt> +<dd><p>This hook should return the decl of a function that implements the +vectorized variant of the function with the <code>combined_fn</code> code +<var>code</var> or <code>NULL_TREE</code> if such a function is not available. +The return type of the vectorized function shall be of vector type +<var>vec_type_out</var> and the argument types should be <var>vec_type_in</var>. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fBUILTIN_005fMD_005fVECTORIZED_005fFUNCTION"></a>Target Hook: <em>tree</em> <strong>TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION</strong> <em>(tree <var>fndecl</var>, tree <var>vec_type_out</var>, tree <var>vec_type_in</var>)</em></dt> +<dd><p>This hook should return the decl of a function that implements the +vectorized variant of target built-in function <code>fndecl</code>. The +return type of the vectorized function shall be of vector type +<var>vec_type_out</var> and the argument types should be <var>vec_type_in</var>. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fSUPPORT_005fVECTOR_005fMISALIGNMENT"></a>Target Hook: <em>bool</em> <strong>TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT</strong> <em>(machine_mode <var>mode</var>, const_tree <var>type</var>, int <var>misalignment</var>, bool <var>is_packed</var>)</em></dt> +<dd><p>This hook should return true if the target supports misaligned vector +store/load of a specific factor denoted in the <var>misalignment</var> +parameter. The vector store/load should be of machine mode <var>mode</var> and +the elements in the vectors should be of type <var>type</var>. <var>is_packed</var> +parameter is true if the memory access is defined in a packed struct. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fPREFERRED_005fSIMD_005fMODE"></a>Target Hook: <em>machine_mode</em> <strong>TARGET_VECTORIZE_PREFERRED_SIMD_MODE</strong> <em>(scalar_mode <var>mode</var>)</em></dt> +<dd><p>This hook should return the preferred mode for vectorizing scalar +mode <var>mode</var>. The default is +equal to <code>word_mode</code>, because the vectorizer can do some +transformations even in absence of specialized <acronym>SIMD</acronym> hardware. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fSPLIT_005fREDUCTION"></a>Target Hook: <em>machine_mode</em> <strong>TARGET_VECTORIZE_SPLIT_REDUCTION</strong> <em>(machine_mode)</em></dt> +<dd><p>This hook should return the preferred mode to split the final reduction +step on <var>mode</var> to. The reduction is then carried out reducing upper +against lower halves of vectors recursively until the specified mode is +reached. The default is <var>mode</var> which means no splitting. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fAUTOVECTORIZE_005fVECTOR_005fMODES"></a>Target Hook: <em>unsigned int</em> <strong>TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES</strong> <em>(vector_modes *<var>modes</var>, bool <var>all</var>)</em></dt> +<dd><p>If using the mode returned by <code>TARGET_VECTORIZE_PREFERRED_SIMD_MODE</code> +is not the only approach worth considering, this hook should add one mode to +<var>modes</var> for each useful alternative approach. These modes are then +passed to <code>TARGET_VECTORIZE_RELATED_MODE</code> to obtain the vector mode +for a given element mode. +</p> +<p>The modes returned in <var>modes</var> 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 <code>TARGET_VECTORIZE_PREFERRED_SIMD_MODE</code> for its +element mode. +</p> +<p>If <var>all</var> is true, add suitable vector modes even when they are generally +not expected to be worthwhile. +</p> +<p>The hook returns a bitmask of flags that control how the modes in +<var>modes</var> are used. The flags are: +</p><dl compact="compact"> +<dt><code>VECT_COMPARE_COSTS</code></dt> +<dd><p>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. +</p></dd> +</dl> + +<p>The hook does not need to do anything if the vector returned by +<code>TARGET_VECTORIZE_PREFERRED_SIMD_MODE</code> is the only one relevant +for autovectorization. The default implementation adds no modes and +returns 0. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fRELATED_005fMODE"></a>Target Hook: <em>opt_machine_mode</em> <strong>TARGET_VECTORIZE_RELATED_MODE</strong> <em>(machine_mode <var>vector_mode</var>, scalar_mode <var>element_mode</var>, poly_uint64 <var>nunits</var>)</em></dt> +<dd><p>If a piece of code is using vector mode <var>vector_mode</var> and also wants +to operate on elements of mode <var>element_mode</var>, return the vector mode +it should use for those elements. If <var>nunits</var> is nonzero, ensure that +the mode has exactly <var>nunits</var> elements, otherwise pick whichever vector +size pairs the most naturally with <var>vector_mode</var>. Return an empty +<code>opt_machine_mode</code> if there is no supported vector mode with the +required properties. +</p> +<p>There is no prescribed way of handling the case in which <var>nunits</var> +is zero. One common choice is to pick a vector mode with the same size +as <var>vector_mode</var>; 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 <var>vector_mode</var>; 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. +</p> +<p>The default implementation uses <code>mode_for_vector</code> to find the +requested mode, returning a mode with the same size as <var>vector_mode</var> +when <var>nunits</var> is zero. This is the correct behavior for most targets. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fGET_005fMASK_005fMODE"></a>Target Hook: <em>opt_machine_mode</em> <strong>TARGET_VECTORIZE_GET_MASK_MODE</strong> <em>(machine_mode <var>mode</var>)</em></dt> +<dd><p>Return the mode to use for a vector mask that holds one boolean +result for each element of vector mode <var>mode</var>. The returned mask mode +can be a vector of integers (class <code>MODE_VECTOR_INT</code>), a vector of +booleans (class <code>MODE_VECTOR_BOOL</code>) or a scalar integer (class +<code>MODE_INT</code>). Return an empty <code>opt_machine_mode</code> if no such +mask mode exists. +</p> +<p>The default implementation returns a <code>MODE_VECTOR_INT</code> with the +same size and number of elements as <var>mode</var>, if such a mode exists. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fEMPTY_005fMASK_005fIS_005fEXPENSIVE"></a>Target Hook: <em>bool</em> <strong>TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE</strong> <em>(unsigned <var>ifn</var>)</em></dt> +<dd><p>This hook returns true if masked internal function <var>ifn</var> (really of +type <code>internal_fn</code>) should be considered expensive when the mask is +all zeros. GCC can then try to branch around the instruction instead. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fCREATE_005fCOSTS"></a>Target Hook: <em>class vector_costs *</em> <strong>TARGET_VECTORIZE_CREATE_COSTS</strong> <em>(vec_info *<var>vinfo</var>, bool <var>costing_for_scalar</var>)</em></dt> +<dd><p>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 <var>loop_info</var> is +non-NULL, it identifies the loop being vectorized; otherwise a single block +is being vectorized. If <var>costing_for_scalar</var> 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. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fBUILTIN_005fGATHER"></a>Target Hook: <em>tree</em> <strong>TARGET_VECTORIZE_BUILTIN_GATHER</strong> <em>(const_tree <var>mem_vectype</var>, const_tree <var>index_type</var>, int <var>scale</var>)</em></dt> +<dd><p>Target builtin that implements vector gather operation. <var>mem_vectype</var> +is the vector type of the load and <var>index_type</var> is scalar type of +the index, scaled by <var>scale</var>. +The default is <code>NULL_TREE</code> which means to not vectorize gather +loads. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fVECTORIZE_005fBUILTIN_005fSCATTER"></a>Target Hook: <em>tree</em> <strong>TARGET_VECTORIZE_BUILTIN_SCATTER</strong> <em>(const_tree <var>vectype</var>, const_tree <var>index_type</var>, int <var>scale</var>)</em></dt> +<dd><p>Target builtin that implements vector scatter operation. <var>vectype</var> +is the vector type of the store and <var>index_type</var> is scalar type of +the index, scaled by <var>scale</var>. +The default is <code>NULL_TREE</code> which means to not vectorize scatter +stores. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fSIMD_005fCLONE_005fCOMPUTE_005fVECSIZE_005fAND_005fSIMDLEN"></a>Target Hook: <em>int</em> <strong>TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN</strong> <em>(struct cgraph_node *<var></var>, struct cgraph_simd_clone *<var></var>, <var>tree</var>, <var>int</var>, <var>bool</var>)</em></dt> +<dd><p>This hook should set <var>vecsize_mangle</var>, <var>vecsize_int</var>, <var>vecsize_float</var> +fields in <var>simd_clone</var> structure pointed by <var>clone_info</var> argument and also +<var>simdlen</var> field if it was previously 0. +<var>vecsize_mangle</var> is a marker for the backend only. <var>vecsize_int</var> and +<var>vecsize_float</var> should be left zero on targets where the number of lanes is +not determined by the bitsize (in which case <var>simdlen</var> is always used). +The hook should return 0 if SIMD clones shouldn’t be emitted, +or number of <var>vecsize_mangle</var> variants that should be emitted. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fSIMD_005fCLONE_005fADJUST"></a>Target Hook: <em>void</em> <strong>TARGET_SIMD_CLONE_ADJUST</strong> <em>(struct cgraph_node *<var></var>)</em></dt> +<dd><p>This hook should add implicit <code>attribute(target("..."))</code> attribute +to SIMD clone <var>node</var> if needed. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fSIMD_005fCLONE_005fUSABLE"></a>Target Hook: <em>int</em> <strong>TARGET_SIMD_CLONE_USABLE</strong> <em>(struct cgraph_node *<var></var>)</em></dt> +<dd><p>This hook should return -1 if SIMD clone <var>node</var> 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. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fSIMT_005fVF"></a>Target Hook: <em>int</em> <strong>TARGET_SIMT_VF</strong> <em>(void)</em></dt> +<dd><p>Return number of threads in SIMT thread group on the target. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fOMP_005fDEVICE_005fKIND_005fARCH_005fISA"></a>Target Hook: <em>int</em> <strong>TARGET_OMP_DEVICE_KIND_ARCH_ISA</strong> <em>(enum omp_device_kind_arch_isa <var>trait</var>, const char *<var>name</var>)</em></dt> +<dd><p>Return 1 if <var>trait</var> <var>name</var> 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. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fGOACC_005fVALIDATE_005fDIMS"></a>Target Hook: <em>bool</em> <strong>TARGET_GOACC_VALIDATE_DIMS</strong> <em>(tree <var>decl</var>, int *<var>dims</var>, int <var>fn_level</var>, unsigned <var>used</var>)</em></dt> +<dd><p>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 <var>fn_level</var> 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. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fGOACC_005fDIM_005fLIMIT"></a>Target Hook: <em>int</em> <strong>TARGET_GOACC_DIM_LIMIT</strong> <em>(int <var>axis</var>)</em></dt> +<dd><p>This hook should return the maximum size of a particular dimension, +or zero if unbounded. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fGOACC_005fFORK_005fJOIN"></a>Target Hook: <em>bool</em> <strong>TARGET_GOACC_FORK_JOIN</strong> <em>(gcall *<var>call</var>, const int *<var>dims</var>, bool <var>is_fork</var>)</em></dt> +<dd><p>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. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fGOACC_005fREDUCTION"></a>Target Hook: <em>void</em> <strong>TARGET_GOACC_REDUCTION</strong> <em>(gcall *<var>call</var>)</em></dt> +<dd><p>This hook is used by the oacc_transform pass to expand calls to the +<var>GOACC_REDUCTION</var> internal function, into a sequence of gimple +instructions. <var>call</var> is gimple statement containing the call to +the function. This hook removes statement <var>call</var> after the +expanded sequence has been inserted. This hook is also responsible +for allocating any storage for reductions when necessary. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fPREFERRED_005fELSE_005fVALUE"></a>Target Hook: <em>tree</em> <strong>TARGET_PREFERRED_ELSE_VALUE</strong> <em>(unsigned <var>ifn</var>, tree <var>type</var>, unsigned <var>nops</var>, tree *<var>ops</var>)</em></dt> +<dd><p>This hook returns the target’s preferred final argument for a call +to conditional internal function <var>ifn</var> (really of type +<code>internal_fn</code>). <var>type</var> specifies the return type of the +function and <var>ops</var> are the operands to the conditional operation, +of which there are <var>nops</var>. +</p> +<p>For example, if <var>ifn</var> is <code>IFN_COND_ADD</code>, the hook returns +a value of type <var>type</var> that should be used when ‘<samp><var>ops</var>[0]</samp>’ +and ‘<samp><var>ops</var>[1]</samp>’ are conditionally added together. +</p> +<p>This hook is only relevant if the target supports conditional patterns +like <code>cond_add<var>m</var></code>. The default implementation returns a zero +constant of type <var>type</var>. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fGOACC_005fADJUST_005fPRIVATE_005fDECL"></a>Target Hook: <em>tree</em> <strong>TARGET_GOACC_ADJUST_PRIVATE_DECL</strong> <em>(location_t <var>loc</var>, tree <var>var</var>, int <var>level</var>)</em></dt> +<dd><p>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. <code>GOMP_DIM_GANG</code>, <code>GOMP_DIM_WORKER</code> or +<code>GOMP_DIM_VECTOR</code>). A typical use for this hook is to force variable +declarations at the <code>gang</code> level to reside in GPU shared memory. +<var>loc</var> may be used for diagnostic purposes. +</p> +<p>You may also use the <code>TARGET_GOACC_EXPAND_VAR_DECL</code> hook if the +adjusted variable declaration needs to be expanded to RTL in a non-standard +way. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fGOACC_005fEXPAND_005fVAR_005fDECL"></a>Target Hook: <em>rtx</em> <strong>TARGET_GOACC_EXPAND_VAR_DECL</strong> <em>(tree <var>var</var>)</em></dt> +<dd><p>This hook, if defined, is used by accelerator target back-ends to expand +specially handled kinds of <code>VAR_DECL</code> expressions. A particular use is +to place variables with specific attributes inside special accelarator +memories. A return value of <code>NULL</code> indicates that the target does not +handle this <code>VAR_DECL</code>, and normal RTL expanding is resumed. +</p> +<p>Only define this hook if your accelerator target needs to expand certain +<code>VAR_DECL</code> nodes in a way that differs from the default. You can also adjust +private variables at OpenACC device-lowering time using the +<code>TARGET_GOACC_ADJUST_PRIVATE_DECL</code> target hook. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fGOACC_005fCREATE_005fWORKER_005fBROADCAST_005fRECORD"></a>Target Hook: <em>tree</em> <strong>TARGET_GOACC_CREATE_WORKER_BROADCAST_RECORD</strong> <em>(tree <var>rec</var>, bool <var>sender</var>, const char *<var>name</var>, unsigned HOST_WIDE_INT <var>offset</var>)</em></dt> +<dd><p>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. +</p> +<p>Presence of this target hook indicates that middle end neutering/broadcasting +be used. +</p></dd></dl> + +<dl> +<dt><a name="index-TARGET_005fGOACC_005fSHARED_005fMEM_005fLAYOUT"></a>Target Hook: <em>void</em> <strong>TARGET_GOACC_SHARED_MEM_LAYOUT</strong> <em>(unsigned HOST_WIDE_INT *<var></var>, unsigned HOST_WIDE_INT *<var></var>, <var>int[]</var>, unsigned <var>HOST_WIDE_INT[]</var>, unsigned <var>HOST_WIDE_INT[]</var>)</em></dt> +<dd><p>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. +</p></dd></dl> + +<hr> +<div class="header"> +<p> +Next: <a href="Anchored-Addresses.html#Anchored-Addresses" accesskey="n" rel="next">Anchored Addresses</a>, Previous: <a href="Library-Calls.html#Library-Calls" accesskey="p" rel="previous">Library Calls</a>, Up: <a href="Target-Macros.html#Target-Macros" accesskey="u" rel="up">Target Macros</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p> +</div> + + + +</body> +</html> |