pub enum BuiltinOp {
Show 19 variants
Popcount,
Clz,
Ctz,
Ffs,
Parity,
Clrsb,
Bswap,
Overflow(BinOp),
OverflowP(BinOp),
Discard,
Prefetch(u8),
Alloca,
Fabs,
Copysign,
FloatOrder(FloatOrder),
FloatClass(FloatClass),
Fpclassify,
CpuSupports(u8),
ComplexProj,
}Expand description
A GNU builtin that becomes a fixed piece of Rust rather than a call.
The bit-manipulation ones map onto the integer methods of the same name;
the overflow ones do the arithmetic in i128 and check the result against
the range of the type it is stored in, which is exactly the “compute in
infinite precision, then convert” the builtins are defined by.
Variants§
Popcount
__builtin_popcount…
Clz
__builtin_clz…; undefined for zero in C, and this follows Rust.
Ctz
__builtin_ctz…
Ffs
__builtin_ffs…: one more than the index of the lowest set bit, or 0.
Parity
__builtin_parity…
Clrsb
__builtin_clrsb…: leading redundant sign bits.
Bswap
__builtin_bswap16/32/64
Overflow(BinOp)
__builtin_{add,sub,mul}_overflow(a, b, &r), whose value is the flag.
OverflowP(BinOp)
The _p forms, which only ask whether it would overflow.
Discard
Evaluate the operands and produce nothing: __builtin_assume and
__builtin_speculation_safe_value, which promise something the
generated code cannot pass on.
Prefetch(u8)
__builtin_prefetch(p, rw, locality), whose one operand is p
converted to const void *. The payload is the two constants packed
into one byte, locality | rw << 2, so that BuiltinOp stays two
bytes wide (see BuiltinOp::CpuSupports); prefetch_hint takes
it apart.
On x86 it is _mm_prefetch with the locality’s hint, on AArch64 a
prfm, and anywhere else — or in a safe function,
where the call would need unsafe — the operand is evaluated and the
hint dropped, which is always a correct translation of a hint.
Alloca
__builtin_alloca(size), whose one operand is the size in bytes,
converted to size_t.
The memory comes out of the arena Function::uses_arena puts at the
top of the function, and no variable length array’s end of scope gives
it back, so it is freed by the return — which is alloca’s own
lifetime.
Fabs
__builtin_fabs…: the sign bit cleared, which is what C’s fabs is
defined as and what makes it exact for a NaN and for a zero.
Copysign
__builtin_copysign…: the first operand’s magnitude with the second
operand’s sign bit.
FloatOrder(FloatOrder)
One of the quiet comparison macros’ builtins, whose value is an int.
FloatClass(FloatClass)
One of the classification builtins, whose value is an int.
Fpclassify
__builtin_fpclassify(nan, inf, normal, subnormal, zero, x): the one
of the first five operands the sixth one’s class selects.
CpuSupports(u8)
__builtin_cpu_supports("avx2"): whether the processor running the
program has that instruction set, as an int.
It becomes ::std::is_x86_feature_detected!("avx2"), which is the same
question asked of the same cpuid leaves. The payload is the row of
crate::x86::TARGET_FEATURES the instruction set is in, so that
BuiltinOp stays two bytes wide — it is a field of ExprKind, and
every expression in the program pays for whatever the largest variant
is. Several Rust features for one GCC name (abm is LZCNT and POPCNT)
are &&ed together; crate::x86::detect_features is the lookup.
ComplexProj
__builtin_cproj(z): C99 7.3.9.5’s projection onto the Riemann sphere.
Everything is itself except a value with an infinite part, which becomes
+∞ with the imaginary part’s sign kept on a zero — so every infinity
is the one point at infinity.