|
|
|
@ -459,6 +459,7 @@ int test6(long arg)
|
|
|
|
|
unsigned long results[6];
|
|
|
|
|
unsigned long v;
|
|
|
|
|
|
|
|
|
|
set_fpscr(0);
|
|
|
|
|
for (i = 0; i < sizeof(sp_dp_equiv) / sizeof(sp_dp_equiv[0]); ++i) {
|
|
|
|
|
v = sp_dp_equiv[i].dp;
|
|
|
|
|
asm("lfd%U0%X0 3,%0; fmr 6,3; fneg 7,3; stfd 6,0(%1); stfd 7,8(%1)"
|
|
|
|
@ -474,6 +475,8 @@ int test6(long arg)
|
|
|
|
|
results[4] != (v & ~SIGN) ||
|
|
|
|
|
results[5] != (v | SIGN))
|
|
|
|
|
return i + 1;
|
|
|
|
|
if (get_fpscr() != 0)
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -484,6 +487,98 @@ int fpu_test_6(void)
|
|
|
|
|
return trapit(0, test6);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned long expected_fprf(unsigned long result, bool single)
|
|
|
|
|
{
|
|
|
|
|
unsigned long sign = (result >> 63) & 1;
|
|
|
|
|
unsigned long exp = (result >> 52) & 0x7ff;
|
|
|
|
|
unsigned long mant = (result & ((1ul << 52) - 1));
|
|
|
|
|
|
|
|
|
|
if (exp == 0x7ff) {
|
|
|
|
|
/* infinity or NaN */
|
|
|
|
|
if (mant)
|
|
|
|
|
return 0x11; /* NaN */
|
|
|
|
|
if (sign)
|
|
|
|
|
return 0x09; /* -Infinity */
|
|
|
|
|
else
|
|
|
|
|
return 0x05; /* +Infinity */
|
|
|
|
|
} else if (exp > (single ? 0x380 : 0)) {
|
|
|
|
|
if (sign)
|
|
|
|
|
return 0x08; /* -normalized */
|
|
|
|
|
else
|
|
|
|
|
return 0x04; /* +normalized */
|
|
|
|
|
} else if (mant || exp > 0) {
|
|
|
|
|
if (sign)
|
|
|
|
|
return 0x18; /* -denorm */
|
|
|
|
|
else
|
|
|
|
|
return 0x14; /* +denorm */
|
|
|
|
|
} else {
|
|
|
|
|
if (sign)
|
|
|
|
|
return 0x12; /* -zero */
|
|
|
|
|
else
|
|
|
|
|
return 0x02; /* +zero */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned long expected_fprf_sp(unsigned long result)
|
|
|
|
|
{
|
|
|
|
|
unsigned long sign = (result >> 31) & 1;
|
|
|
|
|
unsigned long exp = (result >> 23) & 0xff;
|
|
|
|
|
unsigned long mant = (result & ((1ul << 23) - 1));
|
|
|
|
|
|
|
|
|
|
if (exp == 0xff) {
|
|
|
|
|
/* infinity or NaN */
|
|
|
|
|
if (mant)
|
|
|
|
|
return 0x11; /* NaN */
|
|
|
|
|
if (sign)
|
|
|
|
|
return 0x09; /* -Infinity */
|
|
|
|
|
else
|
|
|
|
|
return 0x05; /* +Infinity */
|
|
|
|
|
} else if (exp > 0) {
|
|
|
|
|
if (sign)
|
|
|
|
|
return 0x08; /* -normalized */
|
|
|
|
|
else
|
|
|
|
|
return 0x04; /* +normalized */
|
|
|
|
|
} else if (mant) {
|
|
|
|
|
if (sign)
|
|
|
|
|
return 0x18; /* -denorm */
|
|
|
|
|
else
|
|
|
|
|
return 0x14; /* +denorm */
|
|
|
|
|
} else {
|
|
|
|
|
if (sign)
|
|
|
|
|
return 0x12; /* -zero */
|
|
|
|
|
else
|
|
|
|
|
return 0x02; /* +zero */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int check_fprf(unsigned long result, bool single, unsigned long fpscr)
|
|
|
|
|
{
|
|
|
|
|
unsigned long fprf;
|
|
|
|
|
|
|
|
|
|
fprf = expected_fprf(result, single);
|
|
|
|
|
if (((fpscr >> 12) & 0x1f) == fprf)
|
|
|
|
|
return 0;
|
|
|
|
|
print_string("\r\n");
|
|
|
|
|
print_hex(result, 16, " ");
|
|
|
|
|
print_hex(fpscr, 8, " ");
|
|
|
|
|
print_hex(fprf, 2, " ");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int check_fprf_sp(unsigned long result, unsigned long fpscr)
|
|
|
|
|
{
|
|
|
|
|
unsigned long fprf;
|
|
|
|
|
|
|
|
|
|
fprf = expected_fprf_sp(result);
|
|
|
|
|
if (((fpscr >> 12) & 0x1f) == fprf)
|
|
|
|
|
return 0;
|
|
|
|
|
print_string("\r\n");
|
|
|
|
|
print_hex(result, 16, " ");
|
|
|
|
|
print_hex(fpscr, 8, " ");
|
|
|
|
|
print_hex(fprf, 2, " ");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct int_fp_equiv {
|
|
|
|
|
long ival;
|
|
|
|
|
unsigned long fp;
|
|
|
|
@ -522,12 +617,15 @@ int test7(long arg)
|
|
|
|
|
{
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long results[4];
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(intvals) / sizeof(intvals[0]); ++i) {
|
|
|
|
|
set_fpscr(0);
|
|
|
|
|
asm("lfd%U0%X0 3,%0; fcfid 6,3; fcfidu 7,3; stfd 6,0(%1); stfd 7,8(%1)"
|
|
|
|
|
: : "m" (intvals[i].ival), "b" (results) : "memory");
|
|
|
|
|
asm("fcfids 9,3; stfd 9,16(%0); fcfidus 10,3; stfd 10,24(%0)"
|
|
|
|
|
: : "b" (results) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (results[0] != intvals[i].fp ||
|
|
|
|
|
results[1] != intvals[i].fp_u ||
|
|
|
|
|
results[2] != intvals[i].fp_s ||
|
|
|
|
@ -539,6 +637,8 @@ int test7(long arg)
|
|
|
|
|
print_hex(results[3], 16, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(results[3], true, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -582,16 +682,20 @@ int test8(long arg)
|
|
|
|
|
{
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long result;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(roundvals) / sizeof(roundvals[0]); ++i) {
|
|
|
|
|
asm("lfd 3,0(%0); lfd 4,8(%0); mtfsf 0,3,1,0; frsp 6,4; stfd 6,0(%1)"
|
|
|
|
|
: : "b" (&roundvals[i]), "b" (&result) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (result != roundvals[i].spval) {
|
|
|
|
|
print_string("\r\n");
|
|
|
|
|
print_hex(i, 4, " ");
|
|
|
|
|
print_hex(result, 16, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(result, true, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -796,6 +900,7 @@ int test11(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long results[4];
|
|
|
|
|
struct frivals *vp = frivals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(frivals) / sizeof(frivals[0]); ++i, ++vp) {
|
|
|
|
|
set_fpscr(FPS_RN_FLOOR);
|
|
|
|
@ -807,6 +912,7 @@ int test11(long arg)
|
|
|
|
|
asm("frip 5,3; stfd 5,16(%0)" : : "b" (results) : "memory");
|
|
|
|
|
set_fpscr(FPS_RN_CEIL);
|
|
|
|
|
asm("frim 5,3; stfd 5,24(%0)" : : "b" (results) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (results[0] != vp->nval || results[1] != vp->zval ||
|
|
|
|
|
results[2] != vp->pval || results[3] != vp->mval) {
|
|
|
|
|
print_hex(i, 2, "\r\n");
|
|
|
|
@ -816,6 +922,8 @@ int test11(long arg)
|
|
|
|
|
print_hex(results[3], 16, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(results[3], false, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -903,17 +1011,21 @@ int test13(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long results[2];
|
|
|
|
|
struct addvals *vp = addvals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(addvals) / sizeof(addvals[0]); ++i, ++vp) {
|
|
|
|
|
asm("lfd 5,0(%0); lfd 6,8(%0); fadd 7,5,6; fsub 8,5,6; stfd 7,0(%1); stfd 8,8(%1)"
|
|
|
|
|
: : "b" (&vp->val_a), "b" (results) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (results[0] != vp->sum || results[1] != vp->diff) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
|
print_hex(results[0], 16, " ");
|
|
|
|
|
print_hex(results[1], 16, "\r\n");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(results[1], false, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -976,18 +1088,22 @@ int test14(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long results[2];
|
|
|
|
|
struct addvals *vp = sp_addvals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(sp_addvals) / sizeof(sp_addvals[0]); ++i, ++vp) {
|
|
|
|
|
asm("lfd 5,0(%0); frsp 5,5; lfd 6,8(%0); frsp 6,6; "
|
|
|
|
|
"fadds 7,5,6; fsubs 8,5,6; stfd 7,0(%1); stfd 8,8(%1)"
|
|
|
|
|
: : "b" (&vp->val_a), "b" (results) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (results[0] != vp->sum || results[1] != vp->diff) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
|
print_hex(results[0], 16, " ");
|
|
|
|
|
print_hex(results[1], 16, "\r\n");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(results[1], true, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -1017,16 +1133,20 @@ int test15(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long result;
|
|
|
|
|
struct mulvals *vp = mulvals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(mulvals) / sizeof(mulvals[0]); ++i, ++vp) {
|
|
|
|
|
asm("lfd 5,0(%0); lfd 6,8(%0); fmul 7,5,6; stfd 7,0(%1)"
|
|
|
|
|
: : "b" (&vp->val_a), "b" (&result) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (result != vp->prod) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
|
print_hex(result, 16, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(result, false, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -1056,16 +1176,20 @@ int test16(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned int result;
|
|
|
|
|
struct mulvals_sp *vp = mulvals_sp;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(mulvals_sp) / sizeof(mulvals_sp[0]); ++i, ++vp) {
|
|
|
|
|
asm("lfs 5,0(%0); lfs 6,4(%0); fmuls 7,5,6; stfs 7,0(%1)"
|
|
|
|
|
: : "b" (&vp->val_a), "b" (&result) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (result != vp->prod) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
|
print_hex(result, 8, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf_sp(result, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -1086,6 +1210,10 @@ struct divvals {
|
|
|
|
|
{ 0xbff0000000000000, 0x3ff0000000000000, 0xbff0000000000000 },
|
|
|
|
|
{ 0x4000000000000000, 0x4008000000000000, 0x3fe5555555555555 },
|
|
|
|
|
{ 0xc01fff0007ffffff, 0xc03ffffffdffffbf, 0x3fcfff0009fff041 },
|
|
|
|
|
{ 0x0010000000000000, 0x0018000000000000, 0x3fe5555555555555 },
|
|
|
|
|
{ 0x0008000000000000, 0x0018000000000000, 0x3fd5555555555555 },
|
|
|
|
|
{ 0x0010000000000000, 0x0000c00000000000, 0x4035555555555555 },
|
|
|
|
|
{ 0x0004000000000000, 0x0000300000000000, 0x4035555555555555 },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int test17(long arg)
|
|
|
|
@ -1093,16 +1221,20 @@ int test17(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long result;
|
|
|
|
|
struct divvals *vp = divvals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(divvals) / sizeof(divvals[0]); ++i, ++vp) {
|
|
|
|
|
asm("lfd 5,0(%0); lfd 6,8(%0); fdiv 7,5,6; stfd 7,0(%1)"
|
|
|
|
|
: : "b" (&vp->val_a), "b" (&result) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (result != vp->prod) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
|
print_hex(result, 16, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(result, false, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -1123,6 +1255,9 @@ struct recipvals {
|
|
|
|
|
{ 0xbff0000000000000, 0xbfeff00400000000 },
|
|
|
|
|
{ 0x4008000000000000, 0x3fd54e3800000000 },
|
|
|
|
|
{ 0xc03ffffffdffffbf, 0xbfa0040000000000 },
|
|
|
|
|
{ 0x0008100000000000, 0x7fdfb0c400000000 },
|
|
|
|
|
{ 0x0004080000000000, 0x7fefb0c400000000 },
|
|
|
|
|
{ 0x0002040000000000, 0x7ff0000000000000 },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int test18(long arg)
|
|
|
|
@ -1130,16 +1265,20 @@ int test18(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long result;
|
|
|
|
|
struct recipvals *vp = recipvals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(recipvals) / sizeof(recipvals[0]); ++i, ++vp) {
|
|
|
|
|
asm("lfd 6,0(%0); fre 7,6; stfd 7,0(%1)"
|
|
|
|
|
: : "b" (&vp->val), "b" (&result) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (result != vp->inv) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
|
print_hex(result, 16, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(result, false, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -1273,16 +1412,20 @@ int test21(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long result;
|
|
|
|
|
struct isqrtvals *vp = isqrtvals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(isqrtvals) / sizeof(isqrtvals[0]); ++i, ++vp) {
|
|
|
|
|
asm("lfd 6,0(%0); frsqrte 7,6; stfd 7,0(%1)"
|
|
|
|
|
: : "b" (&vp->val), "b" (&result) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (result != vp->inv) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
|
print_hex(result, 16, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(result, false, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -1320,16 +1463,20 @@ int test22(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long result;
|
|
|
|
|
struct sqrtvals *vp = sqrtvals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(sqrtvals) / sizeof(sqrtvals[0]); ++i, ++vp) {
|
|
|
|
|
asm("lfd 6,0(%0); fsqrt 7,6; stfd 7,0(%1)"
|
|
|
|
|
: : "b" (&vp->val), "b" (&result) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (result != vp->inv) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
|
print_hex(result, 16, " ");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(result, false, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -1384,6 +1531,7 @@ int test23(long arg)
|
|
|
|
|
long i;
|
|
|
|
|
unsigned long results[4];
|
|
|
|
|
struct fmavals *vp = fmavals;
|
|
|
|
|
unsigned long fpscr;
|
|
|
|
|
|
|
|
|
|
set_fpscr(FPS_RN_NEAR);
|
|
|
|
|
for (i = 0; i < sizeof(fmavals) / sizeof(fmavals[0]); ++i, ++vp) {
|
|
|
|
@ -1391,6 +1539,7 @@ int test23(long arg)
|
|
|
|
|
: : "b" (&vp->ra), "b" (results) : "memory");
|
|
|
|
|
asm("fmsub 1,6,7,8; fnmadd 2,6,7,8; fnmsub 3,6,7,8; stfd 1,8(%0); stfd 2,16(%0); stfd 3,24(%0)"
|
|
|
|
|
: : "b" (results) : "memory");
|
|
|
|
|
fpscr = get_fpscr();
|
|
|
|
|
if (results[0] != vp->fma || results[1] != vp->fms ||
|
|
|
|
|
results[2] != vp->nfma || results[3] != vp->nfms) {
|
|
|
|
|
print_hex(i, 2, " ");
|
|
|
|
@ -1400,6 +1549,8 @@ int test23(long arg)
|
|
|
|
|
print_hex(results[3], 16, "\r\n");
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
if (check_fprf(results[3], false, fpscr))
|
|
|
|
|
return i + 0x101;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|