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:
186
em.c
186
em.c
@@ -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
106
fp.h
@@ -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
13
regs.h
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user