+#if __x86_64__ && CLIB_DEBUG == 0
+#define foreach_march_variant_runtime(macro, _args...) \
+ macro(avx512, avx512f, _args) \
+ macro(avx2, avx2, _args)
+#else
+#define foreach_march_variant_runtime(macro, _args...)
+#endif
+
+#define CLIB_MARCH_ARCH_CHECK(arch, archname, fn) \
+ if (clib_cpu_supports_ ## archname ()) \
+ return & fn ## _ ##arch;
+
+#define CLIB_MARCH_SELECT_FN(fn,...) \
+ __VA_ARGS__ void * fn ## _multiarch_select(void) \
+{ \
+ foreach_march_variant_runtime(CLIB_MARCH_ARCH_CHECK, fn) \
+ return & fn; \
+}
+
+#define DEFINE_WEAK_FN(_arch, _fn, _args...) \
+ int __attribute__((weak)) _fn##_ma_##_arch(_args);
+#define DEFINE_FN_HELPER(arch, archname, macro, _args...) \
+ macro(arch, _args)
+
+#ifndef CLIB_MARCH_VARIANT
+#define MARCH_FN(fn, _args...) \
+ static void * (*fn ## _selected) (void); \
+ foreach_march_variant_runtime (DEFINE_FN_HELPER, DEFINE_WEAK_FN, fn, \
+ _args); \
+ static inline int CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (fn ## _ma)(_args)
+#else
+#define MARCH_FN(fn, _args...) \
+ int CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (fn ## _ma)(_args)
+#endif
+