|
native 0.0.1
Vectors, masks and wide register packs for C++26
|
Half precision saves space when data can tolerate a smaller range and fewer significant bits. F16C converts between stored IEEE binary16 and binary32, so an algorithm can keep its arithmetic in float while loading and storing halves.
import native.x86.f16c; exports the following operations through native::native. native.x86 and native re-export it.
| Call | Input | Output |
|---|---|---|
| cvtss_sh<Arch, Imm8>(x) | float | std::uint16_t half bits |
| cvtsh_ss<Arch>(h) | std::uint16_t half bits | float |
| cvtps_ph<Arch, Imm8>(x) | simd<float,N,Arch> | simd<fp16,N,Arch> |
| cvtph_ps<Arch, N>(h) | simd<fp16,N,Arch> | simd<float,N,Arch> |
Packed forms have N = 4 or 8; the widening lane count must match the half vector. fp16::from_bits() and to_bits() connect scalar storage to its representation. Half-vector loads and stores transfer elements without numerical conversion; the four-lane narrowing result clears physical padding.
The scalar forms also accept cvtss_sh<Imm8>(x) and cvtsh_ss(h) using the module default tag, or cvtss_sh<Imm8, Arch>(x) with an explicit tag. All calls are noexcept.
Imm8 is in 0–255. With bit 2 clear, bits 1:0 select nearest-even, downward, upward or toward-zero rounding. Bit 2 selects MXCSR rounding. Bits 7:3 are ignored: _MM_FROUND_NO_EXC does not suppress F16C exceptions. Use 0 for nearest-even or 4 for MXCSR rounding.
Widening is exact for finite inputs, including half subnormals, regardless of DAZ. Narrowing honors DAZ for binary32 subnormals and ignores FTZ; tiny results can become half subnormals or signed zero. Overflow follows the selected rounding direction. Both conversions preserve signs and high NaN payload bits, quieting NaNs; signaling NaNs raise invalid.
Widening can signal invalid. Narrowing can signal invalid, denormal, overflow, underflow and precision; status accumulates in MXCSR and unmasked exceptions can trap. With DM masked and UM or PM unmasked, binary32 subnormal input can trap with DE, UE and PE set. Exact tiny results can trap with underflow unmasked. noexcept only concerns C++ exceptions. Calls retain the conversion instruction and its ordering with MXCSR access even when the numerical result is unused.
Runtime calls need F16C, AVX storage and enabled XMM/YMM state. Use target_features<native::x86>("f16c"), a matching target and admission before entry. Neither AVX2 nor AVX512FP16 is required. F16C provides conversion, not half arithmetic. Scalar defaults use the provider's NATIVE_BASELINE, which caller target attributes do not change.
Feature-bearing overloads are constexpr with native runtime paths. Without F16C, scalar calls and packed calls with complete storage are consteval-only. Constant evaluation assumes masked exceptions, gradual inputs and outputs, and nearest-even when the immediate selects MXCSR. It neither updates FP flags nor traps.
See Intel's VCVTPS2PH definition and F16C floating-point rules.