@@ -93,41 +93,38 @@ pub fn has_cpuid() -> bool {
93
93
// https://software.intel.com/en-us/articles/using-cpuid-to-detect-the-presence-of-sse-41-and-sse-42-instruction-sets/
94
94
// which detects whether `cpuid` is available by checking whether the 21st bit of the EFLAGS register is modifiable or not.
95
95
// 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
131
128
}
132
129
}
133
130
}
0 commit comments