1
0
mirror of https://github.com/prirun/p50em.git synced 2026-04-02 19:40:10 +00:00

bs: flt.pt. fixes, fix ecb copy in PCL

This commit is contained in:
Jim
2011-10-20 10:44:04 -04:00
parent 7075729d8c
commit e43a2167f0
3 changed files with 150 additions and 155 deletions

186
em.c
View File

@@ -2938,11 +2938,12 @@ static pcl (ea_t ecbea) {
if (access == 1 && (ecbea & 0xF) != 0)
fault(ACCESSFAULT, 0, ecbea);
if ((pa & 01777) <= 02000 - sizeof(ecb)/sizeof(ecb[0])) {
memcpy(ecb, MEM+pa, sizeof(ecb)); //BS
memcpy(ecb, MEM+pa, sizeof(ecb));
for (i=0; i<9; i++)
swap16(ecb[i]);
} else {
*(long long *)(ecb+0) = get64(ecbea+0);
*(long long *)(ecb+4) = get64(ecbea+4);
ecb[8] = get16(ecbea+8);
for (i=0; i<9; i++)
ecb[i] = get16(ecbea+i);
}
TRACE(T_PCL, " ecb.pb: %o/%o\n ecb.framesize: %d\n ecb.stackroot %o\n ecb.argdisp: %o\n ecb.nargs: %d\n ecb.lb: %o/%o\n ecb.keys: %o\n", ecb[0], ecb[1], ecb[2], ecb[3], ecb[4], ecb[5], ecb[6], ecb[7], ecb[8]);
@@ -7128,15 +7129,26 @@ d_flot: /* 0140550 */
goto fetch;
d_frn: /* 0140534 */
TRACE(T_FLOW, " FRN\n");
CLEARC;
frn(crsl+FAC1);
{
int oflow;
TRACE(T_FLOW, " FRN\n");
CLEARC;
putfr64(2, frn(getfr64(2), &oflow));
if (oflow)
mathexception('f', FC_DFP_OFLOW, 0);
}
goto fetch;
d_dfcm: /* 0140574 */
TRACE(T_FLOW, " DFCM\n");
dfcm(crsl+FAC1);
goto fetch;
{
int oflow;
TRACE(T_FLOW, " DFCM\n");
dfcmfac1:
putfr64(2, dfcm(getfr64(2), &oflow));
if (oflow)
mathexception('f', FC_DFP_OFLOW, 0);
goto fetch;
}
d_adll: /* 0141000 */
TRACE(T_FLOW, " ADLL\n");
@@ -7145,8 +7157,7 @@ d_adll: /* 0141000 */
d_fcmv: /* 0140530 */
TRACE(T_FLOW, " FCMv\n");
dfcm(crsl+FAC1);
goto fetch;
goto dfcmfac1;
d_fsze: /* 0140510 */
TRACE(T_FLOW, " FSZE\n");
@@ -7187,7 +7198,7 @@ d_fsgt: /* 0140515 */
d_int: /* 0140554 */
TRACE(T_FLOW, " INTr\n");
/* XXX: do -1073741824.5 and 1073741823.5 work on Prime, or overflow? */
if (prieee8(crs+FLTH, &tempd) && -1073741824.0 <= tempd && tempd <= 1073741823.0) {
if (prieee8(getfr64(2), &tempd) && -1073741824.0 <= tempd && tempd <= 1073741823.0) {
templ = tempd;
putcrs16(B, templ & 0x7FFF);
putcrs16(A, templ >> 15);
@@ -7199,7 +7210,7 @@ d_int: /* 0140554 */
d_inta: /* 0140531 */
TRACE(T_FLOW, " INTA\n");
/* XXX: do 32767.5 and -32768.5 work on Prime, or overflow? */
if (prieee8(crs+FLTH, &tempd) && -32768.0 <= tempd && tempd <= 32767.0) {
if (prieee8(getfr64(2), &tempd) && -32768.0 <= tempd && tempd <= 32767.0) {
putcrs16(A, (short)tempd);
CLEARC;
} else
@@ -7214,7 +7225,7 @@ d_flta: /* 0140532 */
d_intl: /* 0140533 */
TRACE(T_FLOW, " INTL\n");
if (prieee8(crs+FLTH, &tempd) && -2147483648.0 <= tempd && tempd <= 2147483647.0) {
if (prieee8(getfr64(2), &tempd) && -2147483648.0 <= tempd && tempd <= 2147483647.0) {
putcrs32s(L, tempd);
CLEARC;
} else
@@ -7967,8 +7978,14 @@ imode:
break;
case 0144:
TRACE(T_FLOW, " DFCM\n");
dfcm(crsl+FAC0+dr);
{
int oflow;
TRACE(T_FLOW, " DFCM\n");
dfcmdr:
putfr64(dr, dfcm(getfr64(dr), &oflow));
if (oflow)
mathexception('f', FC_DFP_OFLOW, 0);
}
break;
case 0130:
@@ -7993,7 +8010,7 @@ imode:
case 0100:
TRACE(T_FLOW, " FCM\n");
dfcm(crsl+FAC0+dr);
goto dfcmdr;
break;
case 0105:
@@ -8017,9 +8034,14 @@ imode:
break;
case 0107:
TRACE(T_FLOW, " FRN\n");
CLEARC;
frn(crsl+FAC0+dr);
{
int oflow;
TRACE(T_FLOW, " FRN\n");
CLEARC;
putfr64(2, frn(getfr64(dr), &oflow));
if (oflow)
mathexception('f', FC_DFP_OFLOW, 0);
}
break;
case 0146: /* I-mode FRNM */
@@ -8079,7 +8101,7 @@ imode:
case 0103:
TRACE(T_FLOW, " INT 0\n");
if (prieee8(crsl+FAC0, &tempd) && -2147483648.0 <= tempd && tempd <= 2147483647.0) {
if (prieee8(getfr64(0), &tempd) && -2147483648.0 <= tempd && tempd <= 2147483647.0) {
putgr32s(dr, tempd);
CLEARC;
} else
@@ -8088,7 +8110,7 @@ imode:
case 0113:
TRACE(T_FLOW, " INT 1\n");
if (prieee8(crsl+FAC1, &tempd) && -2147483648.0 <= tempd && tempd <= 2147483647.0) {
if (prieee8(getfr64(2), &tempd) && -2147483648.0 <= tempd && tempd <= 2147483647.0) {
putgr32s(dr, (int)tempd);
CLEARC;
} else
@@ -8097,7 +8119,7 @@ imode:
case 0101:
TRACE(T_FLOW, " INTH 0\n");
if (prieee8(crsl+FAC0, &tempd) && -32768.0 <= tempd && tempd <= 32767.0) {
if (prieee8(getfr64(0), &tempd) && -32768.0 <= tempd && tempd <= 32767.0) {
putgr16s(dr, (short)tempd);
CLEARC;
} else
@@ -8106,7 +8128,7 @@ imode:
case 0111:
TRACE(T_FLOW, " INTH 1\n");
if (prieee8(crsl+FAC1, &tempd) && -32768.0 <= tempd && tempd <= 32767.0) {
if (prieee8(getfr64(2), &tempd) && -32768.0 <= tempd && tempd <= 32767.0) {
putgr16s(dr, (short)tempd);
CLEARC;
} else
@@ -8631,7 +8653,7 @@ imode:
utempl = ((immu64 >> 32) & 0xffffff00) | (immu64 & 0xff);
else
utempl = get32(ea);
fcs(crsl+FAC0+dr, utempl);
fcs(getfr64(dr), utempl);
break;
case 5:
@@ -8640,7 +8662,7 @@ imode:
TRACE(T_FLOW, " DFC\n");
if (*(int *)&ea >= 0)
immu64 = get64(ea);
dfcs(crsl+FAC0+dr, immu64);
dfcs(getfr64(dr), immu64);
break;
default:
@@ -8718,6 +8740,7 @@ imode:
case 016: /* Special MR FP format */
/* FST, DFST, FA, DFA */
switch (dr) {
int oflow;
case 0:
case 2:
dr &= 2;
@@ -8725,7 +8748,7 @@ imode:
CLEARC;
if (*(int *)&ea >= 0) {
if (getcrs16(KEYS) & 010)
frn(crsl+FAC0+dr);
putfr64(2, frn(getfr64(2), &oflow)); /* sing prec can't overflow */
if ((getgr32(FAC0+dr+1) & 0xFF00) == 0)
put32((getfr32(dr) & 0xFFFFFF00) | (getgr32(FAC0+dr+1) & 0xFF), ea);
else
@@ -8761,8 +8784,8 @@ imode:
tempa1 = getgr32(FAC0+dr+1) & 0xffff;
tempa2 = immu64 & 0xffff;
if (abs(tempa1-tempa2) < 48)
if (prieee8(crsl+FAC0+dr, &tempd1)
&& prieee8(&immu64, &tempd2)
if (prieee8(getfr64(dr), &tempd1)
&& prieee8(immu64, &tempd2)
&& ieeepr8(tempd1+tempd2, (long long *)(crsl+FAC0+dr), 0))
CLEARC;
else
@@ -8783,8 +8806,8 @@ imode:
immu64 = get64(ea);
if (*(int *)&immu64)
if (getgr32s(FAC0+dr))
if (prieee8(crsl+FAC0+dr, &tempd1)
&& prieee8(&immu64, &tempd2)
if (prieee8(getfr64(dr), &tempd1)
&& prieee8(immu64, &tempd2)
&& ieeepr8(tempd1+tempd2, (long long *)(crsl+FAC0+dr), 0))
CLEARC;
else
@@ -8875,19 +8898,19 @@ imode:
tempa1 = getgr32(FAC0+dr+1) & 0xffff;
tempa2 = immu64 & 0xffff;
if (abs(tempa1-tempa2) < 48)
if (prieee8(crsl+FAC0+dr, &tempd1)
&& prieee8(&immu64, &tempd2)
if (prieee8(getfr64(dr), &tempd1)
&& prieee8(immu64, &tempd2)
&& ieeepr8(tempd1-tempd2, (long long *)(crsl+FAC0+dr), 0))
CLEARC;
else
mathexception('f', FC_SFP_OFLOW, ea);
else if (tempa1 < tempa2) {
putgr64s(FAC0+dr, immu64);
dfcm(crsl+FAC0+dr);
goto dfcmdr;
}
} else {
putgr64s(FAC0+dr, immu64);
dfcm(crsl+FAC0+dr);
goto dfcmdr;
}
else if (getgr32s(FAC0+dr) == 0)
putgr64s(FAC0+dr, 0);
@@ -8901,15 +8924,15 @@ imode:
immu64 = get64(ea);
if (*(int *)&immu64)
if (getgr32s(FAC0+dr))
if (prieee8(crsl+FAC0+dr, &tempd1)
&& prieee8(&immu64, &tempd2)
if (prieee8(getfr64(dr), &tempd1)
&& prieee8(immu64, &tempd2)
&& ieeepr8(tempd1-tempd2, (long long *)(crsl+FAC0+dr), 0))
CLEARC;
else
mathexception('f', FC_DFP_OFLOW, ea);
else {
putgr64s(FAC0+dr, immu64);
dfcm(crsl+FAC0+dr);
goto dfcmdr;
}
else if (getgr32s(FAC0+dr) == 0)
putgr64s(FAC0+dr, 0);
@@ -8925,8 +8948,8 @@ imode:
immu64 = ((immu64 << 32) & 0xffffff0000000000LL) | (immu64 & 0xff);
}
if (*(int *)&immu64)
if (prieee8(&immu64, &tempd2)
&& prieee8(crsl+FAC0+dr, &tempd1)
if (prieee8(immu64, &tempd2)
&& prieee8(getfr64(dr), &tempd1)
&& ieeepr8(tempd1*tempd2, (long long *)(crsl+FAC0+dr), 0))
CLEARC;
else
@@ -8945,8 +8968,8 @@ imode:
if (*(int *)&ea >= 0)
immu64 = get64(ea);
if (*(int *)&immu64)
if (prieee8(&immu64, &tempd2)
&& prieee8(crsl+FAC0+dr, &tempd1)
if (prieee8(immu64, &tempd2)
&& prieee8(getfr64(dr), &tempd1)
&& ieeepr8(tempd1*tempd2, (long long *)(crsl+FAC0+dr), 0))
CLEARC;
else
@@ -9023,8 +9046,8 @@ imode:
}
if (*(int *)&immu64)
if (getgr32s(FAC0+dr))
if (prieee8(&immu64, &tempd2)
&& prieee8(crsl+FAC0+dr, &tempd1)
if (prieee8(immu64, &tempd2)
&& prieee8(getfr64(dr), &tempd1)
&& ieeepr8(tempd1/tempd2, (long long *)(crsl+FAC0+dr), 1))
CLEARC;
else
@@ -9043,8 +9066,8 @@ imode:
immu64 = get64(ea);
if (*(int *)&immu64)
if (getgr32s(FAC0+dr))
if (prieee8(&immu64, &tempd2)
&& prieee8(crsl+FAC0+dr, &tempd1)
if (prieee8(immu64, &tempd2)
&& prieee8(getfr64(dr), &tempd1)
&& ieeepr8(tempd1/tempd2, (long long *)(crsl+FAC0+dr), 1))
CLEARC;
else
@@ -9973,8 +9996,8 @@ d_fad: /* 00601 */
tempa1 = getcrs16(FEXP);
tempa2 = immu64 & 0xffff;
if (abs(tempa1-tempa2) < 48)
if (prieee8(crsl+FAC1, &tempd1)
&& prieee8(&immu64, &tempd2)
if (prieee8(getfr64(2), &tempd1)
&& prieee8(immu64, &tempd2)
&& ieeepr8(tempd1+tempd2, (long long *)(crsl+FAC1), 0))
CLEARC;
else
@@ -9992,7 +10015,7 @@ d_fad: /* 00601 */
d_fcs: /* 01101 */
TRACE(T_FLOW, " FCS\n");
templ = get32(ea);
RPL += fcs(crsl+FAC1, templ);
RPL += fcs(getfr64(2), templ);
goto fetch;
d_fdv: /* 01701 */
@@ -10001,8 +10024,8 @@ d_fdv: /* 01701 */
immu64 = ((immu64 << 32) & 0xffffff0000000000LL) | (immu64 & 0xff);
if (*(int *)&immu64)
if (getgr32s(FAC1))
if (prieee8(&immu64, &tempd2)
&& prieee8(crsl+FAC1, &tempd1)
if (prieee8(immu64, &tempd2)
&& prieee8(getfr64(2), &tempd1)
&& ieeepr8(tempd1/tempd2, (long long *)(crsl+FAC1), 1))
CLEARC;
else
@@ -10026,8 +10049,8 @@ d_fmp: /* 01601 */
immu64 = get32(ea);
immu64 = ((immu64 << 32) & 0xffffff0000000000LL) | (immu64 & 0xff);
if (*(int *)&immu64)
if (prieee8(&immu64, &tempd2)
&& prieee8(crsl+FAC1, &tempd1)
if (prieee8(immu64, &tempd2)
&& prieee8(getfr64(2), &tempd1)
&& ieeepr8(tempd1*tempd2, (long long *)(crsl+FAC1), 0))
CLEARC;
else
@@ -10047,33 +10070,38 @@ d_fsb: /* 00701 */
tempa1 = getcrs16(FEXP);
tempa2 = immu64 & 0xffff;
if (abs(tempa1-tempa2) < 48)
if (prieee8(crsl+FAC1, &tempd1)
&& prieee8(&immu64, &tempd2)
if (prieee8(getfr64(2), &tempd1)
&& prieee8(immu64, &tempd2)
&& ieeepr8(tempd1-tempd2, (long long *)(crsl+FAC1), 0))
CLEARC;
else
mathexception('f', FC_SFP_OFLOW, ea);
else if (tempa1 < tempa2) {
putgr64s(FAC1, immu64);
dfcm(crsl+FAC1);
goto dfcmfac1;
}
} else {
putgr64s(FAC1, immu64);
dfcm(crsl+FAC1);
goto dfcmfac1;
}
else if (getgr32s(FAC1) == 0)
putgr64s(FAC1, 0);
goto fetch;
d_fst: /* 0401 */
TRACE(T_FLOW, " FST\n");
CLEARC;
if (getcrs16(KEYS) & 010)
frn(crsl+FAC1);
if ((getgr32(FAC1+1) & 0xFF00) == 0)
put32((getgr32(FAC1) & 0xFFFFFF00) | (getgr32(FAC1+1) & 0xFF), ea);
else
mathexception('f', FC_SFP_STORE, ea);
{
int oflow;
unsigned long long dfp;
TRACE(T_FLOW, " FST\n");
CLEARC;
if (getcrs16(KEYS) & 010)
putfr64(2, frn(getfr64(2), &oflow)); /* sing prec can't overflow */
dfp = getfr64(2);
if ((dfp & 0xFF00) == 0)
put32(((dfp & 0xFFFFFF0000000000LL) >> 32) | (dfp & 0xFF), ea);
else
mathexception('f', FC_SFP_STORE, ea);
}
goto fetch;
d_dfad: /* 0602 */
@@ -10081,8 +10109,8 @@ d_dfad: /* 0602 */
immu64 = get64(ea);
if (*(int *)&immu64)
if (getgr32s(FAC1))
if (prieee8(crsl+FAC1, &tempd1)
&& prieee8(&immu64, &tempd2)
if (prieee8(getfr64(2), &tempd1)
&& prieee8(immu64, &tempd2)
&& ieeepr8(tempd1+tempd2, (long long *)(crsl+FAC1), 0)) {
CLEARC;
TRACE(T_FLOW, " %f ('%o %o %o %o) + %f (%o %o %o %o)\n", tempd1, getcrs16(FLTH), getcrs16(FLTL), getcrs16(FLTD), getcrs16(FEXP), tempd2, (unsigned short)(immu64>>48), (unsigned short)((immu64>>32)&0xffff), (unsigned short)((immu64>>16)&0xffff), (unsigned short)(immu64&0xffff));
@@ -10098,7 +10126,7 @@ d_dfad: /* 0602 */
d_dfcs: /* 01102 */
TRACE(T_FLOW, " DFCS\n");
templl = get64(ea);
RPL += dfcs(crsl+FAC1, templl);
RPL += dfcs(getfr64(2), templl);
goto fetch;
d_dfdv: /* 01702 */
@@ -10107,8 +10135,8 @@ d_dfdv: /* 01702 */
immu64 = get64(ea);
if (*(int *)&immu64)
if (getgr32s(FAC1))
if (prieee8(&immu64, &tempd2)
&& prieee8(crsl+FAC1, &tempd1)
if (prieee8(immu64, &tempd2)
&& prieee8(getfr64(2), &tempd1)
&& ieeepr8(tempd1/tempd2, (long long *)(crsl+FAC1), 1)) {
CLEARC;
TRACE(T_FLOW, " %f ('%o %o %o %o) / %f (%o %o %o %o)\n", tempd1, getcrs16(FLTH), getcrs16(FLTL), getcrs16(FLTD), getcrs16(FEXP), tempd2, (unsigned short)(immu64>>48), (unsigned short)((immu64>>32)&0xffff), (unsigned short)((immu64>>16)&0xffff), (unsigned short)(immu64&0xffff));
@@ -10125,7 +10153,7 @@ d_dfld: /* 0202 */
TRACE(T_FLOW, " DFLD\n");
putcrs64s(FLTH, get64(ea));
#ifndef NOTRACE
if (!prieee8(crs+FLTH, &tempd1))
if (!prieee8(getfr64(2), &tempd1))
tempd1 = -0.0;
#endif
TRACE(T_FLOW, " Loaded %f '%o %o %o %o\n", tempd1, getcrs16(FLTH), getcrs16(FLTL), getcrs16(FLTD), getcrs16(FEXP));
@@ -10136,8 +10164,8 @@ d_dfmp: /* 01602 */
if (getgr32s(FAC1)) {
immu64 = get64(ea);
if (*(int *)&immu64)
if (prieee8(&immu64, &tempd2)
&& prieee8(crsl+FAC1, &tempd1)
if (prieee8(immu64, &tempd2)
&& prieee8(getfr64(2), &tempd1)
&& ieeepr8(tempd1*tempd2, (long long *)(crsl+FAC1), 0)) {
CLEARC;
TRACE(T_FLOW, " %f ('%o %o %o %o) * %f (%o %o %o %o)\n", tempd1, getcrs16(FLTH), getcrs16(FLTL), getcrs16(FLTD), getcrs16(FEXP), tempd2, (unsigned short)(immu64>>48), (unsigned short)((immu64>>32)&0xffff), (unsigned short)((immu64>>16)&0xffff), (unsigned short)(immu64&0xffff));
@@ -10155,8 +10183,8 @@ d_dfsb: /* 0702 */
immu64 = get64(ea);
if (*(int *)&immu64)
if (getgr32s(FAC1))
if (prieee8(crsl+FAC1, &tempd1)
&& prieee8(&immu64, &tempd2)
if (prieee8(getfr64(2), &tempd1)
&& prieee8(immu64, &tempd2)
&& ieeepr8(tempd1-tempd2, (long long *)(crsl+FAC1), 0)) {
CLEARC;
TRACE(T_FLOW, " %f ('%o %o %o %o) - %f (%o %o %o %o)\n", tempd1, getcrs16(FLTH), getcrs16(FLTL), getcrs16(FLTD), getcrs16(FEXP), tempd2, (unsigned short)(immu64>>48), (unsigned short)((immu64>>32)&0xffff), (unsigned short)((immu64>>16)&0xffff), (unsigned short)(immu64&0xffff));
@@ -10165,7 +10193,7 @@ d_dfsb: /* 0702 */
mathexception('f', FC_DFP_OFLOW, ea);
else {
putgr64s(FAC1, immu64);
dfcm(crsl+FAC1);
goto dfcmfac1;
}
else if (getgr32s(FAC1) == 0)
putgr64s(FAC1, 0);
@@ -10175,10 +10203,10 @@ d_dfst: /* 0402 */
TRACE(T_FLOW, " DFST\n");
put64(getcrs64s(FLTH), ea);
#ifndef NOTRACE
if (!prieee8(crs+FLTH, &tempd1))
if (!prieee8(getfr64(2), &tempd1))
tempd1 = -0.0;
#endif
TRACE(T_FLOW, " Stored %f '%o %o %o %o\n", tempd1, getcrs16(FLTH), getcrs16(FLTL), getcrs16(FLTD), getcrs16(FEXP));
#endif
goto fetch;
d_ealb: /* 01302 */

106
fp.h
View File

@@ -40,17 +40,13 @@ http://tima-cmp.imag.fr/~guyot/Cours/Oparithm/english/Op_Ar2.htm
/* getdp unpacks a Prime DPFP into 48-bit sign + mantissa (left
justified in 64 bits) and a 32-bit signed exponent */
inline getdp (void *p, long long *frac64, int *exp32) {
inline getdp (unsigned long long p, long long *frac64, int *exp32) {
*frac64 = *(long long *)p & 0xFFFFFFFFFFFF0000LL; /* unpack fraction */
*exp32 = *((short *)p+3); /* unpack SIGNED exponent */
}
inline putdp (void *p, long long frac64, int exp32) {
*(long long *)p = (frac64 & 0xFFFFFFFFFFFF0000LL) | (exp32 & 0xFFFF);
*frac64 = p & 0xFFFFFFFFFFFF0000LL; /* unpack fraction */
*exp32 = (short) (p & 0xFFFFLL); /* unpack SIGNED exponent */
}
#define RETFP(frac64, exp32) return ((frac64) & 0xFFFFFFFFFFFF0000LL) | ((exp32) & 0xFFFF)
/* Conversion from Prime DPFP to IEEE DPFP
Returns true if conversion succeeded, false if it failed.
@@ -58,20 +54,7 @@ inline putdp (void *p, long long frac64, int exp32) {
IEEE DPFP exponents are only 11 bits.
*/
/* Floating point conversion caches.
1st entry is a Prime-format DPFP number.
2nd entry is the corresponding IEEE DPFP number.
Unused entries are 0.0
There are two corresponding hash arrays, one for Prime entries
and a 2nd for IEEE entries. Whenever a conversion is done, both
types of entries are updated. */
static double fpcache[2][512];
static short primecix[512];
static short ieeecix[512];
int prieee8(void *dp, double *d) {
int prieee8(unsigned long long dp, double *d) {
long long frac64, sign;
int exp32;
@@ -107,7 +90,7 @@ int prieee8(void *dp, double *d) {
/* normalize positive fraction until bit 2 is 1 */
while ((*(int *)&frac64 & 0x40000000) == 0) {
while ((frac64 & 0x4000000000000000LL) == 0) {
frac64 = frac64 << 1;
exp32--;
}
@@ -226,7 +209,7 @@ retry:
/* XXX: should this be a subtract for negative numbers? */
frac64 += 0x10000;
*p = (frac64 & 0xffffffffffff0000LL) | (exp32 & 0xffff);
*p = swap64((frac64 & 0xffffffffffff0000LL) | (exp32 & 0xffff));
return okay;
}
@@ -272,12 +255,12 @@ double fltl (int int32) {
/* Prime DPFP complement */
dfcm (void *dp) {
unsigned long long dfcm (unsigned long long dp, int *oflow) {
long long frac64;
int exp32, oflow;
int exp32;
CLEARC;
oflow = 0;
*oflow = 0;
getdp(dp, &frac64, &exp32);
if (frac64 != 0) { /* can't normalize zero */
if (frac64 == 0x8000000000000000LL) { /* overflow case? */
@@ -290,37 +273,34 @@ dfcm (void *dp) {
exp32--;
}
}
putdp(dp, frac64, exp32);
oflow = exp32 > 32767 || exp32 < -32768;
if (exp32 > 32767 || exp32 < -32768)
*oflow = 1;
RETFP(frac64, exp32);
} else
*(double *)dp = 0.0;; /* DFCM is documented to clean up dirty zeroes */
if (oflow)
mathexception('f', FC_DFP_OFLOW, 0);
RETFP(0, 0); /* DFCM is documented to clean up dirty zeroes */
}
/* double precision floating point normalize
Passed a pointer to a Prime double precision variable and updates
it in place. May set the C-bit or cause a floating point
exception. */
Passed a Prime double precision variable and returns normalized
value and overflow flag. */
void norm(void *dp) {
unsigned long long norm(unsigned long long dp, int *oflow) {
long long frac64;
int exp32;
*oflow = 0;
getdp(dp, &frac64, &exp32);
while ((frac64 ^ (frac64 << 1)) >= 0) {
frac64 = frac64 << 1;
exp32--;
}
putdp(dp, frac64, exp32);
if (exp32 > 32767 || exp32 < -32768)
mathexception('f', FC_DFP_OFLOW, 0);
*oflow = 1;
RETFP(frac64, exp32);
}
/* double->single floating point round (FRN) instruction.
Passed a pointer to a Prime double precision variable, one of the
@@ -329,14 +309,15 @@ void norm(void *dp) {
NOTE: this routine is coded strangely because I ran into compiler
bugs (gcc 4.0.1) */
void frn(void *dp) {
unsigned long long frn(unsigned long long dp, int *oflow) {
long long frac64;
int exp32;
int doround1, doround2;
*oflow = 0;
getdp(dp, &frac64, &exp32);
if (frac64 == 0)
*(long long *)dp = 0;
return 0;
else {
doround1 = ((frac64 & 0x18000000000LL) != 0);
doround2 = ((frac64 & 0x8000000000LL) != 0) && ((frac64 & 0x7FFFFF0000LL) != 0);
@@ -349,8 +330,8 @@ void frn(void *dp) {
exp32++;
}
frac64 |= (exp32 & 0xFFFF);
norm(&frac64);
*(long long *)dp = frac64;
frac64 = norm(frac64, oflow);
return frac64;
}
}
}
@@ -362,16 +343,16 @@ void frn(void *dp) {
RPL should be advanced.
*/
int fcs (unsigned int *fac, int fop) {
int fcs (unsigned long long fac, int fop) {
int templ;
short fopexp, facexp;
CLEARCC;
templ = fac[0] & 0xffffff00; /* FAC SP mantissa */
templ = (fac & 0xffffff0000000000LL) >> 32; /* FAC SP mantissa */
if (templ == 0) /* fix dirty zero */
facexp = 0;
else
facexp = fac[1] & 0xffff; /* FAC exponent */
facexp = fac & 0xffff; /* FAC exponent */
fopexp = fop & 0xff;
fop = fop & 0xffffff00;
if (fop == 0) /* fix dirty zero */
@@ -410,12 +391,12 @@ int fcs (unsigned int *fac, int fop) {
Prime ASCII characters in the DAC) won't convert to IEEE.
*/
int dfcs (unsigned int *fac, long long fop) {
int dfcs (unsigned long long fac, long long fop) {
long long templl;
short fopexp, facexp;
CLEARCC;
templl = *(long long *)fac;
templl = fac;
facexp = templl & 0xffff; /* FAC exponent */
templl = templl & 0xffffffffffff0000LL; /* FAC SP mantissa */
if (templl == 0) /* fix dirty zero */
@@ -448,30 +429,3 @@ int dfcs (unsigned int *fac, long long fop) {
} else
return 0; /* FAC > operand */
}
#if 0
/* Prime DPFP multiply */
dfmp(void *dp1, void *dp2, ea_t ea) {
long long frac64, frac641, frac642;
int exp32, exp321, exp322;
short fcode;
fcode = 0;
CLEARC;
getdp(dp1, &frac641, &exp321);
getdp(dp2, &frac642, &exp322);
exp32 = exp321 + exp322;
/* XXX: need to get 128-bit result to test for overflow? */
frac64 = frac641 * frac642;
if (exp32 > 32767 || exp32 < -32768)
fcode = FC_DFP_OFLOW;
/* insert (optional) rounding code here */
if (fcode == 0)
putdp(dp1, frac64, exp32);
else
mathexception('f', fcode, ea);
}
#endif

13
regs.h
View File

@@ -373,6 +373,19 @@ static inline int64_t putgr64s(int offset, int64_t val) { \
pointer to FR0, then use offset as an index */
#define getfr32(offset) getgr32(FAC0+offset)
/* fetch 64-bit unsigned at FP register 0 or 1
For FP 0, offset=0; for FP 1, offset=2 */
static inline uint64_t getfr64(int offset) { \
return (uint64_t) swap64(*(unsigned long long *)(crsl+FAC0+offset));
}
/* put 64-bit double in FP reg 0 or 1
For FP 0, offset=0; for FP 1, offset=2 */
//#define putfr64(offset, val)
static inline double putfr64(int offset, unsigned long long val) { \
*(unsigned long long *)(crsl+FAC0+offset) = swap64((val));
}
/* put 64-bit double in FP reg 0 or 1
For FP 0, offset=0; for FP 1, offset=2 */
//#define putfr64d(offset, val) *(double *)(crsl+FAC0+offset) = (val)