| 933 | } |
| 934 | |
| 935 | GI_FORCEINLINE |
| 936 | int32_t GiReduceAddInt8(GI_INT8_t Vector) { |
| 937 | #if defined(GI_NEON64_INTRINSICS) |
| 938 | return vaddlvq_s8(Vector); |
| 939 | #elif defined(GI_NEON32_INTRINSICS) |
| 940 | int32x4_t sum = vpaddlq_s16(vpaddlq_s8(Vector)); |
| 941 | return (vgetq_lane_s32(sum, 0) + vgetq_lane_s32(sum, 1) + vgetq_lane_s32(sum, 2) + |
| 942 | vgetq_lane_s32(sum, 3)); |
| 943 | #elif defined(GI_SSE42_INTRINSICS) |
| 944 | __m128i v0 = _mm_cvtepi8_epi16(Vector); |
| 945 | __m128i v1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(Vector, Vector)); |
| 946 | __m128i sum_int16 = _mm_add_epi16(v0, v1); |
| 947 | __m128i v0_int32 = _mm_cvtepi16_epi32(sum_int16); |
| 948 | __m128i v1_int32 = _mm_cvtepi16_epi32(_mm_unpackhi_epi64(sum_int16, sum_int16)); |
| 949 | __m128i sum = _mm_add_epi32(v0_int32, v1_int32); |
| 950 | float ret = _mm_extract_epi32(sum, 0); |
| 951 | ret += _mm_extract_epi32(sum, 1); |
| 952 | ret += _mm_extract_epi32(sum, 2); |
| 953 | ret += _mm_extract_epi32(sum, 3); |
| 954 | return (int16_t)(ret); |
| 955 | |
| 956 | #elif defined(GI_SSE2_INTRINSICS) |
| 957 | __m64 low = _mm_movepi64_pi64(Vector); |
| 958 | __m64 high = _mm_movepi64_pi64(_mm_unpackhi_epi64(Vector, Vector)); |
| 959 | __m128 v0 = _mm_cvtpi8_ps(low); |
| 960 | __m128 v1 = _mm_cvtpi8_ps(_mm_unpackhi_pi32(low, low)); |
| 961 | __m128 v2 = _mm_cvtpi8_ps(high); |
| 962 | __m128 v3 = _mm_cvtpi8_ps(_mm_unpackhi_pi32(high, high)); |
| 963 | __m128 sum0 = _mm_add_ps(v0, v1); |
| 964 | __m128 sum1 = _mm_add_ps(v2, v3); |
| 965 | __m128 sum = _mm_add_ps(sum0, sum1); |
| 966 | float ret0 = _mm_cvtss_f32(sum); |
| 967 | float ret1 = _mm_cvtss_f32(_mm_shuffle_ps(sum, sum, _MM_SHUFFLE(1, 1, 1, 1))); |
| 968 | float ret2 = _mm_cvtss_f32(_mm_shuffle_ps(sum, sum, _MM_SHUFFLE(2, 2, 2, 2))); |
| 969 | float ret3 = _mm_cvtss_f32(_mm_shuffle_ps(sum, sum, _MM_SHUFFLE(3, 3, 3, 3))); |
| 970 | return (int16_t)(ret0 + ret1 + ret2 + ret3); |
| 971 | #elif defined(GI_RVV_INTRINSICS) |
| 972 | vint16m1_t redsum = vundefined_i16m1(); |
| 973 | vint16m1_t zero = vmv_v_x_i16m1(0, GI_SIMD_LEN_BYTE / sizeof(int16_t)); |
| 974 | redsum = vwredsum_vs_i8m1_i16m1( |
| 975 | redsum, Vector, zero, GI_SIMD_LEN_BYTE / sizeof(int8_t)); |
| 976 | int16_t ret = 0; |
| 977 | vse16_v_i16m1(&ret, redsum, 1); |
| 978 | return ret; |
| 979 | #else |
| 980 | int16_t sum = 0; |
| 981 | for (size_t i = 0; i < GI_SIMD_LEN_BYTE / sizeof(int8_t); i++) { |
| 982 | sum += Vector[i]; |
| 983 | } |
| 984 | return sum; |
| 985 | #endif |
| 986 | } |
| 987 | |
| 988 | GI_FORCEINLINE |
| 989 | int8_t GiReduceMaxInt8(GI_INT8_t Vector) { |
nothing calls this directly
no outgoing calls
no test coverage detected