@@ -369,7 +369,7 @@ struct VM {
369369 INTEL_THREAD_MISMATCH ,
370370 XEON_THREAD_MISMATCH ,
371371
372- // start of non-technqiue flags
372+ // start of non-technique flags
373373 EXTREME ,
374374 NO_MEMO ,
375375 WIN_HYPERV_DEFAULT ,
@@ -380,7 +380,7 @@ struct VM {
380380 static constexpr u8 enum_size = __LINE__ - enum_line_start - 4 ; // get enum size
381381 static constexpr u8 technique_count = enum_size - 4 ; // get total number of techniques
382382 static constexpr u8 non_technique_count = enum_size - technique_count; // get number of non-technique flags like VM::NO_MEMO for example
383-
383+ static constexpr u8 start_of_non_technique = VM :: EXTREME ;
384384 // for the bitset
385385 using flagset = std::bitset<enum_size>;
386386
@@ -634,6 +634,7 @@ struct VM {
634634 bool found;
635635 bool is_xeon;
636636 bool is_i_series;
637+ bool is_ryzen;
637638 std::string string;
638639 };
639640
@@ -642,6 +643,7 @@ struct VM {
642643
643644 constexpr const char * intel_i_series_regex = " i[0-9]-[A-Z0-9]{1,7}" ;
644645 constexpr const char * intel_xeon_series_regex = " [DEW]-[A-Z0-9]{1,7}" ;
646+ constexpr const char * amd_ryzen_regex = " ^(PRO)?[A-Z0-9]{1,7}" ;
645647
646648 std::string match_str = " " ;
647649
@@ -663,26 +665,29 @@ struct VM {
663665 return false ;
664666 };
665667
666- bool found = false ;
667- bool is_xeon = false ;
668- bool is_i_series = false ;
669- std::string string = " " ;
668+ bool found = false ;
669+ bool is_xeon = false ;
670+ bool is_i_series = false ;
671+ bool is_ryzen = false ;
670672
671673 if (cpu::is_intel ()) {
672674 if (match (intel_i_series_regex)) {
673675 found = true ;
674676 is_i_series = true ;
675- string = match_str;
676677 } else if (match (intel_xeon_series_regex)) {
677678 found = true ;
678679 is_xeon = true ;
679- string = match_str;
680680 }
681681 }
682682
683- // no AMD (for now)
683+ if (cpu::is_amd ()) {
684+ if (match (amd_ryzen_regex)) {
685+ found = true ;
686+ is_ryzen = true ;
687+ }
688+ }
684689
685- return model_struct{ found, is_xeon, is_i_series, string };
690+ return model_struct{ found, is_xeon, is_i_series, is_ryzen, match_str };
686691 };
687692
688693#if (CPP >= 17)
@@ -6766,38 +6771,41 @@ struct VM {
67666771 }
67676772
67686773
6769-
6770-
6771-
6772- // TODO: DO AMD
6773- // https://en.wikipedia.org/wiki/List_of_AMD_Ryzen_processors
6774-
6775-
6776-
6777-
6778-
6779-
6780-
6781-
6782-
67836774 /* *
6784- * @brief
6775+ * @brief Check for AMD CPUs that don't match their thread count
67856776 * @category All, x86
6786- * @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
6777+ * @link https://en.wikipedia.org/wiki/List_of_AMD_Ryzen_processors
67876778 */
67886779/*
6789- [[nodiscard]] static bool () try {
6780+ [[nodiscard]] static bool amd_thread_mismatch () try {
67906781#if (!x86)
67916782 return false;
67926783#else
6784+ if (!cpu::is_amd()) {
6785+ return false;
6786+ }
6787+
6788+ if (cpu::has_hyperthreading()) {
6789+ return false;
6790+ }
67936791
6792+ const cpu::model_struct model = cpu::get_model();
6793+
6794+ if (!model.found) {
6795+ return false;
6796+ }
6797+
6798+ if (!model.is_i_series) {
6799+ return false;
6800+ }
6801+
6802+ debug("XEON_THREAD_MISMATCH: CPU model = ", model.string);
67946803#endif
67956804 }
67966805 catch (...) {
6797- debug("XEON_THREAD_MISMATCH : catched error, returned false");
6806+ debug("AMD_THREAD_MISMATCH : catched error, returned false");
67986807 return false;
67996808 }
6800-
68016809*/
68026810
68036811
@@ -6807,7 +6815,6 @@ struct VM {
68076815
68086816
68096817
6810-
68116818 struct core {
68126819 MSVC_DISABLE_WARNING (PADDING )
68136820 struct technique {
@@ -6867,8 +6874,7 @@ struct VM {
68676874
68686875 bool is_non_technique_set = false ;
68696876
6870- // VM::EXTREME is the start of non-technique flags in the enum
6871- for (std::size_t i = VM ::EXTREME ; i <= enum_size; i++) {
6877+ for (std::size_t i = start_of_non_technique; i <= enum_size; i++) {
68726878 if (p_flags.test (i)) {
68736879 is_non_technique_set = true ;
68746880 break ;
@@ -6907,7 +6913,7 @@ struct VM {
69076913 }
69086914
69096915 // check if the technique is cached already
6910- if (memo::is_cached (macro)) {
6916+ if (!memo_disabled && memo::is_cached (macro)) {
69116917 const memo::data_t data = memo::cache_fetch (macro);
69126918
69136919 if (data.result ) {
@@ -6941,31 +6947,28 @@ struct VM {
69416947 }
69426948 }
69436949
6944-
69456950 return points;
69466951 }
69476952
69486953 // check if Hyper-V is running
69496954 static bool hyperv_default_check (const flagset &p_flags) {
6950- if (MSVC && core::disabled (p_flags, WIN_HYPERV_DEFAULT )) {
6951- std::string tmp_brand;
6952-
6953- if (memo::brand::is_brand_cached ()) {
6954- tmp_brand = memo::brand::fetch_brand ();
6955- } else {
6956- tmp_brand = brand ();
6957- }
6955+ #if (!MSVC)
6956+ return false ;
6957+ #else
6958+ std::string tmp_brand;
69586959
6959- if (
6960- tmp_brand == VM ::HYPERV ||
6961- tmp_brand == VM ::VPC ||
6962- tmp_brand == " Microsoft Virtual PC/Hyper-V"
6963- ) {
6964- return true ;
6965- }
6960+ if (memo::brand::is_brand_cached ()) {
6961+ tmp_brand = memo::brand::fetch_brand ();
6962+ } else {
6963+ tmp_brand = brand ();
69666964 }
6967-
6968- return false ;
6965+
6966+ return (
6967+ tmp_brand == VM ::HYPERV ||
6968+ tmp_brand == VM ::VPC ||
6969+ tmp_brand == " Microsoft Virtual PC/Hyper-V"
6970+ );
6971+ #endif
69696972 }
69706973 };
69716974
@@ -7208,8 +7211,10 @@ struct VM {
72087211 result = (points >= 100 );
72097212 }
72107213
7211- if (core::hyperv_default_check (p_flags)) {
7212- return false ;
7214+ if (core::disabled (p_flags, VM ::WIN_HYPERV_DEFAULT )) {
7215+ if (core::hyperv_default_check (p_flags)) {
7216+ return false ;
7217+ }
72137218 }
72147219
72157220 return result;
0 commit comments