Constant Expression Types#
The simplest RTL expressions are those that represent constant values.
(const_int i)This type of expression represents the integer value
i.iis customarily accessed with the macroINTVALas inINTVAL (exp), which is equivalent toXWINT (exp, 0).Constants generated for modes with fewer bits than in
HOST_WIDE_INTmust be sign extended to full width (e.g., withgen_int_mode). For constants for modes with more bits than inHOST_WIDE_INTthe implied high order bits of that constant are copies of the top bit. Note however that values are neither inherently signed nor inherently unsigned; where necessary, signedness is determined by the rtl operation instead.There is only one expression object for the integer value zero; it is the value of the variable
const0_rtx. Likewise, the only expression for integer value one is found inconst1_rtx, the only expression for integer value two is found inconst2_rtx, and the only expression for integer value negative one is found inconstm1_rtx. Any attempt to create an expression of codeconst_intand value zero, one, two or negative one will returnconst0_rtx,const1_rtx,const2_rtxorconstm1_rtxas appropriate.Similarly, there is only one object for the integer whose value is
STORE_FLAG_VALUE. It is found inconst_true_rtx. IfSTORE_FLAG_VALUEis one,const_true_rtxandconst1_rtxwill point to the same object. IfSTORE_FLAG_VALUEis -1,const_true_rtxandconstm1_rtxwill point to the same object.(const_double:m i0 i1 ...)This represents either a floating-point constant of mode
mor (on older ports that do not defineTARGET_SUPPORTS_WIDE_INT) an integer constant too large to fit intoHOST_BITS_PER_WIDE_INTbits but small enough to fit within twice that number of bits. In the latter case,mwill beVOIDmode. For integral values constants for modes with more bits than twice the number inHOST_WIDE_INTthe implied high order bits of that constant are copies of the top bit ofCONST_DOUBLE_HIGH. Note however that integral values are neither inherently signed nor inherently unsigned; where necessary, signedness is determined by the rtl operation instead.On more modern ports,
CONST_DOUBLEonly represents floating point values. New ports defineTARGET_SUPPORTS_WIDE_INTto make this designation.If
misVOIDmode, the bits of the value are stored ini0andi1.i0is customarily accessed with the macroCONST_DOUBLE_LOWandi1withCONST_DOUBLE_HIGH.If the constant is floating point (regardless of its precision), then the number of integers used to store the value depends on the size of
REAL_VALUE_TYPE(see Cross Compilation and Floating Point). The integers represent a floating point number, but not precisely in the target machine’s or host machine’s floating point format. To convert them to the precise bit pattern used by the target machine, use the macroREAL_VALUE_TO_TARGET_DOUBLEand friends (see Output of Data).The host dependency for the number of integers used to store a double value makes it problematic for machine descriptions to use expressions of code
const_doubleand therefore a syntactic alias has been provided:(const_double_zero:m)
standing for:
(const_double:m 0 0 ...)
for matching the floating-point value zero, possibly the only useful one.
(const_wide_int:m nunits elt0 ...)This contains an array of
HOST_WIDE_INTs that is large enough to hold any constant that can be represented on the target. This form of rtl is only used on targets that defineTARGET_SUPPORTS_WIDE_INTto be nonzero and thenCONST_DOUBLEs are only used to hold floating-point values. If the target leavesTARGET_SUPPORTS_WIDE_INTdefined as 0,CONST_WIDE_INTs are not used andCONST_DOUBLEs are as they were before.The values are stored in a compressed format. The higher-order 0s or -1s are not represented if they are just the logical sign extension of the number that is represented.
CONST_WIDE_INT_VEC (code)Returns the entire array of
HOST_WIDE_INTs that are used to store the value. This macro should be rarely used.CONST_WIDE_INT_NUNITS (code)The number of
HOST_WIDE_INTs used to represent the number. Note that this generally is smaller than the number ofHOST_WIDE_INTs implied by the mode size.CONST_WIDE_INT_ELT (code,i)Returns the
ith element of the array. Element 0 is contains the low order bits of the constant.(const_fixed:m ...)Represents a fixed-point constant of mode
m. The operand is a data structure of typestruct fixed_valueand is accessed with the macroCONST_FIXED_VALUE. The high part of data is accessed withCONST_FIXED_VALUE_HIGH; the low part is accessed withCONST_FIXED_VALUE_LOW.(const_poly_int:m [c0 c1 ...])Represents a
poly_int-style polynomial integer with coefficientsc0,c1, …. The coefficients arewide_int-based integers rather than rtxes.CONST_POLY_INT_COEFFSgives the values of individual coefficients (which is mostly only useful in low-level routines) andconst_poly_int_valuegives the fullpoly_intvalue.(const_vector:m [x0 x1 ...])Represents a vector constant. The values in square brackets are elements of the vector, which are always
const_int,const_wide_int,const_doubleorconst_fixedexpressions.Each vector constant
vis treated as a specific instance of an arbitrary-length sequence that itself containsCONST_VECTOR_NPATTERNS (v)interleaved patterns. Each pattern has the form:{ base0, base1, base1 + step, base1 + step * 2, ... }
The first three elements in each pattern are enough to determine the values of the other elements. However, if all
steps are zero, only the first two elements are needed. If in addition eachbase1is equal to the correspondingbase0, only the first element in each pattern is needed. The number of determining elements per pattern is given byCONST_VECTOR_NELTS_PER_PATTERN (v).For example, the constant:
{ 0, 1, 2, 6, 3, 8, 4, 10, 5, 12, 6, 14, 7, 16, 8, 18 }
is interpreted as an interleaving of the sequences:
{ 0, 2, 3, 4, 5, 6, 7, 8 } { 1, 6, 8, 10, 12, 14, 16, 18 }
where the sequences are represented by the following patterns:
base0 == 0, base1 == 2, step == 1 base0 == 1, base1 == 6, step == 2
In this case:
CONST_VECTOR_NPATTERNS (v) == 2 CONST_VECTOR_NELTS_PER_PATTERN (v) == 3
Thus the first 6 elements (
0, 1, 2, 6, 3, 8) are enough to determine the whole sequence; we refer to them as the ‘encoded’ elements. They are the only elements present in the square brackets for variable-lengthconst_vectors (i.e. forconst_vectors whose modemhas a variable number of elements). However, as a convenience to code that needs to handle bothconst_vectors andparallels, all elements are present in the square brackets for fixed-lengthconst_vectors; the encoding scheme simply reduces the amount of work involved in processing constants that follow a regular pattern.Sometimes this scheme can create two possible encodings of the same vector. For example { 0, 1 } could be seen as two patterns with one element each or one pattern with two elements (
base0andbase1). The canonical encoding is always the one with the fewest patterns or (if both encodings have the same number of petterns) the one with the fewest encoded elements.const_vector_encoding_nelts (v)gives the total number of encoded elements inv, which is 6 in the example above.CONST_VECTOR_ENCODED_ELT (v, i)accesses the value of encoded elementi.CONST_VECTOR_DUPLICATE_P (v)is true ifvsimply contains repeated instances ofCONST_VECTOR_NPATTERNS (v)values. This is a shorthand for testingCONST_VECTOR_NELTS_PER_PATTERN (v) == 1.CONST_VECTOR_STEPPED_P (v)is true if at least one pattern invhas a nonzero step. This is a shorthand for testingCONST_VECTOR_NELTS_PER_PATTERN (v) == 3.CONST_VECTOR_NUNITS (v)gives the total number of elements inv; it is a shorthand for getting the number of units inGET_MODE (v).The utility function
const_vector_eltgives the value of an arbitrary element as anrtx.const_vector_int_eltgives the same value as awide_int.(const_string str)Represents a constant string with value
str. Currently this is used only for insn attributes (see Instruction Attributes) since constant strings in C are placed in memory.(symbol_ref:mode symbol)Represents the value of an assembler label for data.
symbolis a string that describes the name of the assembler label. If it starts with a*, the label is the rest ofsymbolnot including the*. Otherwise, the label issymbol, usually prefixed with_.The
symbol_refcontains a mode, which is usuallyPmode. Usually that is the only mode for which a symbol is directly valid.(label_ref:mode label)Represents the value of an assembler label for code. It contains one operand, an expression, which must be a
code_labelor anoteof typeNOTE_INSN_DELETED_LABELthat appears in the instruction sequence to identify the place where the label should go.The reason for using a distinct expression type for code label references is so that jump optimization can distinguish them.
The
label_refcontains a mode, which is usuallyPmode. Usually that is the only mode for which a label is directly valid.(const:m exp)Represents a constant that is the result of an assembly-time arithmetic computation. The operand,
exp, contains onlyconst_int,symbol_ref,label_reforunspecexpressions, combined withplusandminus. Any suchunspecs are target-specific and typically represent some form of relocation operator.mshould be a valid address mode.(high:m exp)Represents the high-order bits of
exp. The number of bits is machine-dependent and is normally the number of bits specified in an instruction that initializes the high order bits of a register. It is used withlo_sumto represent the typical two-instruction sequence used in RISC machines to reference large immediate values and/or link-time constants such as global memory addresses. In the latter case,misPmodeandexpis usually a constant expression involvingsymbol_ref.
The macro CONST0_RTX (mode) refers to an expression with
value 0 in mode mode. If mode mode is of mode class
MODE_INT, it returns const0_rtx. If mode mode is of
mode class MODE_FLOAT, it returns a CONST_DOUBLE
expression in mode mode. Otherwise, it returns a
CONST_VECTOR expression in mode mode. Similarly, the macro
CONST1_RTX (mode) refers to an expression with value 1 in
mode mode and similarly for CONST2_RTX. The
CONST1_RTX and CONST2_RTX macros are undefined
for vector modes.