| 1258 | } |
| 1259 | |
| 1260 | GI_FORCEINLINE |
| 1261 | float GiReduceAddFloat32(GI_FLOAT32_t Vector) { |
| 1262 | #if defined(GI_NEON64_INTRINSICS) |
| 1263 | Vector = vpaddq_f32(Vector, Vector); |
| 1264 | Vector = vpaddq_f32(Vector, Vector); |
| 1265 | return vgetq_lane_f32(Vector, 0); |
| 1266 | #elif defined(GI_NEON32_INTRINSICS) |
| 1267 | float32x2_t VectorLow = vget_low_f32(Vector); |
| 1268 | float32x2_t VectorHigh = vget_high_f32(Vector); |
| 1269 | VectorLow = vpadd_f32(VectorLow, VectorHigh); |
| 1270 | VectorLow = vpadd_f32(VectorLow, VectorHigh); |
| 1271 | return vget_lane_f32(VectorLow, 0); |
| 1272 | #elif defined(GI_SSE2_INTRINSICS) |
| 1273 | Vector = GiAddFloat32( |
| 1274 | Vector, _mm_shuffle_ps(Vector, Vector, _MM_SHUFFLE(2, 3, 2, 3))); |
| 1275 | Vector = GiAddFloat32( |
| 1276 | Vector, _mm_shuffle_ps(Vector, Vector, _MM_SHUFFLE(1, 1, 1, 1))); |
| 1277 | return GiExtractLane0Float32(Vector); |
| 1278 | #elif defined(GI_RVV_INTRINSICS) |
| 1279 | vfloat32m1_t redsum = vundefined_f32m1(); |
| 1280 | //! use Ordered sum, may Unordered sum more fast with vfredusum_vs_f32m1_f32m1 |
| 1281 | redsum = vfredosum_vs_f32m1_f32m1( |
| 1282 | redsum, Vector, GiBroadcastFloat32(0.0f), GI_SIMD_LEN_BYTE / sizeof(float)); |
| 1283 | return GiExtractLane0Float32(redsum); |
| 1284 | #else |
| 1285 | float ret = 0; |
| 1286 | for (size_t i = 0; i < GI_SIMD_LEN_BYTE / sizeof(float); i++) { |
| 1287 | ret += Vector[i]; |
| 1288 | } |
| 1289 | return ret; |
| 1290 | #endif |
| 1291 | } |
| 1292 | |
| 1293 | GI_FORCEINLINE |
| 1294 | float GiReduceMultiplyFloat32(GI_FLOAT32_t Vector) { |
nothing calls this directly
no outgoing calls
no test coverage detected