#include "sn_target.h" #if SN_IS_ARCH(SN_ARCH_X86_64) #include "sn_intrinsic.h" DECLARE_KER_PROC_RIGHT_ANS(float, sse, , quality) { static const __m128 abs_mask_source = { .m128_i32 = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 } }; register __m128 abs_mask = _mm_load_ps(abs_mask_source.m128_i32); register __m128 col0 = _mm_andnot_ps(abs_mask, _mm_load_ps((float *)&right->f32_x[0])); register __m128 col1 = _mm_andnot_ps(abs_mask, _mm_load_ps((float *)&right->f32_x[1])); register __m128 col2 = _mm_andnot_ps(abs_mask, _mm_load_ps((float *)&right->f32_x[2])); register __m128 col3 = _mm_andnot_ps(abs_mask, _mm_load_ps((float *)&right->f32_x[3])); // norm register __m128 row_sum = _mm_add_ps(col0, col1); row_sum = _mm_add_ps(row_sum, col2); row_sum = _mm_add_ps(row_sum, col3); // max(0,2) and max(1,3) register __m128 max = _mm_max_ps(row_sum, _mm_movehl_ps(row_sum, row_sum)); max = _mm_max_ps(max, _mm_shuffle_ps(max, max, _MM_SHUFFLE(2, 3, 0, 1))); float norm = _mm_cvtss_f32(max); ans->f32_x[0].m128_f32[0] = norm; // min on cross col1 = _mm_shuffle_ps(col1, col1, _MM_SHUFFLE(0, 3, 2, 1)); col2 = _mm_shuffle_ps(col2, col2, _MM_SHUFFLE(1, 0, 3, 2)); col3 = _mm_shuffle_ps(col3, col3, _MM_SHUFFLE(2, 1, 0, 3)); max = _mm_min_ps(col0, col2); register max0 = _mm_min_ps(max, col1); max = _mm_min_ps(max0, max); float min_val = _mm_cvtss_f32(max); ans->f32_x[0].m128_f32[1] = min_val; float quality = min_val / (norm + 1e-20f); ans->f32_x[0].m128_f32[2] = quality; } #endif