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, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 #include "fpa11.h" 23 #include "softfloat.h" 24 #include "fpopcode.h" 25 26 float32 float32_exp(float32 Fm); 27 float32 float32_ln(float32 Fm); 28 float32 float32_sin(float32 rFm); 29 float32 float32_cos(float32 rFm); 30 float32 float32_arcsin(float32 rFm); 31 float32 float32_arctan(float32 rFm); 32 float32 float32_log(float32 rFm); 33 float32 float32_tan(float32 rFm); 34 float32 float32_arccos(float32 rFm); 35 float32 float32_pow(float32 rFn,float32 rFm); 36 float32 float32_pol(float32 rFn,float32 rFm); 37 38 unsigned int SingleCPDO(const unsigned int opcode) 39 { 40 FPA11 *fpa11 = GET_FPA11(); 41 float32 rFm, rFn = 0; 42 unsigned int Fd, Fm, Fn, nRc = 1; 43 44 Fm = getFm(opcode); 45 if (CONSTANT_FM(opcode)) 46 { 47 rFm = getSingleConstant(Fm); 48 } 49 else 50 { 51 switch (fpa11->fType[Fm]) 52 { 53 case typeSingle: 54 rFm = fpa11->fpreg[Fm].fSingle; 55 break; 56 57 default: return 0; 58 } 59 } 60 61 if (!MONADIC_INSTRUCTION(opcode)) 62 { 63 Fn = getFn(opcode); 64 switch (fpa11->fType[Fn]) 65 { 66 case typeSingle: 67 rFn = fpa11->fpreg[Fn].fSingle; 68 break; 69 70 default: return 0; 71 } 72 } 73 74 Fd = getFd(opcode); 75 switch (opcode & MASK_ARITHMETIC_OPCODE) 76 { 77 /* dyadic opcodes */ 78 case ADF_CODE: 79 fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm, &fpa11->fp_status); 80 break; 81 82 case MUF_CODE: 83 case FML_CODE: 84 fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm, &fpa11->fp_status); 85 break; 86 87 case SUF_CODE: 88 fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm, &fpa11->fp_status); 89 break; 90 91 case RSF_CODE: 92 fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn, &fpa11->fp_status); 93 break; 94 95 case DVF_CODE: 96 case FDV_CODE: 97 fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm, &fpa11->fp_status); 98 break; 99 100 case RDF_CODE: 101 case FRD_CODE: 102 fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn, &fpa11->fp_status); 103 break; 104 105 #if 0 106 case POW_CODE: 107 fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm); 108 break; 109 110 case RPW_CODE: 111 fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn); 112 break; 113 #endif 114 115 case RMF_CODE: 116 fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm, &fpa11->fp_status); 117 break; 118 119 #if 0 120 case POL_CODE: 121 fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm); 122 break; 123 #endif 124 125 /* monadic opcodes */ 126 case MVF_CODE: 127 fpa11->fpreg[Fd].fSingle = rFm; 128 break; 129 130 case MNF_CODE: 131 rFm ^= 0x80000000; 132 fpa11->fpreg[Fd].fSingle = rFm; 133 break; 134 135 case ABS_CODE: 136 rFm &= 0x7fffffff; 137 fpa11->fpreg[Fd].fSingle = rFm; 138 break; 139 140 case RND_CODE: 141 case URD_CODE: 142 fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm, &fpa11->fp_status); 143 break; 144 145 case SQT_CODE: 146 fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm, &fpa11->fp_status); 147 break; 148 149 #if 0 150 case LOG_CODE: 151 fpa11->fpreg[Fd].fSingle = float32_log(rFm); 152 break; 153 154 case LGN_CODE: 155 fpa11->fpreg[Fd].fSingle = float32_ln(rFm); 156 break; 157 158 case EXP_CODE: 159 fpa11->fpreg[Fd].fSingle = float32_exp(rFm); 160 break; 161 162 case SIN_CODE: 163 fpa11->fpreg[Fd].fSingle = float32_sin(rFm); 164 break; 165 166 case COS_CODE: 167 fpa11->fpreg[Fd].fSingle = float32_cos(rFm); 168 break; 169 170 case TAN_CODE: 171 fpa11->fpreg[Fd].fSingle = float32_tan(rFm); 172 break; 173 174 case ASN_CODE: 175 fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm); 176 break; 177 178 case ACS_CODE: 179 fpa11->fpreg[Fd].fSingle = float32_arccos(rFm); 180 break; 181 182 case ATN_CODE: 183 fpa11->fpreg[Fd].fSingle = float32_arctan(rFm); 184 break; 185 #endif 186 187 case NRM_CODE: 188 break; 189 190 default: 191 { 192 nRc = 0; 193 } 194 } 195 196 if (0 != nRc) fpa11->fType[Fd] = typeSingle; 197 return nRc; 198 } 199 200 #if 0 201 float32 float32_exp(float32 Fm) 202 { 203 //series 204 } 205 206 float32 float32_ln(float32 Fm) 207 { 208 //series 209 } 210 211 float32 float32_sin(float32 rFm) 212 { 213 //series 214 } 215 216 float32 float32_cos(float32 rFm) 217 { 218 //series 219 } 220 221 float32 float32_arcsin(float32 rFm) 222 { 223 //series 224 } 225 226 float32 float32_arctan(float32 rFm) 227 { 228 //series 229 } 230 231 float32 float32_arccos(float32 rFm) 232 { 233 //return float32_sub(halfPi,float32_arcsin(rFm)); 234 } 235 236 float32 float32_log(float32 rFm) 237 { 238 return float32_div(float32_ln(rFm),getSingleConstant(7)); 239 } 240 241 float32 float32_tan(float32 rFm) 242 { 243 return float32_div(float32_sin(rFm),float32_cos(rFm)); 244 } 245 246 float32 float32_pow(float32 rFn,float32 rFm) 247 { 248 return float32_exp(float32_mul(rFm,float32_ln(rFn))); 249 } 250 251 float32 float32_pol(float32 rFn,float32 rFm) 252 { 253 return float32_arctan(float32_div(rFn,rFm)); 254 } 255 #endif 256