3#include "native/isa_import.h"
4#include "native/x86/f16c.h"
5#include "native/detail/constexpr_float.h"
6#include "native/targets.h"
11#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
12namespace native::detail {
13 template<
unsigned Imm8>
constexpr auto f16c_rounding() noexcept {
14 using r=constexpr_float::rounding;
15 if constexpr(Imm8&4)
return r::nearest_even;
16 else if constexpr((Imm8&3)==1)
return r::downward;
17 else if constexpr((Imm8&3)==2)
return r::upward;
18 else if constexpr((Imm8&3)==3)
return r::toward_zero;
19 else return r::nearest_even;
21 template<isa<x86> Arch,
unsigned Imm8,std::
size_t N>
22 consteval simd<fp16,N,Arch> f16c_narrow(simd<float,N,Arch> input)
noexcept {
23 std::array<float,N> values{};input.store(values.data());
24 auto source=std::bit_cast<std::array<std::uint32_t,N>>(values);
25 std::array<std::uint16_t,N> result{};
26 for(std::size_t i=0;i<N;++i) result[i]=constexpr_float::convert_bits<
27 constexpr_float::binary16,constexpr_float::binary32>(source[i],f16c_rounding<Imm8>());
28 return simd<fp16,N,Arch>::load_bits(result.data());
30 template<isa<x86> Arch,std::
size_t N>
31 consteval simd<float,N,Arch> f16c_widen(simd<fp16,N,Arch> input)
noexcept {
32 std::array<std::uint16_t,N> source{};
33 std::array<std::uint32_t,N> result{};
34 input.store_bits(source.data());
35 for(std::size_t i=0;i<N;++i) result[i]=constexpr_float::convert_bits<
36 constexpr_float::binary32,constexpr_float::binary16>(source[i]);
37 auto values=std::bit_cast<std::array<float,N>>(result);
38 return simd<float,N,Arch>::load(values.data());
70 template<isa<x86> Arch,
unsigned Imm8>
71 requires(Arch.has(x86_feature::f16c) && Imm8 <= 255)
74 if consteval {
return detail::f16c_narrow<Arch,Imm8>(a); }
else {
77 detail::x86_f16c::cvtps_ph<Arch, Imm8>(a.to_native()));
82 template<isa<x86> Arch,
unsigned Imm8>
83 requires(
requires {
sizeof(simd<float,4,Arch>);
sizeof(simd<fp16,4,Arch>); } && !Arch.has(x86_feature::f16c) && Imm8 <= 255)
86 return detail::f16c_narrow<Arch,Imm8>(a);
90 template<isa<x86> Arch,
unsigned Imm8>
91 requires(Arch.has(x86_feature::f16c) && Imm8 <= 255)
94 if consteval {
return detail::f16c_narrow<Arch,Imm8>(a); }
else {
96 detail::x86_f16c::cvtps_ph<Arch, Imm8>(a.to_native()));
101 template<isa<x86> Arch,
unsigned Imm8>
102 requires(
requires {
sizeof(simd<float,8,Arch>);
sizeof(simd<fp16,8,Arch>); } && !Arch.has(x86_feature::f16c) && Imm8 <= 255)
105 return detail::f16c_narrow<Arch,Imm8>(a);
109 template<isa<x86> Arch,
unsigned Lanes>
110 requires(Arch.has(x86_feature::f16c) && Lanes == 4)
113 if consteval {
return detail::f16c_widen<Arch>(a); }
else {
115 detail::x86_f16c::cvtph_ps<Arch, 4>(a.to_native()));
120 template<isa<x86> Arch,
unsigned Lanes>
121 requires(
requires {
sizeof(simd<float,4,Arch>);
sizeof(simd<fp16,4,Arch>); } && !Arch.has(x86_feature::f16c) && Lanes == 4)
124 return detail::f16c_widen<Arch>(a);
128 template<isa<x86> Arch,
unsigned Lanes>
129 requires(Arch.has(x86_feature::f16c) && Lanes == 8)
132 if consteval {
return detail::f16c_widen<Arch>(a); }
else {
134 detail::x86_f16c::cvtph_ps<Arch, 8>(a.to_native()));
139 template<isa<x86> Arch,
unsigned Lanes>
140 requires(
requires {
sizeof(simd<float,8,Arch>);
sizeof(simd<fp16,8,Arch>); } && !Arch.has(x86_feature::f16c) && Lanes == 8)
143 return detail::f16c_widen<Arch>(a);
147 template<isa<x86> Arch,
unsigned Imm8>
148 requires(Arch.has(x86_feature::f16c) && Imm8 <= 255)
151 if consteval {
return detail::constexpr_float::convert_bits<detail::constexpr_float::binary16,
152 detail::constexpr_float::binary32>(std::bit_cast<std::uint32_t>(a),detail::f16c_rounding<Imm8>()); }
else {
153 return detail::x86_f16c::cvtss_sh<Arch, Imm8>(a);
158 template<isa<x86> Arch,
unsigned Imm8>
159 requires(!Arch.has(x86_feature::f16c) && Imm8 <= 255)
162 return detail::constexpr_float::convert_bits<detail::constexpr_float::binary16,
163 detail::constexpr_float::binary32>(std::bit_cast<std::uint32_t>(a),detail::f16c_rounding<Imm8>());
168 template<
unsigned Imm8, isa<x86> Arch = NATIVE_BA
SELINE>
169 requires(Arch.has(x86_feature::f16c) && Imm8 <= 255)
172 if consteval {
return detail::constexpr_float::convert_bits<detail::constexpr_float::binary16,
173 detail::constexpr_float::binary32>(std::bit_cast<std::uint32_t>(a),detail::f16c_rounding<Imm8>()); }
else {
179 template<
unsigned Imm8, isa<x86> Arch = NATIVE_BA
SELINE>
180 requires(!Arch.has(x86_feature::f16c) && Imm8 <= 255)
183 return detail::constexpr_float::convert_bits<detail::constexpr_float::binary16,
184 detail::constexpr_float::binary32>(std::bit_cast<std::uint32_t>(a),detail::f16c_rounding<Imm8>());
188 template<isa<x86> Arch = NATIVE_BA
SELINE>
requires(Arch.has(x86_feature::f16c))
191 if consteval {
return std::bit_cast<float>(detail::constexpr_float::convert_bits<
192 detail::constexpr_float::binary32,detail::constexpr_float::binary16>(a)); }
else {
193 return detail::x86_f16c::cvtsh_ss<Arch>(a);
198 template<isa<x86> Arch = NATIVE_BA
SELINE>
requires(!Arch.has(x86_feature::f16c))
201 return std::bit_cast<float>(detail::constexpr_float::convert_bits<
202 detail::constexpr_float::binary32,detail::constexpr_float::binary16>(a));
206 template<isa<x86> Arch,
unsigned Imm8,
class V>
void cvtps_ph(V) =
delete;
208 template<isa<x86> Arch,
unsigned Lanes,
class V>
void cvtph_ps(V) =
delete;
#define native_inline
inline [[always_inline]]
#define native_nodiscard
C++17 [[nodiscard]].
#define native_target(x)
this indicates a required feature set for the current multiversioned function.
constexpr simd< fp16, 4, Arch > cvtps_ph(simd< float, 4, Arch > a) noexcept
Convert 4 binary32 lanes to 4 binary16 lanes.
constexpr simd< float, 4, Arch > cvtph_ps(simd< fp16, 4, Arch > a) noexcept
Widen 4 binary16 lanes to 4 binary32 lanes.
constexpr std::uint16_t cvtss_sh(float a) noexcept
Convert one binary32 value to binary16 representation bits.
constexpr float cvtsh_ss(std::uint16_t a) noexcept
Widen one binary16 representation to binary32.
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
Omitted architecture arguments use the native.simd provider's baseline.