1*3ebdd119Saurel32 /* 2*3ebdd119Saurel32 NetWinder Floating Point Emulator 3*3ebdd119Saurel32 (c) Rebel.COM, 1998,1999 4*3ebdd119Saurel32 5*3ebdd119Saurel32 Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 6*3ebdd119Saurel32 7*3ebdd119Saurel32 This program is free software; you can redistribute it and/or modify 8*3ebdd119Saurel32 it under the terms of the GNU General Public License as published by 9*3ebdd119Saurel32 the Free Software Foundation; either version 2 of the License, or 10*3ebdd119Saurel32 (at your option) any later version. 11*3ebdd119Saurel32 12*3ebdd119Saurel32 This program is distributed in the hope that it will be useful, 13*3ebdd119Saurel32 but WITHOUT ANY WARRANTY; without even the implied warranty of 14*3ebdd119Saurel32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*3ebdd119Saurel32 GNU General Public License for more details. 16*3ebdd119Saurel32 17*3ebdd119Saurel32 You should have received a copy of the GNU General Public License 18*3ebdd119Saurel32 along with this program; if not, write to the Free Software 19*3ebdd119Saurel32 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*3ebdd119Saurel32 */ 21*3ebdd119Saurel32 22*3ebdd119Saurel32 #include "fpa11.h" 23*3ebdd119Saurel32 #include "softfloat.h" 24*3ebdd119Saurel32 #include "fpopcode.h" 25*3ebdd119Saurel32 26*3ebdd119Saurel32 float64 float64_exp(float64 Fm); 27*3ebdd119Saurel32 float64 float64_ln(float64 Fm); 28*3ebdd119Saurel32 float64 float64_sin(float64 rFm); 29*3ebdd119Saurel32 float64 float64_cos(float64 rFm); 30*3ebdd119Saurel32 float64 float64_arcsin(float64 rFm); 31*3ebdd119Saurel32 float64 float64_arctan(float64 rFm); 32*3ebdd119Saurel32 float64 float64_log(float64 rFm); 33*3ebdd119Saurel32 float64 float64_tan(float64 rFm); 34*3ebdd119Saurel32 float64 float64_arccos(float64 rFm); 35*3ebdd119Saurel32 float64 float64_pow(float64 rFn,float64 rFm); 36*3ebdd119Saurel32 float64 float64_pol(float64 rFn,float64 rFm); 37*3ebdd119Saurel32 38*3ebdd119Saurel32 unsigned int DoubleCPDO(const unsigned int opcode) 39*3ebdd119Saurel32 { 40*3ebdd119Saurel32 FPA11 *fpa11 = GET_FPA11(); 41*3ebdd119Saurel32 float64 rFm, rFn = float64_zero; 42*3ebdd119Saurel32 unsigned int Fd, Fm, Fn, nRc = 1; 43*3ebdd119Saurel32 44*3ebdd119Saurel32 //printk("DoubleCPDO(0x%08x)\n",opcode); 45*3ebdd119Saurel32 46*3ebdd119Saurel32 Fm = getFm(opcode); 47*3ebdd119Saurel32 if (CONSTANT_FM(opcode)) 48*3ebdd119Saurel32 { 49*3ebdd119Saurel32 rFm = getDoubleConstant(Fm); 50*3ebdd119Saurel32 } 51*3ebdd119Saurel32 else 52*3ebdd119Saurel32 { 53*3ebdd119Saurel32 switch (fpa11->fType[Fm]) 54*3ebdd119Saurel32 { 55*3ebdd119Saurel32 case typeSingle: 56*3ebdd119Saurel32 rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); 57*3ebdd119Saurel32 break; 58*3ebdd119Saurel32 59*3ebdd119Saurel32 case typeDouble: 60*3ebdd119Saurel32 rFm = fpa11->fpreg[Fm].fDouble; 61*3ebdd119Saurel32 break; 62*3ebdd119Saurel32 63*3ebdd119Saurel32 case typeExtended: 64*3ebdd119Saurel32 // !! patb 65*3ebdd119Saurel32 //printk("not implemented! why not?\n"); 66*3ebdd119Saurel32 //!! ScottB 67*3ebdd119Saurel32 // should never get here, if extended involved 68*3ebdd119Saurel32 // then other operand should be promoted then 69*3ebdd119Saurel32 // ExtendedCPDO called. 70*3ebdd119Saurel32 break; 71*3ebdd119Saurel32 72*3ebdd119Saurel32 default: return 0; 73*3ebdd119Saurel32 } 74*3ebdd119Saurel32 } 75*3ebdd119Saurel32 76*3ebdd119Saurel32 if (!MONADIC_INSTRUCTION(opcode)) 77*3ebdd119Saurel32 { 78*3ebdd119Saurel32 Fn = getFn(opcode); 79*3ebdd119Saurel32 switch (fpa11->fType[Fn]) 80*3ebdd119Saurel32 { 81*3ebdd119Saurel32 case typeSingle: 82*3ebdd119Saurel32 rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); 83*3ebdd119Saurel32 break; 84*3ebdd119Saurel32 85*3ebdd119Saurel32 case typeDouble: 86*3ebdd119Saurel32 rFn = fpa11->fpreg[Fn].fDouble; 87*3ebdd119Saurel32 break; 88*3ebdd119Saurel32 89*3ebdd119Saurel32 default: return 0; 90*3ebdd119Saurel32 } 91*3ebdd119Saurel32 } 92*3ebdd119Saurel32 93*3ebdd119Saurel32 Fd = getFd(opcode); 94*3ebdd119Saurel32 /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */ 95*3ebdd119Saurel32 switch (opcode & MASK_ARITHMETIC_OPCODE) 96*3ebdd119Saurel32 { 97*3ebdd119Saurel32 /* dyadic opcodes */ 98*3ebdd119Saurel32 case ADF_CODE: 99*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status); 100*3ebdd119Saurel32 break; 101*3ebdd119Saurel32 102*3ebdd119Saurel32 case MUF_CODE: 103*3ebdd119Saurel32 case FML_CODE: 104*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status); 105*3ebdd119Saurel32 break; 106*3ebdd119Saurel32 107*3ebdd119Saurel32 case SUF_CODE: 108*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status); 109*3ebdd119Saurel32 break; 110*3ebdd119Saurel32 111*3ebdd119Saurel32 case RSF_CODE: 112*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status); 113*3ebdd119Saurel32 break; 114*3ebdd119Saurel32 115*3ebdd119Saurel32 case DVF_CODE: 116*3ebdd119Saurel32 case FDV_CODE: 117*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status); 118*3ebdd119Saurel32 break; 119*3ebdd119Saurel32 120*3ebdd119Saurel32 case RDF_CODE: 121*3ebdd119Saurel32 case FRD_CODE: 122*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status); 123*3ebdd119Saurel32 break; 124*3ebdd119Saurel32 125*3ebdd119Saurel32 #if 0 126*3ebdd119Saurel32 case POW_CODE: 127*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm); 128*3ebdd119Saurel32 break; 129*3ebdd119Saurel32 130*3ebdd119Saurel32 case RPW_CODE: 131*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn); 132*3ebdd119Saurel32 break; 133*3ebdd119Saurel32 #endif 134*3ebdd119Saurel32 135*3ebdd119Saurel32 case RMF_CODE: 136*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status); 137*3ebdd119Saurel32 break; 138*3ebdd119Saurel32 139*3ebdd119Saurel32 #if 0 140*3ebdd119Saurel32 case POL_CODE: 141*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm); 142*3ebdd119Saurel32 break; 143*3ebdd119Saurel32 #endif 144*3ebdd119Saurel32 145*3ebdd119Saurel32 /* monadic opcodes */ 146*3ebdd119Saurel32 case MVF_CODE: 147*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = rFm; 148*3ebdd119Saurel32 break; 149*3ebdd119Saurel32 150*3ebdd119Saurel32 case MNF_CODE: 151*3ebdd119Saurel32 { 152*3ebdd119Saurel32 unsigned int *p = (unsigned int*)&rFm; 153*3ebdd119Saurel32 #ifdef WORDS_BIGENDIAN 154*3ebdd119Saurel32 p[0] ^= 0x80000000; 155*3ebdd119Saurel32 #else 156*3ebdd119Saurel32 p[1] ^= 0x80000000; 157*3ebdd119Saurel32 #endif 158*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = rFm; 159*3ebdd119Saurel32 } 160*3ebdd119Saurel32 break; 161*3ebdd119Saurel32 162*3ebdd119Saurel32 case ABS_CODE: 163*3ebdd119Saurel32 { 164*3ebdd119Saurel32 unsigned int *p = (unsigned int*)&rFm; 165*3ebdd119Saurel32 #ifdef WORDS_BIGENDIAN 166*3ebdd119Saurel32 p[0] &= 0x7fffffff; 167*3ebdd119Saurel32 #else 168*3ebdd119Saurel32 p[1] &= 0x7fffffff; 169*3ebdd119Saurel32 #endif 170*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = rFm; 171*3ebdd119Saurel32 } 172*3ebdd119Saurel32 break; 173*3ebdd119Saurel32 174*3ebdd119Saurel32 case RND_CODE: 175*3ebdd119Saurel32 case URD_CODE: 176*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status); 177*3ebdd119Saurel32 break; 178*3ebdd119Saurel32 179*3ebdd119Saurel32 case SQT_CODE: 180*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status); 181*3ebdd119Saurel32 break; 182*3ebdd119Saurel32 183*3ebdd119Saurel32 #if 0 184*3ebdd119Saurel32 case LOG_CODE: 185*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_log(rFm); 186*3ebdd119Saurel32 break; 187*3ebdd119Saurel32 188*3ebdd119Saurel32 case LGN_CODE: 189*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_ln(rFm); 190*3ebdd119Saurel32 break; 191*3ebdd119Saurel32 192*3ebdd119Saurel32 case EXP_CODE: 193*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_exp(rFm); 194*3ebdd119Saurel32 break; 195*3ebdd119Saurel32 196*3ebdd119Saurel32 case SIN_CODE: 197*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_sin(rFm); 198*3ebdd119Saurel32 break; 199*3ebdd119Saurel32 200*3ebdd119Saurel32 case COS_CODE: 201*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_cos(rFm); 202*3ebdd119Saurel32 break; 203*3ebdd119Saurel32 204*3ebdd119Saurel32 case TAN_CODE: 205*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_tan(rFm); 206*3ebdd119Saurel32 break; 207*3ebdd119Saurel32 208*3ebdd119Saurel32 case ASN_CODE: 209*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm); 210*3ebdd119Saurel32 break; 211*3ebdd119Saurel32 212*3ebdd119Saurel32 case ACS_CODE: 213*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_arccos(rFm); 214*3ebdd119Saurel32 break; 215*3ebdd119Saurel32 216*3ebdd119Saurel32 case ATN_CODE: 217*3ebdd119Saurel32 fpa11->fpreg[Fd].fDouble = float64_arctan(rFm); 218*3ebdd119Saurel32 break; 219*3ebdd119Saurel32 #endif 220*3ebdd119Saurel32 221*3ebdd119Saurel32 case NRM_CODE: 222*3ebdd119Saurel32 break; 223*3ebdd119Saurel32 224*3ebdd119Saurel32 default: 225*3ebdd119Saurel32 { 226*3ebdd119Saurel32 nRc = 0; 227*3ebdd119Saurel32 } 228*3ebdd119Saurel32 } 229*3ebdd119Saurel32 230*3ebdd119Saurel32 if (0 != nRc) fpa11->fType[Fd] = typeDouble; 231*3ebdd119Saurel32 return nRc; 232*3ebdd119Saurel32 } 233*3ebdd119Saurel32 234*3ebdd119Saurel32 #if 0 235*3ebdd119Saurel32 float64 float64_exp(float64 rFm) 236*3ebdd119Saurel32 { 237*3ebdd119Saurel32 return rFm; 238*3ebdd119Saurel32 //series 239*3ebdd119Saurel32 } 240*3ebdd119Saurel32 241*3ebdd119Saurel32 float64 float64_ln(float64 rFm) 242*3ebdd119Saurel32 { 243*3ebdd119Saurel32 return rFm; 244*3ebdd119Saurel32 //series 245*3ebdd119Saurel32 } 246*3ebdd119Saurel32 247*3ebdd119Saurel32 float64 float64_sin(float64 rFm) 248*3ebdd119Saurel32 { 249*3ebdd119Saurel32 return rFm; 250*3ebdd119Saurel32 //series 251*3ebdd119Saurel32 } 252*3ebdd119Saurel32 253*3ebdd119Saurel32 float64 float64_cos(float64 rFm) 254*3ebdd119Saurel32 { 255*3ebdd119Saurel32 return rFm; 256*3ebdd119Saurel32 //series 257*3ebdd119Saurel32 } 258*3ebdd119Saurel32 259*3ebdd119Saurel32 #if 0 260*3ebdd119Saurel32 float64 float64_arcsin(float64 rFm) 261*3ebdd119Saurel32 { 262*3ebdd119Saurel32 //series 263*3ebdd119Saurel32 } 264*3ebdd119Saurel32 265*3ebdd119Saurel32 float64 float64_arctan(float64 rFm) 266*3ebdd119Saurel32 { 267*3ebdd119Saurel32 //series 268*3ebdd119Saurel32 } 269*3ebdd119Saurel32 #endif 270*3ebdd119Saurel32 271*3ebdd119Saurel32 float64 float64_log(float64 rFm) 272*3ebdd119Saurel32 { 273*3ebdd119Saurel32 return float64_div(float64_ln(rFm),getDoubleConstant(7)); 274*3ebdd119Saurel32 } 275*3ebdd119Saurel32 276*3ebdd119Saurel32 float64 float64_tan(float64 rFm) 277*3ebdd119Saurel32 { 278*3ebdd119Saurel32 return float64_div(float64_sin(rFm),float64_cos(rFm)); 279*3ebdd119Saurel32 } 280*3ebdd119Saurel32 281*3ebdd119Saurel32 float64 float64_arccos(float64 rFm) 282*3ebdd119Saurel32 { 283*3ebdd119Saurel32 return rFm; 284*3ebdd119Saurel32 //return float64_sub(halfPi,float64_arcsin(rFm)); 285*3ebdd119Saurel32 } 286*3ebdd119Saurel32 287*3ebdd119Saurel32 float64 float64_pow(float64 rFn,float64 rFm) 288*3ebdd119Saurel32 { 289*3ebdd119Saurel32 return float64_exp(float64_mul(rFm,float64_ln(rFn))); 290*3ebdd119Saurel32 } 291*3ebdd119Saurel32 292*3ebdd119Saurel32 float64 float64_pol(float64 rFn,float64 rFm) 293*3ebdd119Saurel32 { 294*3ebdd119Saurel32 return float64_arctan(float64_div(rFn,rFm)); 295*3ebdd119Saurel32 } 296*3ebdd119Saurel32 #endif 297