* soft-fp/double.h (FP_CMP_UNORD_D): Also define in

[_FP_W_TYPE_SIZE >= 64] case.
	* soft-fp/extended.h (FP_CMP_UNORD_E): Likewise.
	* soft-fp/quad.h (FP_CMP_UNORD_Q): Likewise.
This commit is contained in:
Roland McGrath 2006-01-30 22:27:31 +00:00
parent f964490f3c
commit 1e832e3759
8 changed files with 86 additions and 81 deletions

View File

@ -1,3 +1,10 @@
2006-01-29 Joseph S. Myers <joseph@codesourcery.com>
* soft-fp/double.h (FP_CMP_UNORD_D): Also define in
[_FP_W_TYPE_SIZE >= 64] case.
* soft-fp/extended.h (FP_CMP_UNORD_E): Likewise.
* soft-fp/quad.h (FP_CMP_UNORD_Q): Likewise.
2006-01-27 Dwayne Grant McConnell <decimal@us.ibm.com> 2006-01-27 Dwayne Grant McConnell <decimal@us.ibm.com>
Jakub Jelinek <jakub@redhat.com> Jakub Jelinek <jakub@redhat.com>
Roland McGrath <roland@redhat.com> Roland McGrath <roland@redhat.com>

View File

@ -3566,6 +3566,13 @@ llround_test (void)
TEST_f_L (llround, -72057594037927936.5L, -72057594037927937LL); TEST_f_L (llround, -72057594037927936.5L, -72057594037927937LL);
TEST_f_L (llround, -72057594037927936.75L, -72057594037927937LL); TEST_f_L (llround, -72057594037927936.75L, -72057594037927937LL);
TEST_f_L (llround, -72057594037927937.5L, -72057594037927938LL); TEST_f_L (llround, -72057594037927937.5L, -72057594037927938LL);
TEST_f_L (llround, 9223372036854775806.25L, 9223372036854775806LL);
TEST_f_L (llround, -9223372036854775806.25L, -9223372036854775806LL);
TEST_f_L (llround, 9223372036854775806.5L, 9223372036854775807LL);
TEST_f_L (llround, -9223372036854775806.5L, -9223372036854775807LL);
TEST_f_L (llround, 9223372036854775807.0L, 9223372036854775807LL);
TEST_f_L (llround, -9223372036854775807.0L, -9223372036854775807LL);
#endif #endif
END (llround); END (llround);

View File

@ -188,6 +188,7 @@ union _FP_UNION_D
#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) #define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un)
#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) #define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y)
#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y)
#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) #define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg)
#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) #define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt)

View File

@ -379,6 +379,7 @@ union _FP_UNION_E
#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) #define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un)
#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) #define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y)
#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,2,r,X,Y)
#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg) #define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg)
#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt) #define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt)

View File

@ -195,6 +195,7 @@ union _FP_UNION_Q
#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un) #define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un)
#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y) #define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y)
#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y)
#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg) #define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg)
#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt) #define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt)

View File

@ -623,38 +623,6 @@ ifloat: 2
ildouble: 3 ildouble: 3
ldouble: 3 ldouble: 3
# llround
Test "llround (4503599627370496.5) == 4503599627370497LL":
ildouble: -1
ldouble: -1
Test "llround (4503599627370497.5) == 4503599627370498LL":
ildouble: -1
ldouble: -1
Test "llround (72057594037927935.5) == 72057594037927936LL":
ildouble: -1
ldouble: -1
Test "llround (72057594037927936.5) == 72057594037927937LL":
ildouble: -1
ldouble: -1
Test "llround (72057594037927936.75) == 72057594037927937LL":
ildouble: -1
ldouble: -1
Test "llround (72057594037927937.5) == 72057594037927938LL":
ildouble: -1
ldouble: -1
Test "llround (9007199254740991.5) == 9007199254740992LL":
ildouble: -1
ldouble: -1
Test "llround (9007199254740992.5) == 9007199254740993LL":
ildouble: -1
ldouble: -1
Test "llround (9007199254740992.75) == 9007199254740993LL":
ildouble: -1
ldouble: -1
Test "llround (9007199254740993.5) == 9007199254740994LL":
ildouble: -1
ldouble: -1
# log10 # log10
Test "log10 (0.75) == -0.124938736608299953132449886193870744": Test "log10 (0.75) == -0.124938736608299953132449886193870744":
double: 1 double: 1

View File

@ -51,7 +51,7 @@ ENTRY (__ceill)
fabs fp9,fp2 fabs fp9,fp2
fsub fp12,fp13,fp13 /* generate 0.0 */ fsub fp12,fp13,fp13 /* generate 0.0 */
fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
fcmpo cr6,fp1,fp12 /* if (x > 0.0) */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
bnl- cr7,.L2 bnl- cr7,.L2
mtfsfi 7,2 /* Set rounding mode toward +inf. */ mtfsfi 7,2 /* Set rounding mode toward +inf. */
fneg fp2,fp12 fneg fp2,fp12

View File

@ -67,79 +67,99 @@
*/ */
ENTRY (__llroundl) ENTRY (__llroundl)
mffs fp7 /* Save current FPU rounding mode. */
fabs fp0,fp1 fabs fp0,fp1
lfd fp13,.LC2@toc(2) /* 2**52 */ lfd fp13,.LC2@toc(2) /* 2**52 */
lfd fp12,.LC3@toc(2) /* 2**63 */ lfd fp12,.LC3@toc(2) /* 2**63 */
lfd fp11,.LC0@toc(2) /* 0.0 */ lfd fp11,.LC0@toc(2) /* 0.0 */
lfd fp10,.LC1@toc(2) /* 0.5 */ lfd fp10,.LC1@toc(2) /* 0.5 */
fcmpu cr0,fp0,fp12 /* if (x < TWO63 */ fabs fp9,fp2
fcmpu cr7,fp0,fp13 /* if (x < TWO52 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
fcmpu cr6,fp1,fp11 /* if (x > 0.0) */ fcmpu cr6,fp1,fp11 /* if (x > 0.0) */
bge- cr0,.L2 bnl- cr7,.L2
bge- cr7,.L8 mtfsfi 7,1 /* Set rounding mode toward 0. */
ble- cr6,.L4 ble- cr6,.L1
fadd fp4,fp2,fp10 /* x+= 0.5; */ fadd fp9,fp1,fp10 /* x+= 0.5; */
fadd fp5,fp1,fp4 /* x+= 0.5; */ b .L0
.L9: .L1:
fctidz fp3,fp5 /* Convert To Integer DW llround toward 0. */ fsub fp9,fp1,fp10 /* x-= 0.5; */
stfd fp3,-16(r1) .L0:
fctid fp0,fp9
stfd fp0,-16(r1)
mtfsf 0x01,fp7 /* restore previous rounding mode. */
nop /* Insure the following load is in a different dispatch group */ nop /* Insure the following load is in a different dispatch group */
nop /* to avoid pipe stall on POWER4&5. */ nop /* to avoid pipe stall on POWER4&5. */
nop nop
ld r3,-16(r1) ld r3,-16(r1)
blr blr
.L4:
fsub fp4,fp2,fp10 /* x-= 0.5; */
fadd fp5,fp1,fp4 /* x+= 0.5; */
b .L9
.L8:
ble cr6,.L6
fneg fp10,fp10
.L6:
fadd fp2,fp2,fp10
fctidz fp3,fp1 /* Convert To Integer DW llround toward 0. */
fctidz fp4,fp2 /* Convert To Integer DW llround toward 0. */
stfd fp3,-16(r1)
stfd fp4,-8(r1)
nop /* Insure the following load is in a different dispatch group */
nop /* to avoid pipe stall on POWER4&5. */
nop
ld r3,-16(r1)
ld r0,-8(r1)
add r3,r3,r0
blr
.L2:
/* The high double is >= TWO63 so it looks like we are "out of range".
But this may be caused by rounding of the high double and the
negative low double may bring it back into range. So we need to
de-round the high double and invert the low double without changing
the effective long double value. To do this we compute a special
value (tau) that we can subtract from the high double and add to
the low double before conversion. The resulting integers can be
summed to get the total value.
tau = floor(x_high/TWO52); /* The high double is > TWO52 so we need to round the low double and
perhaps the high double. In this case we have to round the low
double and handle any adjustment to the high double that may be
caused by rounding (up). This is complicated by the fact that the
high double may already be rounded and the low double may have the
opposite sign to compensate.This gets a bit tricky so we use the
following algorithm:
tau = trunc(x_high/TWO52);
x0 = x_high - tau; x0 = x_high - tau;
x1 = x_low + tau; */ x1 = x_low + tau;
r1 = round(x1);
y_high = x0 + r1;
y_low = x0 - y_high + r1;
return y; */
.L2: .L2:
fcmpu cr7,fp0,fp12 /* if (|x_high| > TWO63) */
fcmpu cr0,fp9,fp11 /* || (|x_low| == 0.0) */
fmr fp9,fp1
fcmpu cr5,fp2,fp11 /* if (x_low > 0.0) */
bgt- cr7,.L0 /* return llround(x); */
mtfsfi 7,1 /* Set rounding mode toward 0. */
fdiv fp8,fp1,fp13 /* x_high/TWO52 */ fdiv fp8,fp1,fp13 /* x_high/TWO52 */
bgt- cr0,.L9 /* if x > TWO63 */
bng- cr6,.L6 /* if (x > 0.0) */
fctidz fp0,fp8 fctidz fp0,fp8
fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ fcfid fp8,fp0 /* tau = trunc(x_high/TWO52); */
bng cr5,.L4 /* if (x_low > 0.0) */
fmr fp3,fp1
fmr fp4,fp2
b .L5
.L4: /* if (x_low < 0.0) */
fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
fctid fp11,fp3 .L5:
fctid fp12,fp4 fadd fp5,fp4,fp10 /* r1 = x1 + 0.5; */
b .L9
.L6: /* if (x < 0.0) */
fctidz fp0,fp8
fcfid fp8,fp0 /* tau = trunc(x_high/TWO52); */
bnl cr5,.L7 /* if (x_low < 0.0) */
fmr fp3,fp1
fmr fp4,fp2
b .L8
.L7: /* if (x_low > 0.0) */
fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
.L8:
fsub fp5,fp4,fp10 /* r1 = x1 - 0.5; */
.L9:
fctid. fp11,fp3
fctid fp12,fp5
stfd fp11,-16(r1) stfd fp11,-16(r1)
stfd fp12,-8(r1) stfd fp12,-8(r1)
mtfsf 0x01,fp7 /* restore previous rounding mode. */
nop /* Insure the following load is in a different dispatch group */ nop /* Insure the following load is in a different dispatch group */
nop /* to avoid pipe stall on POWER4&5. */ nop /* to avoid pipe stall on POWER4&5. */
nop nop
ld r3,-16(r1) ld r3,-16(r1)
bunlr cr1 /* if not overflow, return. */
ld r0,-8(r1) ld r0,-8(r1)
addo. r3,r3,r0 addo. r3,r3,r0
bnslr+ cr0 /* if the sum does not overflow, return. */ bnslr cr0
b .L9 /* Otherwise we want to set "invalid operation". */ fmr fp9,fp12
bng cr6,.L0
fneg fp9,fp12
b .L0
END (__llroundl) END (__llroundl)
strong_alias (__llroundl, __lroundl) strong_alias (__llroundl, __lroundl)