13ebdd119Saurel32 /* 23ebdd119Saurel32 NetWinder Floating Point Emulator 33ebdd119Saurel32 (c) Rebel.COM, 1998,1999 43ebdd119Saurel32 53ebdd119Saurel32 Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 63ebdd119Saurel32 73ebdd119Saurel32 This program is free software; you can redistribute it and/or modify 83ebdd119Saurel32 it under the terms of the GNU General Public License as published by 93ebdd119Saurel32 the Free Software Foundation; either version 2 of the License, or 103ebdd119Saurel32 (at your option) any later version. 113ebdd119Saurel32 123ebdd119Saurel32 This program is distributed in the hope that it will be useful, 133ebdd119Saurel32 but WITHOUT ANY WARRANTY; without even the implied warranty of 143ebdd119Saurel32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 153ebdd119Saurel32 GNU General Public License for more details. 163ebdd119Saurel32 173ebdd119Saurel32 You should have received a copy of the GNU General Public License 1870539e18SBlue Swirl along with this program; if not, see <http://www.gnu.org/licenses/>. 193ebdd119Saurel32 */ 203ebdd119Saurel32 213ebdd119Saurel32 #include "fpa11.h" 22*6b4c305cSPaolo Bonzini #include "fpu/softfloat.h" 233ebdd119Saurel32 #include "fpopcode.h" 243ebdd119Saurel32 253ebdd119Saurel32 float64 float64_exp(float64 Fm); 263ebdd119Saurel32 float64 float64_ln(float64 Fm); 273ebdd119Saurel32 float64 float64_sin(float64 rFm); 283ebdd119Saurel32 float64 float64_cos(float64 rFm); 293ebdd119Saurel32 float64 float64_arcsin(float64 rFm); 303ebdd119Saurel32 float64 float64_arctan(float64 rFm); 313ebdd119Saurel32 float64 float64_log(float64 rFm); 323ebdd119Saurel32 float64 float64_tan(float64 rFm); 333ebdd119Saurel32 float64 float64_arccos(float64 rFm); 343ebdd119Saurel32 float64 float64_pow(float64 rFn,float64 rFm); 353ebdd119Saurel32 float64 float64_pol(float64 rFn,float64 rFm); 363ebdd119Saurel32 373ebdd119Saurel32 unsigned int DoubleCPDO(const unsigned int opcode) 383ebdd119Saurel32 { 393ebdd119Saurel32 FPA11 *fpa11 = GET_FPA11(); 403ebdd119Saurel32 float64 rFm, rFn = float64_zero; 413ebdd119Saurel32 unsigned int Fd, Fm, Fn, nRc = 1; 423ebdd119Saurel32 433ebdd119Saurel32 //printk("DoubleCPDO(0x%08x)\n",opcode); 443ebdd119Saurel32 453ebdd119Saurel32 Fm = getFm(opcode); 463ebdd119Saurel32 if (CONSTANT_FM(opcode)) 473ebdd119Saurel32 { 483ebdd119Saurel32 rFm = getDoubleConstant(Fm); 493ebdd119Saurel32 } 503ebdd119Saurel32 else 513ebdd119Saurel32 { 523ebdd119Saurel32 switch (fpa11->fType[Fm]) 533ebdd119Saurel32 { 543ebdd119Saurel32 case typeSingle: 553ebdd119Saurel32 rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); 563ebdd119Saurel32 break; 573ebdd119Saurel32 583ebdd119Saurel32 case typeDouble: 593ebdd119Saurel32 rFm = fpa11->fpreg[Fm].fDouble; 603ebdd119Saurel32 break; 613ebdd119Saurel32 623ebdd119Saurel32 case typeExtended: 633ebdd119Saurel32 // !! patb 643ebdd119Saurel32 //printk("not implemented! why not?\n"); 653ebdd119Saurel32 //!! ScottB 663ebdd119Saurel32 // should never get here, if extended involved 673ebdd119Saurel32 // then other operand should be promoted then 683ebdd119Saurel32 // ExtendedCPDO called. 693ebdd119Saurel32 break; 703ebdd119Saurel32 713ebdd119Saurel32 default: return 0; 723ebdd119Saurel32 } 733ebdd119Saurel32 } 743ebdd119Saurel32 753ebdd119Saurel32 if (!MONADIC_INSTRUCTION(opcode)) 763ebdd119Saurel32 { 773ebdd119Saurel32 Fn = getFn(opcode); 783ebdd119Saurel32 switch (fpa11->fType[Fn]) 793ebdd119Saurel32 { 803ebdd119Saurel32 case typeSingle: 813ebdd119Saurel32 rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); 823ebdd119Saurel32 break; 833ebdd119Saurel32 843ebdd119Saurel32 case typeDouble: 853ebdd119Saurel32 rFn = fpa11->fpreg[Fn].fDouble; 863ebdd119Saurel32 break; 873ebdd119Saurel32 883ebdd119Saurel32 default: return 0; 893ebdd119Saurel32 } 903ebdd119Saurel32 } 913ebdd119Saurel32 923ebdd119Saurel32 Fd = getFd(opcode); 933ebdd119Saurel32 /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */ 943ebdd119Saurel32 switch (opcode & MASK_ARITHMETIC_OPCODE) 953ebdd119Saurel32 { 963ebdd119Saurel32 /* dyadic opcodes */ 973ebdd119Saurel32 case ADF_CODE: 983ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status); 993ebdd119Saurel32 break; 1003ebdd119Saurel32 1013ebdd119Saurel32 case MUF_CODE: 1023ebdd119Saurel32 case FML_CODE: 1033ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status); 1043ebdd119Saurel32 break; 1053ebdd119Saurel32 1063ebdd119Saurel32 case SUF_CODE: 1073ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status); 1083ebdd119Saurel32 break; 1093ebdd119Saurel32 1103ebdd119Saurel32 case RSF_CODE: 1113ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status); 1123ebdd119Saurel32 break; 1133ebdd119Saurel32 1143ebdd119Saurel32 case DVF_CODE: 1153ebdd119Saurel32 case FDV_CODE: 1163ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status); 1173ebdd119Saurel32 break; 1183ebdd119Saurel32 1193ebdd119Saurel32 case RDF_CODE: 1203ebdd119Saurel32 case FRD_CODE: 1213ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status); 1223ebdd119Saurel32 break; 1233ebdd119Saurel32 1243ebdd119Saurel32 #if 0 1253ebdd119Saurel32 case POW_CODE: 1263ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm); 1273ebdd119Saurel32 break; 1283ebdd119Saurel32 1293ebdd119Saurel32 case RPW_CODE: 1303ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn); 1313ebdd119Saurel32 break; 1323ebdd119Saurel32 #endif 1333ebdd119Saurel32 1343ebdd119Saurel32 case RMF_CODE: 1353ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status); 1363ebdd119Saurel32 break; 1373ebdd119Saurel32 1383ebdd119Saurel32 #if 0 1393ebdd119Saurel32 case POL_CODE: 1403ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm); 1413ebdd119Saurel32 break; 1423ebdd119Saurel32 #endif 1433ebdd119Saurel32 1443ebdd119Saurel32 /* monadic opcodes */ 1453ebdd119Saurel32 case MVF_CODE: 1463ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = rFm; 1473ebdd119Saurel32 break; 1483ebdd119Saurel32 1493ebdd119Saurel32 case MNF_CODE: 1503ebdd119Saurel32 { 1513ebdd119Saurel32 unsigned int *p = (unsigned int*)&rFm; 152e2542fe2SJuan Quintela #ifdef HOST_WORDS_BIGENDIAN 1533ebdd119Saurel32 p[0] ^= 0x80000000; 1543ebdd119Saurel32 #else 1553ebdd119Saurel32 p[1] ^= 0x80000000; 1563ebdd119Saurel32 #endif 1573ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = rFm; 1583ebdd119Saurel32 } 1593ebdd119Saurel32 break; 1603ebdd119Saurel32 1613ebdd119Saurel32 case ABS_CODE: 1623ebdd119Saurel32 { 1633ebdd119Saurel32 unsigned int *p = (unsigned int*)&rFm; 164e2542fe2SJuan Quintela #ifdef HOST_WORDS_BIGENDIAN 1653ebdd119Saurel32 p[0] &= 0x7fffffff; 1663ebdd119Saurel32 #else 1673ebdd119Saurel32 p[1] &= 0x7fffffff; 1683ebdd119Saurel32 #endif 1693ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = rFm; 1703ebdd119Saurel32 } 1713ebdd119Saurel32 break; 1723ebdd119Saurel32 1733ebdd119Saurel32 case RND_CODE: 1743ebdd119Saurel32 case URD_CODE: 1753ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status); 1763ebdd119Saurel32 break; 1773ebdd119Saurel32 1783ebdd119Saurel32 case SQT_CODE: 1793ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status); 1803ebdd119Saurel32 break; 1813ebdd119Saurel32 1823ebdd119Saurel32 #if 0 1833ebdd119Saurel32 case LOG_CODE: 1843ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_log(rFm); 1853ebdd119Saurel32 break; 1863ebdd119Saurel32 1873ebdd119Saurel32 case LGN_CODE: 1883ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_ln(rFm); 1893ebdd119Saurel32 break; 1903ebdd119Saurel32 1913ebdd119Saurel32 case EXP_CODE: 1923ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_exp(rFm); 1933ebdd119Saurel32 break; 1943ebdd119Saurel32 1953ebdd119Saurel32 case SIN_CODE: 1963ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_sin(rFm); 1973ebdd119Saurel32 break; 1983ebdd119Saurel32 1993ebdd119Saurel32 case COS_CODE: 2003ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_cos(rFm); 2013ebdd119Saurel32 break; 2023ebdd119Saurel32 2033ebdd119Saurel32 case TAN_CODE: 2043ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_tan(rFm); 2053ebdd119Saurel32 break; 2063ebdd119Saurel32 2073ebdd119Saurel32 case ASN_CODE: 2083ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm); 2093ebdd119Saurel32 break; 2103ebdd119Saurel32 2113ebdd119Saurel32 case ACS_CODE: 2123ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_arccos(rFm); 2133ebdd119Saurel32 break; 2143ebdd119Saurel32 2153ebdd119Saurel32 case ATN_CODE: 2163ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_arctan(rFm); 2173ebdd119Saurel32 break; 2183ebdd119Saurel32 #endif 2193ebdd119Saurel32 2203ebdd119Saurel32 case NRM_CODE: 2213ebdd119Saurel32 break; 2223ebdd119Saurel32 2233ebdd119Saurel32 default: 2243ebdd119Saurel32 { 2253ebdd119Saurel32 nRc = 0; 2263ebdd119Saurel32 } 2273ebdd119Saurel32 } 2283ebdd119Saurel32 2293ebdd119Saurel32 if (0 != nRc) fpa11->fType[Fd] = typeDouble; 2303ebdd119Saurel32 return nRc; 2313ebdd119Saurel32 } 2323ebdd119Saurel32 2333ebdd119Saurel32 #if 0 2343ebdd119Saurel32 float64 float64_exp(float64 rFm) 2353ebdd119Saurel32 { 2363ebdd119Saurel32 return rFm; 2373ebdd119Saurel32 //series 2383ebdd119Saurel32 } 2393ebdd119Saurel32 2403ebdd119Saurel32 float64 float64_ln(float64 rFm) 2413ebdd119Saurel32 { 2423ebdd119Saurel32 return rFm; 2433ebdd119Saurel32 //series 2443ebdd119Saurel32 } 2453ebdd119Saurel32 2463ebdd119Saurel32 float64 float64_sin(float64 rFm) 2473ebdd119Saurel32 { 2483ebdd119Saurel32 return rFm; 2493ebdd119Saurel32 //series 2503ebdd119Saurel32 } 2513ebdd119Saurel32 2523ebdd119Saurel32 float64 float64_cos(float64 rFm) 2533ebdd119Saurel32 { 2543ebdd119Saurel32 return rFm; 2553ebdd119Saurel32 //series 2563ebdd119Saurel32 } 2573ebdd119Saurel32 2583ebdd119Saurel32 #if 0 2593ebdd119Saurel32 float64 float64_arcsin(float64 rFm) 2603ebdd119Saurel32 { 2613ebdd119Saurel32 //series 2623ebdd119Saurel32 } 2633ebdd119Saurel32 2643ebdd119Saurel32 float64 float64_arctan(float64 rFm) 2653ebdd119Saurel32 { 2663ebdd119Saurel32 //series 2673ebdd119Saurel32 } 2683ebdd119Saurel32 #endif 2693ebdd119Saurel32 2703ebdd119Saurel32 float64 float64_log(float64 rFm) 2713ebdd119Saurel32 { 2723ebdd119Saurel32 return float64_div(float64_ln(rFm),getDoubleConstant(7)); 2733ebdd119Saurel32 } 2743ebdd119Saurel32 2753ebdd119Saurel32 float64 float64_tan(float64 rFm) 2763ebdd119Saurel32 { 2773ebdd119Saurel32 return float64_div(float64_sin(rFm),float64_cos(rFm)); 2783ebdd119Saurel32 } 2793ebdd119Saurel32 2803ebdd119Saurel32 float64 float64_arccos(float64 rFm) 2813ebdd119Saurel32 { 2823ebdd119Saurel32 return rFm; 2833ebdd119Saurel32 //return float64_sub(halfPi,float64_arcsin(rFm)); 2843ebdd119Saurel32 } 2853ebdd119Saurel32 2863ebdd119Saurel32 float64 float64_pow(float64 rFn,float64 rFm) 2873ebdd119Saurel32 { 2883ebdd119Saurel32 return float64_exp(float64_mul(rFm,float64_ln(rFn))); 2893ebdd119Saurel32 } 2903ebdd119Saurel32 2913ebdd119Saurel32 float64 float64_pol(float64 rFn,float64 rFm) 2923ebdd119Saurel32 { 2933ebdd119Saurel32 return float64_arctan(float64_div(rFn,rFm)); 2943ebdd119Saurel32 } 2953ebdd119Saurel32 #endif 296