GCC has a way of doing this that starts by calling __builtin_cpu_init
then calling __builtin_cpu_is
and __builtin_cpu_supports
to check features. https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/X86-Built-in-Functions.html
On x86, when using the C++ frontend, GCC supports "function multiversioning", which allows you to write multiple versions of the function, specify the target it should be used on, and let GCC take care of making sure it is called. https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Function-Multiversioning.html