4#include "native/config.h"
13#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
14namespace native::detail::x86_f16c {
19 template<isa<x86> Arch,
unsigned Imm8,
class V>
20 requires(Arch.has(x86_feature::f16c) && Imm8 <= 255 && std::same_as<V, __m128>)
22 __m128i cvtps_ph(V a) noexcept {
27 __asm__
volatile(
"vcvtps2ph {%2, %1, %0|%0, %1, %2}"
28 :
"=x"(result) :
"x"(a),
"i"(Imm8) :
"memory");
33 template<isa<x86> Arch,
unsigned Imm8,
class V>
34 requires(Arch.has(x86_feature::f16c) && Imm8 <= 255 && std::same_as<V, __m256>)
36 __m128i cvtps_ph(V a)
noexcept {
38 __asm__
volatile(
"vcvtps2ph {%2, %1, %0|%0, %1, %2}"
39 :
"=x"(result) :
"x"(a),
"i"(Imm8) :
"memory");
44 template<isa<x86> Arch,
unsigned Lanes,
class V>
45 requires(Arch.has(x86_feature::f16c) && Lanes == 4 && std::same_as<V, __m128i>)
47 __m128 cvtph_ps(V a)
noexcept {
49 __asm__
volatile(
"vcvtph2ps {%1, %0|%0, %1}"
50 :
"=x"(result) :
"x"(a) :
"memory");
55 template<isa<x86> Arch,
unsigned Lanes,
class V>
56 requires(Arch.has(x86_feature::f16c) && Lanes == 8 && std::same_as<V, __m128i>)
58 __m256 cvtph_ps(V a)
noexcept {
60 __asm__
volatile(
"vcvtph2ps {%1, %0|%0, %1}"
61 :
"=x"(result) :
"x"(a) :
"memory");
66 template<isa<x86> Arch,
unsigned Imm8>
67 requires(Arch.has(x86_feature::f16c) && Imm8 <= 255)
69 std::uint16_t cvtss_sh(
float a)
noexcept {
70 return static_cast<std::uint16_t
>(_mm_cvtsi128_si32(cvtps_ph<Arch, Imm8>(_mm_set_ss(a))));
74 template<isa<x86> Arch>
requires(Arch.has(x86_feature::f16c))
76 float cvtsh_ss(std::uint16_t a)
noexcept {
77 return _mm_cvtss_f32(cvtph_ps<Arch, 4>(_mm_cvtsi32_si128(a)));
Compiler attributes for host code, with shader-safe shared modifiers.
#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.