2

I want to use the _bzhi_u32 intrinsic, but I want to revert to a regular C implementation if the processor where the executable runs doesn't support the BMI2 instruction set.

I'm using GCC 4.8.3 and I have the following

static inline uint32_t myfunc_bmi(uint32_t in) {
     return _bzhi_u32(in, 3); /* as an example */ 
}
static void * resolve_myfunc(void) {
  __builtin_cpu_init();.
  if (__builtin_cpu_is("corei7") return myfunc_bmi2;
  return myfunc_default;
}
static inline uint32_t myfunc(uint32_t in) __attribute__ ((ifunc "resolve_myfunc")));

I originally wanted to use __builtin_cpu_support() to check explicitly for BMI2 but seems that you can't check for that with __builtin_cpu_support(). My current check of corei7 doesn't seem perfect either because as I understand some mobile versions of i7 Haswell doesn't have BMI2 (I tried on a VirtualBox Linux guest running on Windows 7 on i7-3520@2.9GHZ and it raises a SIGILL Illegal Instruction).

So is there a fail-safe way to check for BMI2?

RubenLaguna
  • 21,435
  • 13
  • 113
  • 151
  • The above `__builtin_cpu_is("corei7")` actually returns `false` on the VirtualBox Linux Guest. – RubenLaguna Jul 10 '15 at 10:38
  • [You can answer your own question](http://stackoverflow.com/questions/32214843/compiler-macro-to-detect-bmi2-instruction-set) rather than leave this question unanswered. – Z boson Jan 04 '16 at 19:21

1 Answers1

2

The __builtin_cpu_supports is working for me (GCC 5.1).. GCC 4.9 and lower versions does not support BMI2 detection.

Try this ->

__builtin_cpu_init ();
if (__builtin_cpu_supports("bmi2")) {
    printf("BMI2 supported \n");
}

To resolve your issue you should update your GCC version.

Alternatively use CPUID and extract the BMI2 bit if you don't want to update your GCC.

/A

Anders Cedronius
  • 2,036
  • 1
  • 23
  • 29