PCem
changeset 6:83ee72aa1453
Fixed value of TOP when using FSAVE/FRSTOR. Infinity and NaN should now be preserved when loading/storing 80-bit floating point.
| author | TomW |
|---|---|
| date | Sun Jul 07 12:05:53 2013 +0100 |
| parents | fe9cf232a465 |
| children | 41678958f2e8 |
| files | src/x87.c |
| diffstat | 1 files changed, 41 insertions(+), 21 deletions(-) [+] |
line diff
1.1 --- a/src/x87.c Tue Jun 25 21:46:25 2013 +0100 1.2 +++ b/src/x87.c Sun Jul 07 12:05:53 2013 +0100 1.3 @@ -158,16 +158,22 @@ 1.4 test.eind.ll |= (uint64_t)readmeml(easeg,eaaddr+4)<<32; 1.5 test.begin = readmemw(easeg,eaaddr+8); 1.6 1.7 - int64_t exp64 = (((test.begin&0x7fff) - BIAS80)); 1.8 - int64_t blah = ((exp64 >0)?exp64:-exp64)&0x3ff; 1.9 - int64_t exp64final = ((exp64 >0)?blah:-blah) +BIAS64; 1.10 + int64_t exp64 = (((test.begin&0x7fff) - BIAS80)); 1.11 + int64_t blah = ((exp64 >0)?exp64:-exp64)&0x3ff; 1.12 + int64_t exp64final = ((exp64 >0)?blah:-blah) +BIAS64; 1.13 1.14 - int64_t mant64 = (test.eind.ll >> 11) & (0xfffffffffffff); 1.15 - int64_t sign = (test.begin&0x8000)?1:0; 1.16 + int64_t mant64 = (test.eind.ll >> 11) & (0xfffffffffffff); 1.17 + int64_t sign = (test.begin&0x8000)?1:0; 1.18 1.19 - if (test.eind.ll&0x400) mant64++; 1.20 -// pclog("LD80 %08X %08X\n",test.eind.ll,mant64); 1.21 - test.eind.ll = (sign <<63)|(exp64final << 52)| mant64; 1.22 + if ((test.begin & 0x7fff) == 0x7fff) 1.23 + exp64final = 0x7ff; 1.24 + if ((test.begin & 0x7fff) == 0) 1.25 + exp64final = 0; 1.26 + if (test.eind.ll & 0x400) 1.27 + mant64++; 1.28 + 1.29 + test.eind.ll = (sign <<63)|(exp64final << 52)| mant64; 1.30 + 1.31 return test.eind.d; 1.32 } 1.33 1.34 @@ -181,20 +187,29 @@ 1.35 uint64_t ll; 1.36 } eind; 1.37 } test; 1.38 + 1.39 test.eind.d=d; 1.40 - int64_t sign80 = (test.eind.ll&(0x8000000000000000))?1:0; 1.41 - int64_t exp80 = test.eind.ll&(0x7ff0000000000000); 1.42 - int64_t exp80final = (exp80>>52); 1.43 - int64_t mant80 = test.eind.ll&(0x000fffffffffffff); 1.44 - int64_t mant80final = (mant80 << 11); 1.45 - if(d != 0){ //Zero is a special case 1.46 - // Elvira wants the 8 and tcalc doesn't 1.47 - mant80final |= (0x8000000000000000); 1.48 - //Ca-cyber doesn't like this when result is zero. 1.49 - exp80final += (BIAS80 - BIAS64); 1.50 - } 1.51 - test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; 1.52 - test.eind.ll = mant80final; 1.53 + 1.54 + int64_t sign80 = (test.eind.ll&(0x8000000000000000))?1:0; 1.55 + int64_t exp80 = test.eind.ll&(0x7ff0000000000000); 1.56 + int64_t exp80final = (exp80>>52); 1.57 + int64_t mant80 = test.eind.ll&(0x000fffffffffffff); 1.58 + int64_t mant80final = (mant80 << 11); 1.59 + 1.60 + if (exp80final == 0x7ff) /*Infinity / Nan*/ 1.61 + { 1.62 + exp80final = 0x7fff; 1.63 + mant80final |= (0x8000000000000000); 1.64 + } 1.65 + else if (d != 0){ //Zero is a special case 1.66 + // Elvira wants the 8 and tcalc doesn't 1.67 + mant80final |= (0x8000000000000000); 1.68 + //Ca-cyber doesn't like this when result is zero. 1.69 + exp80final += (BIAS80 - BIAS64); 1.70 + } 1.71 + test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; 1.72 + test.eind.ll = mant80final; 1.73 + 1.74 writememl(easeg,eaaddr,test.eind.ll); 1.75 writememl(easeg,eaaddr+4,test.eind.ll>>32); 1.76 writememw(easeg,eaaddr+8,test.begin); 1.77 @@ -983,9 +998,14 @@ 1.78 ST(6)=x87_ld80(); eaaddr+=10; 1.79 ST(7)=x87_ld80(); 1.80 cycles-=(cr0&1)?34:44; 1.81 +/* pclog("new TOP %i\n", TOP); 1.82 + pclog("%04X %04X %04X %f %f %f %f %f %f %f %f\n", npxc, npxs, tag, ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7));*/ 1.83 return; 1.84 case 6: /*FSAVE*/ 1.85 if (fplog) pclog("FSAVE %08X:%08X\n", easeg, eaaddr); 1.86 + npxs = (npxs & ~(7 << 11)) | (TOP << 11); 1.87 +/* pclog("old TOP %i %04X\n", TOP, npxs); 1.88 + pclog("%04X %04X %04X %f %f %f %f %f %f %f %f\n", npxc, npxs, tag, ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7));*/ 1.89 switch ((cr0&1)|(op32&0x100)) 1.90 { 1.91 case 0x000: /*16-bit real mode*/
