@@ -603,13 +603,32 @@ namespace xsimd
603603 return m_leaf80000000;
604604 }
605605
606+ /* *
607+ * Internal utility to lazily read and cache a CPUID leaf.
608+ *
609+ * @tparam status_id The status bit tracking whether this leaf has been read and cached.
610+ * @tparam L The CPUID leaf type (e.g. x86_cpuid_leaf1, x86_cpuid_leaf7).
611+ * @param leaf_cache A non-const reference to the class member that stores the leaf
612+ * value. It must be non-const because this function may write to it on first
613+ * call. It is passed explicitly (rather than accessed via `this`) to allow
614+ * factoring the caching logic across different leaf members.
615+ * @return A const reference to `leaf_cache`. The non-const input / const-ref output
616+ * asymmetry is intentional: callers must not modify the cached value, but
617+ * this function needs write access to populate it.
618+ *
619+ * On first call, checks whether the leaf number is within the range advertised as
620+ * supported by CPUID (via leaf 0 for the standard range, leaf 0x80000000 for the
621+ * extended range). If supported, reads the leaf from the CPU; otherwise leaves
622+ * `leaf_cache` at its zero-initialized default (all feature bits false). Either
623+ * way, `status_id` is set so subsequent calls return immediately.
624+ */
606625 template <status status_id, typename L>
607- inline auto const & safe_get_leaf (L& leaf ) const
626+ inline auto const & safe_read_leaf (L& leaf_cache ) const
608627 {
609628 // Check if already initialized
610629 if (m_status.bit_is_set <status_id>())
611630 {
612- return leaf ;
631+ return leaf_cache ;
613632 }
614633
615634 // Limit where we need to check leaf0 or leaf 80000000.
@@ -623,32 +642,32 @@ namespace xsimd
623642 // Check leaf0 in regular range
624643 if (L::leaf <= leaf0 ().highest_leaf ())
625644 {
626- leaf = L::read ();
645+ leaf_cache = L::read ();
627646 }
628647 }
629648 else
630649 {
631650 // Check leaf80000000 in extended range
632651 if (L::leaf <= leaf80000000 ().highest_leaf ())
633652 {
634- leaf = L::read ();
653+ leaf_cache = L::read ();
635654 }
636655 }
637656
638657 // Mark as valid in all cases, including if it was not read.
639658 // In this case it will be filled with zeros (all false).
640659 m_status.set_bit <status_id>();
641- return leaf ;
660+ return leaf_cache ;
642661 }
643662
644663 inline x86_cpuid_leaf1 const & leaf1 () const
645664 {
646- return safe_get_leaf <status::leaf1_valid>(m_leaf1);
665+ return safe_read_leaf <status::leaf1_valid>(m_leaf1);
647666 }
648667
649668 inline x86_cpuid_leaf7 const & leaf7 () const
650669 {
651- return safe_get_leaf <status::leaf7_valid>(m_leaf7);
670+ return safe_read_leaf <status::leaf7_valid>(m_leaf7);
652671 }
653672
654673 inline x86_cpuid_leaf7sub1 const & leaf7sub1 () const
@@ -676,7 +695,7 @@ namespace xsimd
676695
677696 inline x86_cpuid_leaf80000001 const & leaf80000001 () const
678697 {
679- return safe_get_leaf <status::leaf80000001_valid>(m_leaf80000001);
698+ return safe_read_leaf <status::leaf80000001_valid>(m_leaf80000001);
680699 }
681700 };
682701
0 commit comments