Unless otherwise specified, all the operands of arithmetic expressions
must be valid for mode m. An operand is valid for mode m
if it has mode m, or if it is a
const_double and m is a mode of class
For commutative binary operations, constants should be placed in the second operand.
(plus:m x y
(ss_plus:m x y
(us_plus:m x y
pluswraps round modulo the width of m;
ss_plussaturates at the maximum signed value representable in m;
us_plussaturates at the maximum unsigned value.
(lo_sum:m x y
high(see Constants) to represent the typical two-instruction sequence used in RISC machines to reference a global memory location.
The number of low order bits is machine-dependent but is
normally the number of bits in a
Pmode item minus the number of
bits set by
m should be
(minus:m x y
(ss_minus:m x y
(us_minus:m x y
(compare:m x y
Of course, machines can't really subtract with infinite precision.
However, they can pretend to do so when only the sign of the result will
be used, which is the case when the result is stored in the condition
code. And that is the only way this kind of expression may
validly be used: as a value to be stored in the condition codes, either
(cc0) or a register. See Comparisons.
The mode m is not related to the modes of x and y, but
instead is the mode of the condition code value. If
used, it is
VOIDmode. Otherwise it is some mode in class
CCmode. See Condition Code. If m
CCmode, the operation returns sufficient
information (in an unspecified format) so that any comparison operator
can be applied to the result of the
COMPARE operation. For other
modes in class
MODE_CC, the operation only returns a subset of
Normally, x and y must have the same mode. Otherwise,
compare is valid only if the mode of x is in class
MODE_INT and y is a
const_double with mode
VOIDmode. The mode of x
determines what mode the comparison is to be done in; thus it must not
If one of the operands is a constant, it should be placed in the second operand and the comparison code adjusted as appropriate.
compare specifying two
VOIDmode constants is not valid
since there is no way to know in what mode the comparison is to be
performed; the comparison must either be folded during the compilation
or the first operand must be loaded into a register while its mode is
neg, the negation of the operand may be a number not representable in mode m, in which case it is truncated to m.
us_negensure that an out-of-bounds result saturates to the maximum or minimum signed or unsigned value.
(mult:m x y
(ss_mult:m x y
(us_mult:m x y
us_multensure that an out-of-bounds result saturates to the maximum or minimum signed or unsigned value.
Some machines support a multiplication that generates a product wider than the operands. Write the pattern for this as
(mult:m (sign_extend:m x) (sign_extend:m y))
where m is wider than the modes of x and y, which need not be the same.
For unsigned widening multiplication, use the same idiom, but with
zero_extend instead of
(fma:m x y z
fmalbuiltin functions that do a combined multiply of x and y and then adding toz without doing an intermediate rounding step.
(div:m x y
(ss_div:m x y
ss_divensures that an out-of-bounds result saturates to the maximum or minimum signed value.
Some machines have division instructions in which the operands and
quotient widths are not all the same; you should represent
such instructions using
sign_extend as in,
(truncate:m1 (div:m2 x (sign_extend:m2 y)))
(udiv:m x y
(us_div:m x y
divbut represents unsigned division.
us_divensures that an out-of-bounds result saturates to the maximum or minimum unsigned value.
(mod:m x y
(umod:m x y
udivbut represent the remainder instead of the quotient.
(smin:m x y
(smax:m x y
smin) or larger (for
smax) of x and y, interpreted as signed values in mode m. When used with floating point, if both operands are zeros, or if either operand is
NaN, then it is unspecified which of the two operands is returned as the result.
(umin:m x y
(umax:m x y
smax, but the values are interpreted as unsigned integers.
(and:m x y
(ior:m x y
(xor:m x y
(ashift:m x c
(ss_ashift:m x c
(us_ashift:m x c
ashiftoperation is a plain shift with no special behavior in case of a change in the sign bit;
us_ashiftsaturates to the minimum or maximum representable value if any of the bits shifted out differs from the final sign bit.
x have mode m, a fixed-point machine mode. c
be a fixed-point mode or be a constant with mode
mode is determined by the mode called for in the machine description
entry for the left-shift instruction. For example, on the VAX, the mode
of c is
QImode regardless of m.
(lshiftrt:m x c
(ashiftrt:m x c
ashiftbut for right shift. Unlike the case for left shift, these two operations are distinct.
(rotate:m x c
(rotatert:m x c
ss_absensures that an out-of-bounds result saturates to the maximum signed value.
CLZ_DEFINED_VALUE_AT_ZERO(see Misc). Note that this is one of the few expressions that is not invariant under widening. The mode of x will usually be an integer mode.
CTZ_DEFINED_VALUE_AT_ZERO(see Misc). Except for this case,
ctz(x)is equivalent to
) - 1. The mode of x will usually be an integer mode.