Next: , Previous: Library Calls, Up: Target Macros


17.14 寻址模式

这是关于寻址模式的宏。

— Macro: HAVE_PRE_INCREMENT
— Macro: HAVE_PRE_DECREMENT
— Macro: HAVE_POST_INCREMENT
— Macro: HAVE_POST_DECREMENT

一个C表达式,为非0,如果机器分别支持前增,前减,后增,或者后减寻址。

— Macro: HAVE_PRE_MODIFY_DISP
— Macro: HAVE_POST_MODIFY_DISP

一个C表达式,非零,如果机器支持pre-或者post-address, 除了生成内存操作数的大小以外,还有常量副作用生成。

— Macro: HAVE_PRE_MODIFY_REG
— Macro: HAVE_POST_MODIFY_REG

一个C表达式,非零,如果机器支持pre-或者post-address, 除了生成内存操作数的大小以外,还有寄存器置换的副作用生成。

— Macro: CONSTANT_ADDRESS_P (x)

一个C表达式,为1,如果RTX x为一个常量,其为一个有效地址。 在大多数机器上,这可以被定义为CONSTANT_P (x), 但一些机器在支持哪些常量地址方面更加严格。

— Macro: CONSTANT_P (x)

CONSTANT_P,其由target无关代码定义,接受整数值表达式, 其值不被显示的知道,例如symbol_ref, label_refhigh表达式, 以及const算术表达式,const_intconst_double表达式。

— Macro: MAX_REGS_PER_ADDRESS

一个数,为可以出现在一个有效的内存地址中的最大寄存器编号。 注意需要你来指定GO_IF_LEGITIMATE_ADDRESS应该能够接受的等于该最大值的值。

— Target Hook: bool TARGET_LEGITIMATE_ADDRESS_P (enum machine_mode mode, rtx x, bool strict)

A function that returns whether x (an RTX) is a legitimate memory address on the target machine for a memory operand of mode mode.

Legitimate addresses are defined in two variants: a strict variant and a non-strict one. The 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.

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. 参见Assembler Format.

Some ports are still using a deprecated legacy substitute for this hook, the GO_IF_LEGITIMATE_ADDRESS macro. This macro has this syntax:

          #define GO_IF_LEGITIMATE_ADDRESS (mode, x, label)

and should goto label if the address x is a valid address on the target machine for a memory operand of mode mode. Whether the strict or non-strict variants are desired is defined by the REG_OK_STRICT macro introduced earlier in this section. Using the hook is usually simpler because it limits the number of files that are recompiled when changes are made.

— Macro: TARGET_MEM_CONSTRAINT

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

— Macro: FIND_BASE_TERM (x)

一个C表达式,用来确定地址x的base term。该宏只在两个地方使用: alias.cfind_base_valuefind_base_term

不定义该宏也总是安全的。它的存在是为了别名分析可以理解机器相关的地址。

该宏的典型用法是处理在UNSPEC中包含label_ref或symbol_ref的地址。

— Target Hook: rtx TARGET_LEGITIMIZE_ADDRESS (rtx x, rtx oldx, enum machine_mode mode)

This hook is given an invalid memory address x for an operand of mode mode and should try to return a valid memory address.

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

The code of the hook should not alter the substructure of x. If it transforms x into a more legitimate form, it should return the new x.

It is not necessary for this hook to come up with a legitimate address. The compiler has standard ways of doing so in all cases. In fact, it is safe to omit this hook or make it return x if it cannot find a valid way to legitimize the address. But often a machine-dependent strategy can generate better code.

— Macro: LEGITIMIZE_RELOAD_ADDRESS (x, mode, opnum, type, ind_levels, win)

一条C复合语句,其尝试使用一个机器模式为mode的操作数的有效内存地址, 来替换地址需要重载的xwin为代码中的一个C语句标号。 不必要定义该宏,但其可能会对性能有帮助。

例如,在i386上,有时可能通过将两个伪寄存器的和重载到一个寄存器中, 从而只使用一个重载寄存器,而不是两个。另一方面, 许多RISC处理器的偏移量是有限制的,使得经常要生成一个中间地址来寻址一个栈槽。 通过适当的定义LEGITIMIZE_RELOAD_ADDRESS, 为邻近的一些栈槽生成的中间地址可以为同一个,实现共享。

注意:该宏应该慎重使用。有必要了解重载是如何工作的,以便有效的使用该宏。

注意:该宏必须能够重载由该宏的之前调用所创建的地址。 如果不能处理这样的地址,则编译器可能会产生不正确的代码或者中断退出。

宏定义应该使用push_reload来指示需要重载的部分; opnumtypeind_levels通常无需更改而直接传给push_reload

该宏生成的代码必须不要修改x的子结构体。如果其将x转换成更合法的形式, 则其必须为x(其总为一个c变量)赋予一个新的值。 这也通常应用于你通过调用push_reload而间接改变的部分。

宏定义可以使用strict_memory_address_p来测试地址是否已经为合法的。

如果你只想改变x的一部分,一种标准的方法是使用copy_rtx。 但是注意,其只与rtl同一级不共享。因此,如果改变的部分不在顶层, 则你要首先替换顶层。该宏不必要产生一个合法的地址;但是通常机器相关的策略可以产生更好的代码。

— Target Hook: bool TARGET_MODE_DEPENDENT_ADDRESS_P (const_rtx addr)

This hook returns true if memory address addr can have different meanings depending on the machine mode of the memory reference it is used for or if the address is valid for some modes but not others.

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

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

The default version of this hook returns false.

— Macro: GO_IF_MODE_DEPENDENT_ADDRESS (addr, label)

一条C语句或者复合语句,具有一个条件goto label;; 当内存地址x(一个RTX)可以具有不同的含义, 该含义取决于内存引用的机器模式时,被执行。

自动递增和自动递减地址通常具有机器模式相关的效果, 因为递增或递减的数量为被寻址的操作数的大小。 一些机器具有其它机器模式相关的地址。许多RISC机器没有机器模式相关的地址。

你可以假设addr对于机器是一个有效的地址。

These are obsolete macros, replaced by the TARGET_MODE_DEPENDENT_ADDRESS_P target hook.

— Macro: LEGITIMATE_CONSTANT_P (x)

一个C表达式,如果x对于target机器上的一个立即操作数为合法的常量, 则为非0。你可以假设x满足CONSTANT_P,所以不需要进行检查。 实际上,在任何CONSTANT_P都是有效的机器上,为该宏定义为‘1’是合适的。

— Target Hook: rtx TARGET_DELEGITIMIZE_ADDRESS (rtx x)

该钩子用于撤销LEGITIMIZE_ADDRESSLEGITIMIZE_RELOAD_ADDRESS target 宏可能造成的模糊效果。这些宏的一些后端实现, 将符号引用包含在一个UNSPEC rtx中来表示PIC或者类似的寻址模式。 该target钩子允许GCC的优化器来理解这些透明的UNSPEC的语义, 通过将它们转换回到它们最初的形式。

— Target Hook: bool TARGET_CANNOT_FORCE_CONST_MEM (rtx x)

该钩子应该返回真,如果x不能够(或不应该)被溢出到常量池中。 该钩子的缺省版本返回假。

定义该钩子的主要原因是阻止重载决定将一个不合法的常量从常量池中重载, 而不是溢出并重载一个寄存器来保存常量。对于不同的target, 该限制对于TLS符号的地址常常是真。

— Target Hook: bool TARGET_USE_BLOCKS_FOR_CONSTANT_P (enum machine_mode mode, rtx x)

该钩子应该返回真, 如果常量x的池实体(pool entries)可以放在一个object_block结构体中。 modex的机器模式。

缺省版本为所有的常量返回假。

— Target Hook: tree TARGET_BUILTIN_RECIPROCAL (enum tree_code fn, bool tm_fn, bool sqrt)

该钩子应该返回一个函数的decl,该函数实现了代码为fn的内建函数的倒数, 或者如果没有这样的函数,则返回NULL_TREE。 当fn为一个机器相关的内建函数的代码时,tm_fn为真。 当sqrt为真时,只对平方根函数进行额外的优化, 并且只有sqrt函数的倒数可用。

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD (void)

该钩子应该返回一个函数f的decl,给定一个地址addr作为参数, 该函数返回一个掩码m,在addr没有被适当的对齐时, 其可以用于从两个向量中抽取位于addr中的相关数据。

自动向量化,当向量化一个加载操作,且地址addr可以没有对齐, 则会生成两个向量加载,从addr附件的两个对齐的地址。 其然后生成一个REALIGN_LOAD操作,来从两个加载的向量中抽取相关数据。 REALIGN_LOAD的前两个参数,v1v2,为两个向量, 每个的大小为VS,第三个参数,OFF,定义了数据如何从这两个向量中抽取: 如果OFF为0,则返回的向量为V2; 否则返回的向量由v1的后VS-OFF个元素连接到v2的前OFF个元素而组成。

如果定义了该钩子,则自动向量化会生成一个对f的调用(使用该钩子返回的DECL) 并使用f的返回值作为REALIGN_LOAD的参数OFF。因此, f返回的掩码m应该遵守REALIGN_LOAD所期望的上面描述的语义。 如果该钩子没有被定义, 则addr将作为REALIGN_LOAD的参数OFF来使用, 这种情况下将会考虑addr的低log2(VS)-1位。

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN (tree x)

该钩子应该返回一个函数f的decl, 该函数实现了两个类型为x的输入向量作为偶数元素的加宽乘法。

如果定义了该钩子,则自动化向量当进行向量化加宽乘法时, 将会使用它和TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD target钩子, 以防结果顺序不需要被保存(例如,只用于减法计算)。 否则将使用widen_mult_hi/lo

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD (tree x)

该钩子应该返回一个函数f的decl, 该函数实现了两个类型为x的输入向量作为奇数元素的加宽乘法。

如果定义了该钩子,则自动化向量当进行向量化加宽乘法时, 将会使用它和TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN target钩子, 以防结果顺序不需要被保存(例如,只用于减法计算)。 否则将使用widen_mult_hi/lo

— Target Hook: int TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST (enum vect_cost_for_stmt type_of_cost, tree vectype, int misalign)

Returns cost of different scalar or vector statements for vectorization cost model. For vector memory operations the cost may depend on type (vectype) and misalignment value (misalign).

— Target Hook: bool TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE (const_tree type, bool is_packed)

Return true if vector alignment is reachable (by peeling N iterations) for the given type.

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_VEC_PERM (tree type, tree *mask_element_type)

Target builtin that implements vector permute.

— Target Hook: bool TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK (tree vec_type, tree mask)

Return true if a vector created for builtin_vec_perm is valid.

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_CONVERSION (enum tree_code code, tree type)

该钩子应该返回一个函数的decl,该函数实现了类型为type的输入向量的转换。 如果type为一个整数类型,则转换结果为一个同样大小的浮点类型的向量。 如果type为浮点类型,则转换结果为一个同样大小的整数类型的向量。 code指定了如何应用转换(截断,舍入,等)。

如果定义了该钩子,则自动向量化当进行向量化转换时, 会使用TARGET_VECTORIZE_BUILTIN_CONVERSION target钩子。 否则,其应该返回NULL_TREE

— Target Hook: tree TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION (enum built_in_function code, tree vec_type_out, tree vec_type_in)

该钩子应该返回一个函数的decl, 该函数实现了代码为code的内建函数的向量化变体, 或者如果没有这样的函数则返回NULL_TREE。 向量化的函数的返回类型应该为向量类型vec_type_out, 并且参数类型应该为vec_type_in

— Target Hook: bool TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT (enum machine_mode mode, const_tree type, int misalignment, bool is_packed)

This hook should return true if the target supports misaligned vector store/load of a specific factor denoted in the misalignment parameter. The vector store/load should be of machine mode mode and the elements in the vectors should be of type type. is_packed parameter is true if the memory access is defined in a packed struct.