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