Skip to content

Commit 81a8da8

Browse files
committed
Refactor leaf check
1 parent 48cd2dd commit 81a8da8

1 file changed

Lines changed: 45 additions & 47 deletions

File tree

include/xsimd/config/xsimd_cpu_features_x86.hpp

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -586,74 +586,72 @@ namespace xsimd
586586
return m_leaf0;
587587
}
588588

589-
inline x86_cpuid_leaf1 const& leaf1() const
589+
inline x86_cpuid_leaf80000000 const& leaf80000000() const
590590
{
591-
if (!m_status.bit_is_set<status::leaf1_valid>())
591+
if (!m_status.bit_is_set<status::leaf80000000_valid>())
592592
{
593-
// Check if safe to call CPUID with this value
594-
if (leaf0().highest_leaf() >= x86_cpuid_leaf1::leaf)
595-
{
596-
m_leaf1 = x86_cpuid_leaf1::read();
597-
}
598-
// Otherwise leave it filled with zeros and mark as valid
599-
m_status.set_bit<status::leaf1_valid>();
593+
m_leaf80000000 = x86_cpuid_leaf80000000::read();
594+
m_status.set_bit<status::leaf80000000_valid>();
600595
}
601-
return m_leaf1;
596+
return m_leaf80000000;
602597
}
603598

604-
inline x86_cpuid_leaf7 const& leaf7() const
599+
template <status status_id, typename L>
600+
inline auto const& safe_get_leaf(L& leaf) const
605601
{
606-
if (!m_status.bit_is_set<status::leaf7_valid>())
602+
// Check if already initialized
603+
if (m_status.bit_is_set<status_id>())
607604
{
608-
// Check if safe to call CPUID with this value
609-
if (leaf0().highest_leaf() >= x86_cpuid_leaf7::leaf)
605+
return leaf;
606+
}
607+
608+
// Limit where we need to check leaf0 or leaf 80000000.
609+
constexpr auto extended_threshold = x86_cpuid_leaf80000000::leaf;
610+
611+
// Check if safe to call CPUID with this value.
612+
// First we identify if the leaf is in the regular or extended range.
613+
// TODO(C++17): if constexpr
614+
if (L::leaf < extended_threshold)
615+
{
616+
// Check leaf0 in regular range
617+
if (L::leaf <= leaf0().highest_leaf())
610618
{
611-
m_leaf7 = x86_cpuid_leaf7::read();
619+
leaf = L::read();
612620
}
613-
// Otherwise leave it filled with zeros and mark as valid
614-
m_status.set_bit<status::leaf7_valid>();
615621
}
616-
return m_leaf7;
617-
}
618-
619-
inline x86_cpuid_leaf7sub1 const& leaf7sub1() const
620-
{
621-
if (!m_status.bit_is_set<status::leaf7sub1_valid>())
622+
else
622623
{
623-
// Check if safe to call CPUID with this value
624-
if (leaf0().highest_leaf() >= x86_cpuid_leaf7::leaf)
624+
// Check leaf80000000 in extended range
625+
if (L::leaf <= leaf80000000().highest_leaf())
625626
{
626-
m_leaf7sub1 = x86_cpuid_leaf7sub1::read();
627+
leaf = L::read();
627628
}
628-
// Otherwise leave it filled with zeros and mark as valid
629-
m_status.set_bit<status::leaf7sub1_valid>();
630629
}
631-
return m_leaf7sub1;
630+
631+
// Mark as valid in all cases, including if it was not read.
632+
// In this case it will be filled with zeros (all false).
633+
m_status.set_bit<status_id>();
634+
return leaf;
632635
}
633636

634-
inline x86_cpuid_leaf80000000 const& leaf80000000() const
637+
inline x86_cpuid_leaf1 const& leaf1() const
635638
{
636-
if (!m_status.bit_is_set<status::leaf80000000_valid>())
637-
{
638-
m_leaf80000000 = x86_cpuid_leaf80000000::read();
639-
m_status.set_bit<status::leaf80000000_valid>();
640-
}
641-
return m_leaf80000000;
639+
return safe_get_leaf<status::leaf1_valid>(m_leaf1);
640+
}
641+
642+
inline x86_cpuid_leaf7 const& leaf7() const
643+
{
644+
return safe_get_leaf<status::leaf7_valid>(m_leaf7);
645+
}
646+
647+
inline x86_cpuid_leaf7sub1 const& leaf7sub1() const
648+
{
649+
return safe_get_leaf<status::leaf7sub1_valid>(m_leaf7sub1);
642650
}
643651

644652
inline x86_cpuid_leaf80000001 const& leaf80000001() const
645653
{
646-
if (!m_status.bit_is_set<status::leaf80000001_valid>())
647-
{
648-
// Check if safe to call CPUID with this value
649-
if (leaf80000000().highest_leaf() >= x86_cpuid_leaf80000001::leaf)
650-
{
651-
m_leaf80000001 = x86_cpuid_leaf80000001::read();
652-
}
653-
// Otherwise leave it filled with zeros and mark as valid
654-
m_status.set_bit<status::leaf80000001_valid>();
655-
}
656-
return m_leaf80000001;
654+
return safe_get_leaf<status::leaf80000001_valid>(m_leaf80000001);
657655
}
658656
};
659657

0 commit comments

Comments
 (0)