Path: blob/main/contrib/arm-optimized-routines/math/aarch64/advsimd/hypot.c
48378 views
/*1* Double-precision vector hypot(x) function.2*3* Copyright (c) 2023-2024, Arm Limited.4* SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception5*/67#include "v_math.h"8#include "test_sig.h"9#include "test_defs.h"1011#if WANT_SIMD_EXCEPT12static const struct data13{14uint64x2_t tiny_bound, thres;15} data = {16.tiny_bound = V2 (0x2000000000000000), /* asuint (0x1p-511). */17.thres = V2 (0x3fe0000000000000), /* asuint (0x1p511) - tiny_bound. */18};19#else20static const struct data21{22uint64x2_t tiny_bound;23uint32x4_t thres;24} data = {25.tiny_bound = V2 (0x0360000000000000), /* asuint (0x1p-969). */26.thres = V4 (0x7c900000), /* asuint (inf) - tiny_bound. */27};28#endif2930static float64x2_t VPCS_ATTR NOINLINE31special_case (float64x2_t x, float64x2_t y, float64x2_t sqsum,32uint32x2_t special)33{34return v_call2_f64 (hypot, x, y, vsqrtq_f64 (sqsum), vmovl_u32 (special));35}3637/* Vector implementation of double-precision hypot.38Maximum error observed is 1.21 ULP:39_ZGVnN2vv_hypot (0x1.6a1b193ff85b5p-204, 0x1.bc50676c2a447p-222)40got 0x1.6a1b19400964ep-20441want 0x1.6a1b19400964dp-204. */42#if WANT_SIMD_EXCEPT4344float64x2_t VPCS_ATTR V_NAME_D2 (hypot) (float64x2_t x, float64x2_t y)45{46const struct data *d = ptr_barrier (&data);4748float64x2_t ax = vabsq_f64 (x);49float64x2_t ay = vabsq_f64 (y);5051uint64x2_t ix = vreinterpretq_u64_f64 (ax);52uint64x2_t iy = vreinterpretq_u64_f64 (ay);5354/* Extreme values, NaNs, and infinities should be handled by the scalar55fallback for correct flag handling. */56uint64x2_t specialx = vcgeq_u64 (vsubq_u64 (ix, d->tiny_bound), d->thres);57uint64x2_t specialy = vcgeq_u64 (vsubq_u64 (iy, d->tiny_bound), d->thres);58ax = v_zerofy_f64 (ax, specialx);59ay = v_zerofy_f64 (ay, specialy);60uint32x2_t special = vaddhn_u64 (specialx, specialy);6162float64x2_t sqsum = vfmaq_f64 (vmulq_f64 (ax, ax), ay, ay);6364if (unlikely (v_any_u32h (special)))65return special_case (x, y, sqsum, special);6667return vsqrtq_f64 (sqsum);68}69#else7071float64x2_t VPCS_ATTR V_NAME_D2 (hypot) (float64x2_t x, float64x2_t y)72{73const struct data *d = ptr_barrier (&data);7475float64x2_t sqsum = vfmaq_f64 (vmulq_f64 (x, x), y, y);7677uint32x2_t special78= vcge_u32 (vsubhn_u64 (vreinterpretq_u64_f64 (sqsum), d->tiny_bound),79vget_low_u32 (d->thres));8081if (unlikely (v_any_u32h (special)))82return special_case (x, y, sqsum, special);8384return vsqrtq_f64 (sqsum);85}86#endif8788TEST_SIG (V, D, 2, hypot, -10.0, 10.0)89TEST_ULP (V_NAME_D2 (hypot), 1.21)90TEST_DISABLE_FENV_IF_NOT (V_NAME_D2 (hypot), WANT_SIMD_EXCEPT)91TEST_INTERVAL2 (V_NAME_D2 (hypot), 0, inf, 0, inf, 10000)92TEST_INTERVAL2 (V_NAME_D2 (hypot), 0, inf, -0, -inf, 10000)93TEST_INTERVAL2 (V_NAME_D2 (hypot), -0, -inf, 0, inf, 10000)94TEST_INTERVAL2 (V_NAME_D2 (hypot), -0, -inf, -0, -inf, 10000)959697