Blame view

3rdparty/boost_1_81_0/libs/atomic/src/cpuid.hpp 2.18 KB
e6ccf0ce   Hu Chunming   提交三方库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  /*
   * Distributed under the Boost Software License, Version 1.0.
   * (See accompanying file LICENSE_1_0.txt or copy at
   * http://www.boost.org/LICENSE_1_0.txt)
   *
   * Copyright (c) 2020 Andrey Semashev
   */
  /*!
   * \file   cpuid.hpp
   *
   * This file contains declaration of \c cpuid function
   */
  
  #ifndef BOOST_ATOMIC_CPUID_HPP_INCLUDED_
  #define BOOST_ATOMIC_CPUID_HPP_INCLUDED_
  
  #include <boost/predef/architecture/x86.h>
  
  #if BOOST_ARCH_X86
  
  #if defined(_MSC_VER)
  #include <intrin.h> // __cpuid
  #endif
  #include <boost/cstdint.hpp>
  #include <boost/atomic/detail/config.hpp>
  
  #include <boost/atomic/detail/header.hpp>
  
  namespace boost {
  namespace atomics {
  namespace detail {
  
  //! The function invokes x86 cpuid instruction
  inline void cpuid(uint32_t& eax, uint32_t& ebx, uint32_t& ecx, uint32_t& edx)
  {
  #if defined(__GNUC__)
  #if (defined(__i386__) || defined(__VXWORKS__)) && (defined(__PIC__) || defined(__PIE__)) && !(defined(__clang__) || (defined(BOOST_GCC) && BOOST_GCC >= 50100))
      // Unless the compiler can do it automatically, we have to backup ebx in 32-bit PIC/PIE code because it is reserved by the ABI.
      // For VxWorks ebx is reserved on 64-bit as well.
  #if defined(__x86_64__)
      uint64_t rbx = ebx;
      __asm__ __volatile__
      (
          "xchgq %%rbx, %0\n\t"
          "cpuid\n\t"
          "xchgq %%rbx, %0\n\t"
              : "+DS" (rbx), "+a" (eax), "+c" (ecx), "+d" (edx)
      );
      ebx = static_cast< uint32_t >(rbx);
  #else // defined(__x86_64__)
      __asm__ __volatile__
      (
          "xchgl %%ebx, %0\n\t"
          "cpuid\n\t"
          "xchgl %%ebx, %0\n\t"
              : "+DS" (ebx), "+a" (eax), "+c" (ecx), "+d" (edx)
      );
  #endif // defined(__x86_64__)
  #else
      __asm__ __volatile__
      (
          "cpuid\n\t"
              : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx)
      );
  #endif
  #elif defined(_MSC_VER)
      int regs[4] = {};
      __cpuid(regs, eax);
      eax = regs[0];
      ebx = regs[1];
      ecx = regs[2];
      edx = regs[3];
  #else
  #error "Boost.Atomic: Unsupported compiler, cpuid instruction cannot be generated"
  #endif
  }
  
  } // namespace detail
  } // namespace atomics
  } // namespace boost
  
  #include <boost/atomic/detail/footer.hpp>
  
  #endif // BOOST_ARCH_X86
  
  #endif // BOOST_ATOMIC_CPUID_HPP_INCLUDED_