gccint: Arithmetic
1
1 14.9 RTL Expressions for Arithmetic
1 ===================================
1
1 Unless otherwise specified, all the operands of arithmetic expressions
1 must be valid for mode M. An operand is valid for mode M if it has mode
1 M, or if it is a 'const_int' or 'const_double' and M is a mode of class
1 'MODE_INT'.
1
1 For commutative binary operations, constants should be placed in the
1 second operand.
1
1 '(plus:M X Y)'
1 '(ss_plus:M X Y)'
1 '(us_plus:M X Y)'
1
1 These three expressions all represent the sum of the values
1 represented by X and Y carried out in machine mode M. They differ
1 in their behavior on overflow of integer modes. 'plus' wraps round
1 modulo the width of M; 'ss_plus' saturates at the maximum signed
1 value representable in M; 'us_plus' saturates at the maximum
1 unsigned value.
1
1 '(lo_sum:M X Y)'
1
1 This expression represents the sum of X and the low-order bits of
1 Y. It is used with 'high' (⇒Constants) to represent the
1 typical two-instruction sequence used in RISC machines to reference
1 a global memory location.
1
1 The number of low order bits is machine-dependent but is normally
1 the number of bits in a 'Pmode' item minus the number of bits set
1 by 'high'.
1
1 M should be 'Pmode'.
1
1 '(minus:M X Y)'
1 '(ss_minus:M X Y)'
1 '(us_minus:M X Y)'
1
1 These three expressions represent the result of subtracting Y from
1 X, carried out in mode M. Behavior on overflow is the same as for
1 the three variants of 'plus' (see above).
1
1 '(compare:M X Y)'
1 Represents the result of subtracting Y from X for purposes of
1 comparison. The result is computed without overflow, as if with
1 infinite precision.
1
1 Of course, machines cannot really subtract with infinite precision.
1 However, they can pretend to do so when only the sign of the result
1 will be used, which is the case when the result is stored in the
1 condition code. And that is the _only_ way this kind of expression
1 may validly be used: as a value to be stored in the condition
1 codes, either '(cc0)' or a register. ⇒Comparisons.
1
1 The mode M is not related to the modes of X and Y, but instead is
1 the mode of the condition code value. If '(cc0)' is used, it is
1 'VOIDmode'. Otherwise it is some mode in class 'MODE_CC', often
1 'CCmode'. ⇒Condition Code. If M is 'VOIDmode' or 'CCmode',
1 the operation returns sufficient information (in an unspecified
1 format) so that any comparison operator can be applied to the
1 result of the 'COMPARE' operation. For other modes in class
1 'MODE_CC', the operation only returns a subset of this information.
1
1 Normally, X and Y must have the same mode. Otherwise, 'compare' is
1 valid only if the mode of X is in class 'MODE_INT' and Y is a
1 'const_int' or 'const_double' with mode 'VOIDmode'. The mode of X
1 determines what mode the comparison is to be done in; thus it must
1 not be 'VOIDmode'.
1
1 If one of the operands is a constant, it should be placed in the
1 second operand and the comparison code adjusted as appropriate.
1
1 A 'compare' specifying two 'VOIDmode' constants is not valid since
1 there is no way to know in what mode the comparison is to be
1 performed; the comparison must either be folded during the
1 compilation or the first operand must be loaded into a register
1 while its mode is still known.
1
1 '(neg:M X)'
1 '(ss_neg:M X)'
1 '(us_neg:M X)'
1 These two expressions represent the negation (subtraction from
1 zero) of the value represented by X, carried out in mode M. They
1 differ in the behavior on overflow of integer modes. In the case
1 of 'neg', the negation of the operand may be a number not
1 representable in mode M, in which case it is truncated to M.
1 'ss_neg' and 'us_neg' ensure that an out-of-bounds result saturates
1 to the maximum or minimum signed or unsigned value.
1
1 '(mult:M X Y)'
1 '(ss_mult:M X Y)'
1 '(us_mult:M X Y)'
1 Represents the signed product of the values represented by X and Y
1 carried out in machine mode M. 'ss_mult' and 'us_mult' ensure that
1 an out-of-bounds result saturates to the maximum or minimum signed
1 or unsigned value.
1
1 Some machines support a multiplication that generates a product
1 wider than the operands. Write the pattern for this as
1
1 (mult:M (sign_extend:M X) (sign_extend:M Y))
1
1 where M is wider than the modes of X and Y, which need not be the
1 same.
1
1 For unsigned widening multiplication, use the same idiom, but with
1 'zero_extend' instead of 'sign_extend'.
1
1 '(fma:M X Y Z)'
1 Represents the 'fma', 'fmaf', and 'fmal' builtin functions, which
1 compute 'X * Y + Z' without doing an intermediate rounding step.
1
1 '(div:M X Y)'
1 '(ss_div:M X Y)'
1 Represents the quotient in signed division of X by Y, carried out
1 in machine mode M. If M is a floating point mode, it represents
1 the exact quotient; otherwise, the integerized quotient. 'ss_div'
1 ensures that an out-of-bounds result saturates to the maximum or
1 minimum signed value.
1
1 Some machines have division instructions in which the operands and
1 quotient widths are not all the same; you should represent such
1 instructions using 'truncate' and 'sign_extend' as in,
1
1 (truncate:M1 (div:M2 X (sign_extend:M2 Y)))
1
1 '(udiv:M X Y)'
1 '(us_div:M X Y)'
1 Like 'div' but represents unsigned division. 'us_div' ensures that
1 an out-of-bounds result saturates to the maximum or minimum
1 unsigned value.
1
1 '(mod:M X Y)'
1 '(umod:M X Y)'
1 Like 'div' and 'udiv' but represent the remainder instead of the
1 quotient.
1
1 '(smin:M X Y)'
1 '(smax:M X Y)'
1 Represents the smaller (for 'smin') or larger (for 'smax') of X and
1 Y, interpreted as signed values in mode M. When used with floating
1 point, if both operands are zeros, or if either operand is 'NaN',
1 then it is unspecified which of the two operands is returned as the
1 result.
1
1 '(umin:M X Y)'
1 '(umax:M X Y)'
1 Like 'smin' and 'smax', but the values are interpreted as unsigned
1 integers.
1
1 '(not:M X)'
1 Represents the bitwise complement of the value represented by X,
1 carried out in mode M, which must be a fixed-point machine mode.
1
1 '(and:M X Y)'
1 Represents the bitwise logical-and of the values represented by X
1 and Y, carried out in machine mode M, which must be a fixed-point
1 machine mode.
1
1 '(ior:M X Y)'
1 Represents the bitwise inclusive-or of the values represented by X
1 and Y, carried out in machine mode M, which must be a fixed-point
1 mode.
1
1 '(xor:M X Y)'
1 Represents the bitwise exclusive-or of the values represented by X
1 and Y, carried out in machine mode M, which must be a fixed-point
1 mode.
1
1 '(ashift:M X C)'
1 '(ss_ashift:M X C)'
1 '(us_ashift:M X C)'
1 These three expressions represent the result of arithmetically
1 shifting X left by C places. They differ in their behavior on
1 overflow of integer modes. An 'ashift' operation is a plain shift
1 with no special behavior in case of a change in the sign bit;
1 'ss_ashift' and 'us_ashift' saturates to the minimum or maximum
1 representable value if any of the bits shifted out differs from the
1 final sign bit.
1
1 X have mode M, a fixed-point machine mode. C be a fixed-point mode
1 or be a constant with mode 'VOIDmode'; which mode is determined by
1 the mode called for in the machine description entry for the
1 left-shift instruction. For example, on the VAX, the mode of C is
1 'QImode' regardless of M.
1
1 '(lshiftrt:M X C)'
1 '(ashiftrt:M X C)'
1 Like 'ashift' but for right shift. Unlike the case for left shift,
1 these two operations are distinct.
1
1 '(rotate:M X C)'
1 '(rotatert:M X C)'
1 Similar but represent left and right rotate. If C is a constant,
1 use 'rotate'.
1
1 '(abs:M X)'
1 '(ss_abs:M X)'
1 Represents the absolute value of X, computed in mode M. 'ss_abs'
1 ensures that an out-of-bounds result saturates to the maximum
1 signed value.
1
1 '(sqrt:M X)'
1 Represents the square root of X, computed in mode M. Most often M
1 will be a floating point mode.
1
1 '(ffs:M X)'
1 Represents one plus the index of the least significant 1-bit in X,
1 represented as an integer of mode M. (The value is zero if X is
1 zero.) The mode of X must be M or 'VOIDmode'.
1
1 '(clrsb:M X)'
1 Represents the number of redundant leading sign bits in X,
1 represented as an integer of mode M, starting at the most
1 significant bit position. This is one less than the number of
1 leading sign bits (either 0 or 1), with no special cases. The mode
1 of X must be M or 'VOIDmode'.
1
1 '(clz:M X)'
1 Represents the number of leading 0-bits in X, represented as an
1 integer of mode M, starting at the most significant bit position.
1 If X is zero, the value is determined by
1 'CLZ_DEFINED_VALUE_AT_ZERO' (⇒Misc). Note that this is one
1 of the few expressions that is not invariant under widening. The
1 mode of X must be M or 'VOIDmode'.
1
1 '(ctz:M X)'
1 Represents the number of trailing 0-bits in X, represented as an
1 integer of mode M, starting at the least significant bit position.
1 If X is zero, the value is determined by
1 'CTZ_DEFINED_VALUE_AT_ZERO' (⇒Misc). Except for this case,
1 'ctz(x)' is equivalent to 'ffs(X) - 1'. The mode of X must be M or
1 'VOIDmode'.
1
1 '(popcount:M X)'
1 Represents the number of 1-bits in X, represented as an integer of
1 mode M. The mode of X must be M or 'VOIDmode'.
1
1 '(parity:M X)'
1 Represents the number of 1-bits modulo 2 in X, represented as an
1 integer of mode M. The mode of X must be M or 'VOIDmode'.
1
1 '(bswap:M X)'
1 Represents the value X with the order of bytes reversed, carried
1 out in mode M, which must be a fixed-point machine mode. The mode
1 of X must be M or 'VOIDmode'.
1