summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vppinfra/cpu.h')
-rw-r--r--src/vppinfra/cpu.h56
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) \