Lines 20-45
Link Here
|
20 |
#include <math.h> |
20 |
#include <math.h> |
21 |
|
21 |
|
22 |
|
22 |
|
23 |
/* Use the -inf rounding mode conversion instructions to implement floor. */ |
23 |
/* Use the -inf rounding mode conversion instructions to implement |
|
|
24 |
floor. We note when the exponent is large enough that the value |
25 |
must be integral, as this avoids unpleasant integer overflows. */ |
24 |
|
26 |
|
25 |
float |
27 |
float |
26 |
__floorf (float x) |
28 |
__floorf (float x) |
27 |
{ |
29 |
{ |
28 |
float two23 = copysignf (0x1.0p23, x); |
30 |
if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ |
29 |
float r, tmp; |
31 |
{ |
30 |
|
32 |
/* Note that Alpha S_Floating is stored in registers in a |
31 |
__asm ( |
33 |
restricted T_Floating format, so we don't even need to |
|
|
34 |
convert back to S_Floating in the end. The initial |
35 |
conversion to T_Floating is needed to handle denormals. */ |
36 |
|
37 |
float tmp1, tmp2, new_x; |
38 |
|
39 |
__asm ("cvtst/s %3,%2\n\t" |
32 |
#ifdef _IEEE_FP_INEXACT |
40 |
#ifdef _IEEE_FP_INEXACT |
33 |
"adds/suim %2, %3, %1\n\tsubs/suim %1, %3, %0" |
41 |
"cvttq/svim %2,%1\n\t" |
34 |
#else |
42 |
#else |
35 |
"adds/sum %2, %3, %1\n\tsubs/sum %1, %3, %0" |
43 |
"cvttq/svm %2,%1\n\t" |
36 |
#endif |
44 |
#endif |
37 |
: "=&f"(r), "=&f"(tmp) |
45 |
"cvtqt/m %1,%0\n\t" |
38 |
: "f"(x), "f"(two23)); |
46 |
: "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) |
|
|
47 |
: "f"(x)); |
39 |
|
48 |
|
40 |
/* floor(-0) == -0, and in general we'll always have the same |
49 |
/* floor(-0) == -0, and in general we'll always have the same |
41 |
sign as our input. */ |
50 |
sign as our input. */ |
42 |
return copysignf (r, x); |
51 |
x = copysignf(new_x, x); |
|
|
52 |
} |
53 |
return x; |
43 |
} |
54 |
} |
44 |
|
55 |
|
45 |
weak_alias (__floorf, floorf) |
56 |
weak_alias (__floorf, floorf) |