1*412f47f9SXin Li /*
2*412f47f9SXin Li * Single-precision SVE hypot(x) function.
3*412f47f9SXin Li *
4*412f47f9SXin Li * Copyright (c) 2023, Arm Limited.
5*412f47f9SXin Li * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
6*412f47f9SXin Li */
7*412f47f9SXin Li
8*412f47f9SXin Li #include "sv_math.h"
9*412f47f9SXin Li #include "pl_sig.h"
10*412f47f9SXin Li #include "pl_test.h"
11*412f47f9SXin Li
12*412f47f9SXin Li #define TinyBound 0x0c800000 /* asuint (0x1p-102). */
13*412f47f9SXin Li #define Thres 0x73000000 /* 0x70000000 - TinyBound. */
14*412f47f9SXin Li
15*412f47f9SXin Li static svfloat32_t NOINLINE
special_case(svfloat32_t sqsum,svfloat32_t x,svfloat32_t y,svbool_t pg,svbool_t special)16*412f47f9SXin Li special_case (svfloat32_t sqsum, svfloat32_t x, svfloat32_t y, svbool_t pg,
17*412f47f9SXin Li svbool_t special)
18*412f47f9SXin Li {
19*412f47f9SXin Li return sv_call2_f32 (hypotf, x, y, svsqrt_x (pg, sqsum), special);
20*412f47f9SXin Li }
21*412f47f9SXin Li
22*412f47f9SXin Li /* SVE implementation of single-precision hypot.
23*412f47f9SXin Li Maximum error observed is 1.21 ULP:
24*412f47f9SXin Li _ZGVsMxvv_hypotf (0x1.6a213cp-19, -0x1.32b982p-26) got 0x1.6a2346p-19
25*412f47f9SXin Li want 0x1.6a2344p-19. */
SV_NAME_F2(hypot)26*412f47f9SXin Li svfloat32_t SV_NAME_F2 (hypot) (svfloat32_t x, svfloat32_t y,
27*412f47f9SXin Li const svbool_t pg)
28*412f47f9SXin Li {
29*412f47f9SXin Li svfloat32_t sqsum = svmla_x (pg, svmul_x (pg, x, x), y, y);
30*412f47f9SXin Li
31*412f47f9SXin Li svbool_t special = svcmpge (
32*412f47f9SXin Li pg, svsub_x (pg, svreinterpret_u32 (sqsum), TinyBound), Thres);
33*412f47f9SXin Li
34*412f47f9SXin Li if (unlikely (svptest_any (pg, special)))
35*412f47f9SXin Li return special_case (sqsum, x, y, pg, special);
36*412f47f9SXin Li
37*412f47f9SXin Li return svsqrt_x (pg, sqsum);
38*412f47f9SXin Li }
39*412f47f9SXin Li
40*412f47f9SXin Li PL_SIG (SV, F, 2, hypot, -10.0, 10.0)
41*412f47f9SXin Li PL_TEST_ULP (SV_NAME_F2 (hypot), 0.71)
42*412f47f9SXin Li PL_TEST_INTERVAL2 (SV_NAME_F2 (hypot), 0, inf, 0, inf, 10000)
43*412f47f9SXin Li PL_TEST_INTERVAL2 (SV_NAME_F2 (hypot), 0, inf, -0, -inf, 10000)
44*412f47f9SXin Li PL_TEST_INTERVAL2 (SV_NAME_F2 (hypot), -0, -inf, 0, inf, 10000)
45*412f47f9SXin Li PL_TEST_INTERVAL2 (SV_NAME_F2 (hypot), -0, -inf, -0, -inf, 10000)
46