17#include <sys/utsname.h>
18#if __GLIBC_PREREQ (2,16)
45# if defined(__linux__) && defined(__x86_64__)
46 inline void cpuid(uint32_t op, uint32_t op2, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
50 :
"=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
51 :
"a" (op),
"c" (op2));
57 #define bit_SSE3 (1 << 0)
58 #define bit_SSSE3 (1 << 9)
59 #define bit_FMA (1 << 12)
60 #define bit_CMPXCHG16B (1 << 13)
61 #define bit_SSE4_1 (1 << 19)
62 #define bit_SSE4_2 (1 << 20)
63 #define bit_MOVBE (1 << 22)
64 #define bit_POPCNT (1 << 23)
65 #define bit_OSXSAVE (1 << 27)
66 #define bit_AVX (1 << 28)
67 #define bit_F16C (1 << 29)
71 #define bit_LAHF_LM (1 << 0)
72 #define bit_LZCNT (1 << 5)
76 #define bit_BMI (1 << 3)
77 #define bit_AVX2 (1 << 5)
78 #define bit_BMI2 (1 << 8)
79 #define bit_AVX512F (1 << 16)
80 #define bit_AVX512DQ (1 << 17)
81 #define bit_AVX512CD (1 << 28)
82 #define bit_AVX512BW (1 << 30)
83 #define bit_AVX512VL (1u << 31)
85 int get_x86_64_level(
void)
89 unsigned int op_1_ecx = 0, op_80000001_ecx = 0, op_7_ebx = 0, unused = 0;
90 cpuid(1, 0, &unused, &unused, &op_1_ecx, &unused);
91 cpuid(0x80000001, 0, &unused, &unused, &op_80000001_ecx, &unused);
92 cpuid(7, 0, &unused, &op_7_ebx, &unused, &unused);
94 const unsigned int op_1_ecx_lv2 = bit_SSE3 | bit_SSSE3 | bit_CMPXCHG16B | bit_SSE4_1 | bit_SSE4_2 | bit_POPCNT;
95 if ((op_1_ecx & op_1_ecx_lv2) == op_1_ecx_lv2 && (op_80000001_ecx & bit_LAHF_LM))
98 const unsigned int op_1_ecx_lv3 = bit_FMA | bit_MOVBE | bit_OSXSAVE | bit_AVX | bit_F16C;
99 const unsigned int op_7_ebx_lv3 = bit_BMI | bit_AVX2 | bit_BMI2;
100 if (level == 2 && (op_1_ecx & op_1_ecx_lv3) == op_1_ecx_lv3 && (op_7_ebx & op_7_ebx_lv3) == op_7_ebx_lv3
101 && (op_80000001_ecx & bit_LZCNT))
104 const unsigned int op_7_ebx_lv4 = bit_AVX512F | bit_AVX512DQ | bit_AVX512CD | bit_AVX512BW | bit_AVX512VL;
105 if (level == 3 && (op_7_ebx & op_7_ebx_lv4) == op_7_ebx_lv4)
112 Arch _autoDetectSystemArchitecture() {
113 struct ::utsname buf;
114 if ( ::uname( &buf ) < 0 )
116 ERR <<
"Can't determine system architecture" << endl;
120 Arch architecture( buf.machine );
121 MIL <<
"Uname architecture is '" << buf.machine <<
"'" << endl;
123 if ( architecture == Arch_x86_64 )
125 #if defined(__linux__) && defined(__x86_64__)
126 switch ( get_x86_64_level() )
129 architecture = Arch_x86_64_v2;
130 WAR <<
"CPU has 'x86_64': architecture upgraded to '" << architecture <<
"'" << endl;
133 architecture = Arch_x86_64_v3;
134 WAR <<
"CPU has 'x86_64': architecture upgraded to '" << architecture <<
"'" << endl;
137 architecture = Arch_x86_64_v4;
138 WAR <<
"CPU has 'x86_64': architecture upgraded to '" << architecture <<
"'" << endl;
143 else if ( architecture == Arch_i686 )
148 std::ifstream cpuinfo(
"/proc/cpuinfo" );
155 if ( in->find(
"cx8" ) == std::string::npos
156 || in->find(
"cmov" ) == std::string::npos )
158 architecture = Arch_i586;
159 WAR <<
"CPU lacks 'cx8' or 'cmov': architecture downgraded to '" << architecture <<
"'" << endl;
167 ERR <<
"Cant open " <<
PathInfo(
"/proc/cpuinfo") << endl;
170 else if ( architecture == Arch_sparc || architecture == Arch_sparc64 )
173 std::ifstream cpuinfo(
"/proc/cpuinfo" );
180 if ( in->find(
"sun4v" ) != std::string::npos )
182 architecture = ( architecture == Arch_sparc64 ? Arch_sparc64v : Arch_sparcv9v );
183 WAR <<
"CPU has 'sun4v': architecture upgraded to '" << architecture <<
"'" << endl;
185 else if ( in->find(
"sun4u" ) != std::string::npos )
187 architecture = ( architecture == Arch_sparc64 ? Arch_sparc64 : Arch_sparcv9 );
188 WAR <<
"CPU has 'sun4u': architecture upgraded to '" << architecture <<
"'" << endl;
190 else if ( in->find(
"sun4m" ) != std::string::npos )
192 architecture = Arch_sparcv8;
193 WAR <<
"CPU has 'sun4m': architecture upgraded to '" << architecture <<
"'" << endl;
201 ERR <<
"Cant open " <<
PathInfo(
"/proc/cpuinfo") << endl;
204 else if ( architecture == Arch_armv8l || architecture == Arch_armv7l || architecture == Arch_armv6l )
206 std::ifstream platform(
"/etc/rpm/platform" );
213 architecture = Arch_armv8hl;
214 WAR <<
"/etc/rpm/platform contains armv8hl-: architecture upgraded to '" << architecture <<
"'" << endl;
219 architecture = Arch_armv7hl;
220 WAR <<
"/etc/rpm/platform contains armv7hl-: architecture upgraded to '" << architecture <<
"'" << endl;
225 architecture = Arch_armv6hl;
226 WAR <<
"/etc/rpm/platform contains armv6hl-: architecture upgraded to '" << architecture <<
"'" << endl;
232 #if __GLIBC_PREREQ (2,16)
233 else if ( architecture == Arch_ppc64 )
235 const char * platform = (
const char *)getauxval( AT_PLATFORM );
237 if ( platform && sscanf( platform,
"power%d", &powerlvl ) == 1 && powerlvl > 6 )
238 architecture = Arch_ppc64p7;
347 {
return ! ( lhs == rhs ); }
371 #define DEF_BUILTIN(A) \
372 namespace { static inline const IdString & a_##A () { static IdString _str(#A); return _str; } } \
373 const Arch Arch_##A( a_##A() )
473 using Set = std::unordered_set<CompatEntry>;
474 using iterator = Set::iterator;
475 using const_iterator = Set::const_iterator;
478 static ArchCompatSet & instance()
480 static ArchCompatSet _instance;
487 const Arch::CompatEntry & assertDef(
const std::string & archStr_r )
488 {
return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
490 const Arch::CompatEntry & assertDef( IdString archStr_r )
491 {
return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
493 const_iterator begin()
const
494 {
return _compatSet.begin(); }
496 const_iterator end()
const
497 {
return _compatSet.end(); }
501 int operator()(
const CompatEntry & lhs,
const CompatEntry & rhs )
const
502 {
return lhs._idBit.value() < rhs._idBit.value(); }
505 std::ostream &
dumpOn( std::ostream & str )
const
507 str <<
"ArchCompatSet:";
508 std::list<CompatEntry> ov( _compatSet.begin(), _compatSet.end() );
509 ov.sort( DumpOnCompare() );
510 for_( it, ov.begin(), ov.end() )
512 str << endl <<
' ' << *it;
524 _compatSet.insert( Arch::CompatEntry( a_noarch(), 0 ) );
531 defCompatibleWith( a_i386(), a_noarch() );
532 defCompatibleWith( a_i486(), a_noarch(),a_i386() );
533 defCompatibleWith( a_i586(), a_noarch(),a_i386(),a_i486() );
534 defCompatibleWith( a_i686(), a_noarch(),a_i386(),a_i486(),a_i586() );
535 defCompatibleWith( a_athlon(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686() );
536 defCompatibleWith( a_x86_64(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_athlon() );
537 defCompatibleWith( a_x86_64_v2(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_athlon(),a_x86_64() );
538 defCompatibleWith( a_x86_64_v3(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_athlon(),a_x86_64(),a_x86_64_v2() );
539 defCompatibleWith( a_x86_64_v4(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_athlon(),a_x86_64(),a_x86_64_v2(),a_x86_64_v3() );
541 defCompatibleWith( a_pentium3(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686() );
542 defCompatibleWith( a_pentium4(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_pentium3() );
544 defCompatibleWith( a_ia64(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686() );
546 defCompatibleWith( a_s390(), a_noarch() );
547 defCompatibleWith( a_s390x(), a_noarch(),a_s390() );
549 defCompatibleWith( a_ppc(), a_noarch() );
550 defCompatibleWith( a_ppc64(), a_noarch(),a_ppc() );
551 defCompatibleWith( a_ppc64p7(), a_noarch(),a_ppc(),a_ppc64() );
553 defCompatibleWith( a_ppc64le(), a_noarch() );
555 defCompatibleWith( a_alpha(), a_noarch() );
556 defCompatibleWith( a_alphaev5(), a_noarch(),a_alpha() );
557 defCompatibleWith( a_alphaev56(), a_noarch(),a_alpha(),a_alphaev5() );
558 defCompatibleWith( a_alphapca56(), a_noarch(),a_alpha(),a_alphaev5(),a_alphaev56() );
559 defCompatibleWith( a_alphaev6(), a_noarch(),a_alpha(),a_alphaev5(),a_alphaev56(),a_alphapca56() );
560 defCompatibleWith( a_alphaev67(), a_noarch(),a_alpha(),a_alphaev5(),a_alphaev56(),a_alphapca56(),a_alphaev6() );
562 defCompatibleWith( a_sparc(), a_noarch() );
563 defCompatibleWith( a_sparcv8(), a_noarch(),a_sparc() );
564 defCompatibleWith( a_sparcv9(), a_noarch(),a_sparc(),a_sparcv8() );
565 defCompatibleWith( a_sparcv9v(), a_noarch(),a_sparc(),a_sparcv8(),a_sparcv9() );
567 defCompatibleWith( a_sparc64(), a_noarch(),a_sparc(),a_sparcv8(),a_sparcv9() );
568 defCompatibleWith( a_sparc64v(), a_noarch(),a_sparc(),a_sparcv8(),a_sparcv9(),a_sparcv9v(),a_sparc64() );
570 defCompatibleWith( a_armv3l(), a_noarch() );
571 defCompatibleWith( a_armv4l(), a_noarch(),a_armv3l() );
572 defCompatibleWith( a_armv4tl(), a_noarch(),a_armv3l(),a_armv4l() );
573 defCompatibleWith( a_armv5l(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl() );
574 defCompatibleWith( a_armv5tl(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l() );
575 defCompatibleWith( a_armv5tel(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl() );
576 defCompatibleWith( a_armv5tejl(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl(),a_armv5tel() );
577 defCompatibleWith( a_armv6l(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl(),a_armv5tel(),a_armv5tejl() );
578 defCompatibleWith( a_armv7l(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl(),a_armv5tel(),a_armv5tejl(),a_armv6l() );
579 defCompatibleWith( a_armv8l(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl(),a_armv5tel(),a_armv5tejl(),a_armv6l(),a_armv7l() );
581 defCompatibleWith( a_armv6hl(), a_noarch() );
582 defCompatibleWith( a_armv7hl(), a_noarch(),a_armv6hl() );
583 defCompatibleWith( a_armv8hl(), a_noarch(),a_armv7hl() );
584 defCompatibleWith( a_armv7hnl(), a_noarch(),a_armv7hl(),a_armv6hl() );
586 defCompatibleWith( a_armv7nhl(), a_noarch(),a_armv7hnl(),a_armv7hl(),a_armv6hl() );
588 defCompatibleWith( a_armv7thl(), a_noarch(),a_armv7hl() );
589 defCompatibleWith( a_armv7tnhl(), a_noarch(),a_armv7hl(),a_armv7nhl(),a_armv7thl() );
591 defCompatibleWith( a_aarch64(), a_noarch() );
593 defCompatibleWith( a_riscv64(), a_noarch() );
595 defCompatibleWith( a_sh3(), a_noarch() );
597 defCompatibleWith( a_sh4(), a_noarch() );
598 defCompatibleWith( a_sh4a(), a_noarch(),a_sh4() );
600 defCompatibleWith( a_m68k(), a_noarch() );
602 defCompatibleWith( a_mips(), a_noarch() );
603 defCompatibleWith( a_mipsel(), a_noarch() );
604 defCompatibleWith( a_mips64(), a_noarch() );
605 defCompatibleWith( a_mips64el(), a_noarch() );
607 defCompatibleWith( a_loong64(), a_noarch() );
634 const CompatEntry & assertCompatSetEntry( IdString archStr_r )
635 {
return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; }
639 void defCompatibleWith( IdString targetArch_r,
651 const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
652 target.addCompatBit( assertCompatSetEntry( arch0_r )._idBit );
653#define SETARG(N) if ( arch##N##_r.empty() ) return; target.addCompatBit( assertCompatSetEntry( arch##N##_r )._idBit )
682 :
_entry( &ArchCompatSet::instance().assertDef( a_noarch() ) )
686 :
_entry( &ArchCompatSet::instance().assertDef(
IdString(id_r) ) )
690 :
_entry( &ArchCompatSet::instance().assertDef( idstr_r ) )
694 :
_entry( &ArchCompatSet::instance().assertDef( str_r ) )
698 :
_entry( &ArchCompatSet::instance().assertDef( cstr_r ) )
703 static Arch _val( _autoDetectSystemArchitecture() );
751 if (Arch_x86_64.compatibleWith(*
this))
755 if (Arch_sparc64v.compatibleWith(*
this))
757 return Arch_sparc64v;
759 if (Arch_sparc64.compatibleWith(*
this))
763 if (Arch_ppc64.compatibleWith(*
this))
767 if (Arch_s390x.compatibleWith(*
this))
773 if ( cset.size() > 2 )
775 return *(++cset.rbegin());
797 for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
798 it != ArchCompatSet::instance().end(); ++it )
800 if ( it->compatibleWith( *targetArch_r.
_entry ) )
802 ret.insert(
Arch(*it) );
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
#define ZYPP_DEFINE_ID_HASHABLE(C)
Define hash function for id based classes.
const CompatEntry * _entry
int compare(const Arch &rhs) const
Arch comparison.
Arch()
Default ctor Arc_noarch.
static CompatSet compatSet(const Arch &targetArch_r)
Return a set of all Arch's compatibleWith a targetArch_r.
bool isBuiltIn() const
Whether this is a buitin (or known) architecture.
IdString idStr() const
String representation of Arch.
const std::string & asString() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::set< Arch, CompareByGT< Arch > > CompatSet
Reversed arch order, best Arch first.
static Arch detectSystemArchitecture()
Determine system architecture evaluating uname and /proc/cpuinfo.
bool compatibleWith(const Arch &targetArch_r) const
Compatibility relation.
Access to the sat-pools string space.
sat::detail::IdType IdType
IdType id() const
Expert backdoor.
static const IdString Empty
Empty string.
constexpr IdString()
Default ctor, empty string.
An integral type used as BitField.
TInt value() const
Return the value.
Simple lineparser: Traverse each line in a file.
bool next()
Advance to next line.
String related utilities and Regular expression matching.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
std::string numstring(char n, int w=0)
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Easy-to use interface to the ZYPP dependency resolver.
bool operator!=(const Capability &lhs, const Capability &rhs)
relates: Capability
bool operator==(const Capability &lhs, const Capability &rhs)
relates: Capability
const Arch Arch_empty(IdString::Empty)
std::ostream & dumpOn(std::ostream &str, const Capability &obj)
relates: Capability Detailed stream output
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Holds an architecture ID and its compatible relation.
void addCompatBit(const CompatBits &idBit_r) const
bool compatibleWith(const CompatEntry &targetEntry_r) const
Return whether this is compatible with targetEntry_r.
int compare(const CompatEntry &rhs) const
compare by score, then archStr.
IdString::IdType id() const
bit::BitField< uint64_t > CompatBits
Bitfield for architecture IDs and compatBits relation.
CompatEntry(IdString archStr_r, CompatBits::IntT idBit_r=1)
CompatEntry(const std::string &archStr_r, CompatBits::IntT idBit_r=1)
static const unsigned size