@@ -93,41 +93,38 @@ pub fn has_cpuid() -> bool {
9393 // https://software.intel.com/en-us/articles/using-cpuid-to-detect-the-presence-of-sse-41-and-sse-42-instruction-sets/
9494 // which detects whether `cpuid` is available by checking whether the 21st bit of the EFLAGS register is modifiable or not.
9595 // If it is, then `cpuid` is available.
96- let eax: i32 ;
97- asm ! ( r#"
98- # Save a copy of the original eflags that we will restore later:
99- pushfd
100- # Copy eflags to ecx and eax:
101- pushfd
102- pop %eax
103- mov %ecx, %eax
104- # Flip 21st bit and write back to eflags register:
105- xor %eax, 0x200000
106- push %eax
107- popfd
108- # Read eflags register again:
109- pushfd
110- pop %eax
111- # If cpuid is available, the bit will still be flipped
112- # and it will be the only bit modified.
113- #
114- # xor with the original eflags should produce a 1 in
115- # the 21st bit in this case, and zeros for all other bits:
116- xor %eax, %ecx
117- # So if the value of the 21st bit is 1, cpuid is available,
118- # and if it is zero, it isn't because we didn't manage to
119- # modify it:
120- shrl %eax, 21
121- # Restore original eflags
122- popfd
123- "#
124- : "={eax}" ( eax) // output operands
125- : // input operands
126- : "memory" , "ecx" // clobbers all memory and ecx
127- : "volatile" // has side-effects
128- ) ;
129- debug_assert ! ( eax == 0 || eax == 1 ) ;
130- eax == 1
96+ let result: u32 ;
97+ let _temp: u32 ;
98+ unsafe {
99+ asm ! ( r#"
100+ # Read eflags into $0 and copy into $1:
101+ pushfd
102+ pop $0
103+ mov $1, $0
104+ # Flip 21st bit:
105+ xor $0, 0x200000
106+ # Set eflags:
107+ push $0
108+ popfd
109+ # Read eflags again, if cpuid is available
110+ # the 21st bit will be flipped, otherwise it
111+ # it will have the same value as the original in $1:
112+ pushfd
113+ pop $0
114+ # Xor'ing with the original eflags should have the
115+ # 21st bit set to true if cpuid is available and zero
116+ # otherwise. All other bits have not been modified and
117+ # are zero:
118+ xor $0, $1
119+ # Store in $0 the value of the 21st bit
120+ shr $0, 21
121+ "#
122+ : "=r" ( result) , "=r" ( _temp)
123+ :
124+ : "cc" , "memory"
125+ : "intel" ) ;
126+ }
127+ result != 0
131128 }
132129 }
133130}
0 commit comments