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 "qemu/osdep.h" 22 #include "fpa11.h" 23 #include "fpu/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 = float32_zero; 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 fpa11->fpreg[Fd].fSingle = float32_chs(rFm); 132 break; 133 134 case ABS_CODE: 135 fpa11->fpreg[Fd].fSingle = float32_abs(rFm); 136 break; 137 138 case RND_CODE: 139 case URD_CODE: 140 fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm, &fpa11->fp_status); 141 break; 142 143 case SQT_CODE: 144 fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm, &fpa11->fp_status); 145 break; 146 147 #if 0 148 case LOG_CODE: 149 fpa11->fpreg[Fd].fSingle = float32_log(rFm); 150 break; 151 152 case LGN_CODE: 153 fpa11->fpreg[Fd].fSingle = float32_ln(rFm); 154 break; 155 156 case EXP_CODE: 157 fpa11->fpreg[Fd].fSingle = float32_exp(rFm); 158 break; 159 160 case SIN_CODE: 161 fpa11->fpreg[Fd].fSingle = float32_sin(rFm); 162 break; 163 164 case COS_CODE: 165 fpa11->fpreg[Fd].fSingle = float32_cos(rFm); 166 break; 167 168 case TAN_CODE: 169 fpa11->fpreg[Fd].fSingle = float32_tan(rFm); 170 break; 171 172 case ASN_CODE: 173 fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm); 174 break; 175 176 case ACS_CODE: 177 fpa11->fpreg[Fd].fSingle = float32_arccos(rFm); 178 break; 179 180 case ATN_CODE: 181 fpa11->fpreg[Fd].fSingle = float32_arctan(rFm); 182 break; 183 #endif 184 185 case NRM_CODE: 186 break; 187 188 default: 189 { 190 nRc = 0; 191 } 192 } 193 194 if (0 != nRc) fpa11->fType[Fd] = typeSingle; 195 return nRc; 196 } 197 198 #if 0 199 float32 float32_exp(float32 Fm) 200 { 201 //series 202 } 203 204 float32 float32_ln(float32 Fm) 205 { 206 //series 207 } 208 209 float32 float32_sin(float32 rFm) 210 { 211 //series 212 } 213 214 float32 float32_cos(float32 rFm) 215 { 216 //series 217 } 218 219 float32 float32_arcsin(float32 rFm) 220 { 221 //series 222 } 223 224 float32 float32_arctan(float32 rFm) 225 { 226 //series 227 } 228 229 float32 float32_arccos(float32 rFm) 230 { 231 //return float32_sub(halfPi,float32_arcsin(rFm)); 232 } 233 234 float32 float32_log(float32 rFm) 235 { 236 return float32_div(float32_ln(rFm),getSingleConstant(7)); 237 } 238 239 float32 float32_tan(float32 rFm) 240 { 241 return float32_div(float32_sin(rFm),float32_cos(rFm)); 242 } 243 244 float32 float32_pow(float32 rFn,float32 rFm) 245 { 246 return float32_exp(float32_mul(rFm,float32_ln(rFn))); 247 } 248 249 float32 float32_pol(float32 rFn,float32 rFm) 250 { 251 return float32_arctan(float32_div(rFn,rFm)); 252 } 253 #endif 254