#include "StgSharpNative.h" #include "sn_intrinsic.h" #if defined(_MSC_VER) && !defined(__clang__) #include #include #else #include #endif // _MSC_VER PRIVATE void load_intrinsic_sse(sn_intrinsic *context); PRIVATE void load_intrinsic_avx(sn_intrinsic *context); PRIVATE void load_intrinsic_512(sn_intrinsic *context); PRIVATE int check_isa(most_advanced_instruction instruction_family) { if (instruction_family != NEON) { #if defined(_MSC_VER) && !defined(__clang__) return __check_isa_support(instruction_family, 0); #else switch (instruction_family) { case SSE: return __builtin_cpu_supports("sse4.2"); case AVX256: return __builtin_cpu_supports("avx2"); case AVX512: return __builtin_cpu_supports("avx512f"); default: return 0; } #endif // _MSC_VER } #if defined(__ARM_NEON) || defined(__ARM_NEON__) return 1; #else return 0; #endif } SN_API int load_intrinsic_function(void *intrinsic_context) { sn_null_assert(intrinsic_context); sn_intrinsic *context = (sn_intrinsic *)intrinsic_context; if (check_isa(AVX512)) { load_intrinsic_512(context); return 3; } else if (check_isa(AVX256)) { load_intrinsic_avx(context); return 2; } else if (check_isa(SSE)) { load_intrinsic_sse(context); return 1; } else if (check_isa(NEON)) { return -1; } return 0; } void load_intrinsic_sse(sn_intrinsic *context) { context->city_hash_simplify = city_hash_simplify_sse; context->factorial_simd = factorial_simd_sse; context->index_pair = index_pair_sse; context->f32_clear_panel = PNL_PROC(float, sse, clear); context->f32_build_panel = BUILD_PANEL(sse, float); context->f32_buffer_add = BUF_PROC(float, sse, add); context->f32_panel_fma = PNL_PROC(float, sse, fma); context->f32_buffer_fill = BUF_PROC(float, sse, fill); context->variant = BUF_PROC(float, sse, scalar_mul); context->f32_buffer_sub = BUF_PROC(float, sse, sub); context->f32_buffer_transpose = KER_PROC(float, sse, transpose); context->f32_buffer_scalar_mul = BUF_PROC(float, sse, scalar_mul); context->f32_normalize_3 = f32_normalize; } void load_intrinsic_avx(sn_intrinsic *context) { context->city_hash_simplify = city_hash_simplify_sse; context->factorial_simd = factorial_simd_sse; context->index_pair = index_pair_sse; context->f32_clear_panel = PNL_PROC(float, avx, clear); context->f32_build_panel = BUILD_PANEL(avx, float); context->f32_buffer_add = BUF_PROC(float, avx, add); context->f32_panel_fma = PNL_PROC(float, avx, fma); context->f32_buffer_fill = BUF_PROC(float, avx, fill); context->variant = BUF_PROC(float, avx, scalar_mul); context->f32_buffer_sub = BUF_PROC(float, avx, sub); context->f32_buffer_transpose = KER_PROC(float, avx, transpose); context->f32_buffer_scalar_mul = BUF_PROC(float, avx, scalar_mul); context->f32_normalize_3 = f32_normalize; } void load_intrinsic_512(sn_intrinsic *context) { context->city_hash_simplify = city_hash_simplify_sse; context->factorial_simd = factorial_simd_sse; context->index_pair = index_pair_sse; context->f32_clear_panel = PNL_PROC(float, sse, clear); context->f32_build_panel = BUILD_PANEL(512, float); context->f32_buffer_add = BUF_PROC(float, 512, add); context->f32_panel_fma = PNL_PROC(float, 512, fma); context->f32_buffer_fill = BUF_PROC(float, 512, fill); context->variant = BUF_PROC(float, 512, scalar_mul); context->f32_buffer_sub = BUF_PROC(float, 512, sub); context->f32_buffer_transpose = KER_PROC(float, 512, transpose); context->f32_buffer_scalar_mul = BUF_PROC(float, 512, scalar_mul); context->f32_normalize_3 = f32_normalize; }