diff options
Diffstat (limited to 'src/vppinfra/cpu.h')
-rw-r--r-- | src/vppinfra/cpu.h | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/vppinfra/cpu.h b/src/vppinfra/cpu.h index 97e0144be60..7f0d6ad2e34 100644 --- a/src/vppinfra/cpu.h +++ b/src/vppinfra/cpu.h @@ -62,6 +62,62 @@ #define CLIB_MARCH_SFX CLIB_MULTIARCH_FN +typedef struct _clib_march_fn_registration +{ + void *function; + int priority; + struct _clib_march_fn_registration *next; + char *name; +} clib_march_fn_registration; + +static_always_inline void * +clib_march_select_fn_ptr (clib_march_fn_registration * r) +{ + void *rv = 0; + int last_prio = -1; + + while (r) + { + if (last_prio < r->priority) + { + last_prio = r->priority; + rv = r->function; + } + r = r->next; + } + return rv; +} + +#define CLIB_MARCH_FN_POINTER(fn) \ + clib_march_select_fn_ptr (fn##_march_fn_registrations); + +#define _CLIB_MARCH_FN_REGISTRATION(fn) \ +static clib_march_fn_registration \ +CLIB_MARCH_SFX(fn##_march_fn_registration) = \ +{ \ + .name = CLIB_MARCH_VARIANT_STR \ +}; \ +\ +static void __clib_constructor \ +fn##_march_register () \ +{ \ + clib_march_fn_registration *r; \ + r = & CLIB_MARCH_SFX (fn##_march_fn_registration); \ + r->priority = CLIB_MARCH_FN_PRIORITY(); \ + r->next = fn##_march_fn_registrations; \ + r->function = CLIB_MARCH_SFX (fn); \ + fn##_march_fn_registrations = r; \ +} + +#ifdef CLIB_MARCH_VARIANT +#define CLIB_MARCH_FN_REGISTRATION(fn) \ +extern clib_march_fn_registration *fn##_march_fn_registrations; \ +_CLIB_MARCH_FN_REGISTRATION(fn) +#else +#define CLIB_MARCH_FN_REGISTRATION(fn) \ +clib_march_fn_registration *fn##_march_fn_registrations = 0; \ +_CLIB_MARCH_FN_REGISTRATION(fn) +#endif #define foreach_x86_64_flags \ _ (sse3, 1, ecx, 0) \ _ (ssse3, 1, ecx, 9) \ |