Reputation: 76703
I have some code that relies on AVX.
In the same code base I also use TZCNT
.
The latter is part of BMI1. I know I can test for this instruction using CPUID, but I'm lazy so I did not actually implement that.
To test for support I simply perform an AVX instruction. If I get a #UD
undefined instruction exception back I know the CPU does not support AVX.
However tzcnt
is backwards compatible (kind of) with the bsf
(or bsr
- I always forget which is which), so that will not trigger an exception.
If I have AVX
support, does that imply BMI1
support?
For the record, I do not have AVX2 on the CPU that I'm testing with right now.
Upvotes: 3
Views: 1388
Reputation: 76703
No, AVX support does not imply BMI1 support.
See the following table for details:
Intel AMD Year
---------------------------------------------------
AVX Sandy Bridge Bulldozer 2011
---------------------------------------------------
BMI1 Haswell Piledriver/Jaguar 2013
---------------------------------------------------
ABM Barcelona 2007
Haswell 2013
---------------------------------------------------
AVX2 Haswell 2013
Carrizo 2015
Ryzen 2017
---------------------------------------------------
BMI2 Haswell 2013
Excavator 2015
Ryzen 2017
Most processors support both, but AVX predates BMI1 by two years.
Add to this the fact that tzcnt
and bsf
have different semantics with regards to the flags.
If you want to force a #UD
exception, you can use a andn
.
If you want to use CPUID:
BMI1 -> CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]
(ANDN, BEXTR, BLSI, BLSMSK, BLSR, TZCNT)
BMI2 -> CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]
(BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX)
LZCNT -> CPUID.(EAX=80000001H) ECX.LZCNT[bit 5]
POPCNT -> CPUID.(EAX=01H) :ECX.POPCNT [Bit 23]
Note that even if CPUID indicates that a (Intel) processor does not support popcnt
it often does.
Upvotes: 4