Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libm/machine/spu/headers/asinhf4.h')
-rw-r--r--newlib/libm/machine/spu/headers/asinhf4.h36
1 files changed, 25 insertions, 11 deletions
diff --git a/newlib/libm/machine/spu/headers/asinhf4.h b/newlib/libm/machine/spu/headers/asinhf4.h
index 6a8a3b5da..95feb0fe2 100644
--- a/newlib/libm/machine/spu/headers/asinhf4.h
+++ b/newlib/libm/machine/spu/headers/asinhf4.h
@@ -96,8 +96,8 @@
#define ASINH_MAC25 6.4472103118896484375000000000000000000000000000000000000000000000000000E-3
#define ASINH_MAC27 -5.7400376708419234664351851851851851851851851851851851851851851851851852E-3
#define ASINH_MAC29 5.1533096823199041958512931034482758620689655172413793103448275862068966E-3
-#if 0
#define ASINH_MAC31 -4.6601434869150961599042338709677419354838709677419354838709677419354839E-3
+#if 0
#define ASINH_MAC33 4.2409070936793630773370916193181818181818181818181818181818181818181818E-3
#define ASINH_MAC35 -3.8809645588376692363194056919642857142857142857142857142857142857142857E-3
#define ASINH_MAC37 3.5692053938259345454138678473395270270270270270270270270270270270270270E-3
@@ -107,34 +107,43 @@
#endif
-
static __inline vector float _asinhf4(vector float x)
{
vec_float4 sign_mask = spu_splats(-0.0f);
vec_float4 onef = spu_splats(1.0f);
- vec_float4 result, fresult, mresult;;
+ vec_uint4 oneu = spu_splats(1u);
+ vec_uint4 twou = spu_splats(2u);
+ vec_uint4 threeu = spu_splats(3u);
+ vec_float4 ln2 = spu_splats(6.931471805599453094172321E-1f);
+ vec_float4 largef = spu_splats(9.21e18f);
+ vec_float4 result, fresult, mresult;
vec_float4 xabs, xsqu;
/* Where we switch from maclaurin to formula */
- vec_float4 switch_approx = spu_splats(0.685f);
+ vec_float4 switch_approx = spu_splats(0.74f);
+ vec_float4 trunc_part2 = spu_splats(20.0f);
+ vec_uint4 truncadd;
+ vec_uint4 islarge;
vec_uint4 use_form;
-
xabs = spu_andc(x, sign_mask);
xsqu = spu_mul(x, x);
+ islarge = spu_cmpgt(xabs, largef);
/*
* Formula:
* asinh = ln(|x| + sqrt(x^2 + 1))
*/
- fresult = _sqrtf4(spu_madd(x, x, onef));
- fresult = spu_add(xabs, fresult);
- fresult = _logf4(fresult);
+ vec_float4 logarg = spu_add(xabs, _sqrtf4(spu_madd(xabs, xabs, onef)));
+ logarg = spu_sel(logarg, xabs, islarge);
+ fresult = _logf4(logarg);
+ fresult = spu_sel(fresult, spu_add(fresult, ln2), islarge);
/*
* Maclaurin Series
*/
- mresult = spu_madd(xsqu, spu_splats((float)ASINH_MAC29), spu_splats((float)ASINH_MAC27));
+ mresult = spu_madd(xsqu, spu_splats((float)ASINH_MAC31), spu_splats((float)ASINH_MAC29));
+ mresult = spu_madd(xsqu, mresult, spu_splats((float)ASINH_MAC27));
mresult = spu_madd(xsqu, mresult, spu_splats((float)ASINH_MAC25));
mresult = spu_madd(xsqu, mresult, spu_splats((float)ASINH_MAC23));
mresult = spu_madd(xsqu, mresult, spu_splats((float)ASINH_MAC21));
@@ -150,13 +159,18 @@ static __inline vector float _asinhf4(vector float x)
mresult = spu_madd(xsqu, mresult, spu_splats((float)ASINH_MAC01));
mresult = spu_mul(xabs, mresult);
-
/*
* Choose between series and formula
*/
- use_form = spu_cmpgt(xabs, switch_approx);
+ use_form = spu_cmpgt(xabs, switch_approx);
result = spu_sel(mresult, fresult, use_form);
+ /*
+ * Truncation correction on spu
+ */
+ truncadd = spu_sel(oneu, threeu, use_form);
+ truncadd = spu_sel(truncadd, twou, spu_cmpgt(xabs, trunc_part2));
+ result = (vec_float4)spu_add((vec_uint4)result, truncadd);
/* Preserve sign - asinh is anti-symmetric */
result = spu_sel(result, x, (vec_uint4)sign_mask);