math: use double_t for temporaries to avoid stores on i386

When FLT_EVAL_METHOD!=0 (only i386 with x87 fp) the excess
precision of an expression must be removed in an assignment.
(gcc needs -fexcess-precision=standard or -std=c99 for this)

This is done by extra load/store instructions which adds code
bloat when lot of temporaries are used and it makes the result
less precise in many cases.
Using double_t and float_t avoids these issues on i386 and
it makes no difference on other archs.

For now only a few functions are modified where the excess
precision is clearly beneficial (mostly polynomial evaluations
with temporaries).

object size differences on i386, gcc-4.8:
             old   new
__cosdf.o    123    95
__cos.o      199   169
__sindf.o    131    95
__sin.o      225   203
__tandf.o    207   151
__tan.o      605   499
erff.o      1470  1416
erf.o       1703  1649
j0f.o       1779  1745
j0.o        2308  2274
j1f.o       1602  1568
j1.o        2286  2252
tgamma.o    1431  1424
math/*.o   64164 63635
This commit is contained in:
Szabolcs Nagy
2013-05-15 23:08:52 +00:00
parent 2c184264ea
commit e216951f50
21 changed files with 31 additions and 28 deletions

View File

@ -86,7 +86,7 @@ sb7 = -2.2440952301e+01; /* 0xc1b38712 */
static float erfc1(float x)
{
float s,P,Q;
float_t s,P,Q;
s = fabsf(x) - 1;
P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
@ -96,7 +96,8 @@ static float erfc1(float x)
static float erfc2(uint32_t ix, float x)
{
float s,z,R,S;
float_t s,R,S;
float z;
if (ix < 0x3fa00000) /* |x| < 1.25 */
return erfc1(x);