native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
lzcnt.h
1// SPDX-FileCopyrightText: 2026 Edward Kmett <ekmett@gmail.com>
2// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
3#pragma once
4#include "native/config.h"
5#include "native/attributes.h"
6#include "native/isa.h"
7#include <bit>
8#include <cstdint>
9#if NATIVE_HOST_X86
10#include <immintrin.h>
11
12namespace native {
22 template<isa<x86> Arch> requires(Arch.has(x86_feature::lzcnt))
23 native_nodiscard native_inline native_const __attribute__((target("lzcnt")))
24 constexpr std::uint16_t lzcnt(std::uint16_t value) noexcept {
25 if (__builtin_is_constant_evaluated()) {
26 return static_cast<std::uint16_t>(std::countl_zero(value));
27 } else {
28 return __builtin_ia32_lzcnt_u16(value);
29 }
30 }
31
34 template<isa<x86> Arch> requires(Arch.has(x86_feature::lzcnt))
35 native_nodiscard native_inline native_const __attribute__((target("lzcnt")))
36 constexpr std::uint32_t lzcnt(std::uint32_t value) noexcept {
37 if (__builtin_is_constant_evaluated()) {
38 return static_cast<std::uint32_t>(std::countl_zero(value));
39 } else {
40 return _lzcnt_u32(value);
41 }
42 }
43
46 template<isa<x86> Arch> requires(Arch.has(x86_feature::lzcnt))
47 native_nodiscard native_inline native_const __attribute__((target("lzcnt")))
48 constexpr std::uint64_t lzcnt(std::uint64_t value) noexcept {
49 if (__builtin_is_constant_evaluated()) {
50 return static_cast<std::uint64_t>(std::countl_zero(value));
51 } else {
52 return _lzcnt_u64(value);
53 }
54 }
55
57 template<isa<x86> Arch> requires(!Arch.has(x86_feature::lzcnt))
59 consteval std::uint16_t lzcnt(std::uint16_t value) noexcept {
60 return lzcnt<isa<x86>{x86_feature::lzcnt}>(value);
61 }
62
64 template<isa<x86> Arch> requires(!Arch.has(x86_feature::lzcnt))
66 consteval std::uint32_t lzcnt(std::uint32_t value) noexcept {
67 return lzcnt<isa<x86>{x86_feature::lzcnt}>(value);
68 }
69
71 template<isa<x86> Arch> requires(!Arch.has(x86_feature::lzcnt))
73 consteval std::uint64_t lzcnt(std::uint64_t value) noexcept {
74 return lzcnt<isa<x86>{x86_feature::lzcnt}>(value);
75 }
76
78}
79#endif
Compiler attributes for host code, with shader-safe shared modifiers.
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
#define native_nodiscard
C++17 [[nodiscard]].
Definition attributes.h:189
#define native_const
[[const]] is not const
Definition attributes.h:108
constexpr std::uint16_t lzcnt(std::uint16_t value) noexcept
Definition lzcnt.h:24
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
constexpr int target
First matching requirement, with every later choice checked for shadowing.
Definition isa.h:396
Standard-library adaptations documented here for SIMD value types.