double_cpdo.c (6569B)
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 26float64 float64_exp(float64 Fm); 27float64 float64_ln(float64 Fm); 28float64 float64_sin(float64 rFm); 29float64 float64_cos(float64 rFm); 30float64 float64_arcsin(float64 rFm); 31float64 float64_arctan(float64 rFm); 32float64 float64_log(float64 rFm); 33float64 float64_tan(float64 rFm); 34float64 float64_arccos(float64 rFm); 35float64 float64_pow(float64 rFn,float64 rFm); 36float64 float64_pol(float64 rFn,float64 rFm); 37 38unsigned int DoubleCPDO(const unsigned int opcode) 39{ 40 FPA11 *fpa11 = GET_FPA11(); 41 float64 rFm, rFn = float64_zero; 42 unsigned int Fd, Fm, Fn, nRc = 1; 43 44 //printk("DoubleCPDO(0x%08x)\n",opcode); 45 46 Fm = getFm(opcode); 47 if (CONSTANT_FM(opcode)) 48 { 49 rFm = getDoubleConstant(Fm); 50 } 51 else 52 { 53 switch (fpa11->fType[Fm]) 54 { 55 case typeSingle: 56 rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); 57 break; 58 59 case typeDouble: 60 rFm = fpa11->fpreg[Fm].fDouble; 61 break; 62 63 case typeExtended: 64 // !! patb 65 //printk("not implemented! why not?\n"); 66 //!! ScottB 67 // should never get here, if extended involved 68 // then other operand should be promoted then 69 // ExtendedCPDO called. 70 break; 71 72 default: return 0; 73 } 74 } 75 76 if (!MONADIC_INSTRUCTION(opcode)) 77 { 78 Fn = getFn(opcode); 79 switch (fpa11->fType[Fn]) 80 { 81 case typeSingle: 82 rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); 83 break; 84 85 case typeDouble: 86 rFn = fpa11->fpreg[Fn].fDouble; 87 break; 88 89 default: return 0; 90 } 91 } 92 93 Fd = getFd(opcode); 94 /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */ 95 switch (opcode & MASK_ARITHMETIC_OPCODE) 96 { 97 /* dyadic opcodes */ 98 case ADF_CODE: 99 fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status); 100 break; 101 102 case MUF_CODE: 103 case FML_CODE: 104 fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status); 105 break; 106 107 case SUF_CODE: 108 fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status); 109 break; 110 111 case RSF_CODE: 112 fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status); 113 break; 114 115 case DVF_CODE: 116 case FDV_CODE: 117 fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status); 118 break; 119 120 case RDF_CODE: 121 case FRD_CODE: 122 fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status); 123 break; 124 125#if 0 126 case POW_CODE: 127 fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm); 128 break; 129 130 case RPW_CODE: 131 fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn); 132 break; 133#endif 134 135 case RMF_CODE: 136 fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status); 137 break; 138 139#if 0 140 case POL_CODE: 141 fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm); 142 break; 143#endif 144 145 /* monadic opcodes */ 146 case MVF_CODE: 147 fpa11->fpreg[Fd].fDouble = rFm; 148 break; 149 150 case MNF_CODE: 151 { 152 unsigned int *p = (unsigned int*)&rFm; 153#ifdef HOST_WORDS_BIGENDIAN 154 p[0] ^= 0x80000000; 155#else 156 p[1] ^= 0x80000000; 157#endif 158 fpa11->fpreg[Fd].fDouble = rFm; 159 } 160 break; 161 162 case ABS_CODE: 163 { 164 unsigned int *p = (unsigned int*)&rFm; 165#ifdef HOST_WORDS_BIGENDIAN 166 p[0] &= 0x7fffffff; 167#else 168 p[1] &= 0x7fffffff; 169#endif 170 fpa11->fpreg[Fd].fDouble = rFm; 171 } 172 break; 173 174 case RND_CODE: 175 case URD_CODE: 176 fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status); 177 break; 178 179 case SQT_CODE: 180 fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status); 181 break; 182 183#if 0 184 case LOG_CODE: 185 fpa11->fpreg[Fd].fDouble = float64_log(rFm); 186 break; 187 188 case LGN_CODE: 189 fpa11->fpreg[Fd].fDouble = float64_ln(rFm); 190 break; 191 192 case EXP_CODE: 193 fpa11->fpreg[Fd].fDouble = float64_exp(rFm); 194 break; 195 196 case SIN_CODE: 197 fpa11->fpreg[Fd].fDouble = float64_sin(rFm); 198 break; 199 200 case COS_CODE: 201 fpa11->fpreg[Fd].fDouble = float64_cos(rFm); 202 break; 203 204 case TAN_CODE: 205 fpa11->fpreg[Fd].fDouble = float64_tan(rFm); 206 break; 207 208 case ASN_CODE: 209 fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm); 210 break; 211 212 case ACS_CODE: 213 fpa11->fpreg[Fd].fDouble = float64_arccos(rFm); 214 break; 215 216 case ATN_CODE: 217 fpa11->fpreg[Fd].fDouble = float64_arctan(rFm); 218 break; 219#endif 220 221 case NRM_CODE: 222 break; 223 224 default: 225 { 226 nRc = 0; 227 } 228 } 229 230 if (0 != nRc) fpa11->fType[Fd] = typeDouble; 231 return nRc; 232} 233 234#if 0 235float64 float64_exp(float64 rFm) 236{ 237 return rFm; 238//series 239} 240 241float64 float64_ln(float64 rFm) 242{ 243 return rFm; 244//series 245} 246 247float64 float64_sin(float64 rFm) 248{ 249 return rFm; 250//series 251} 252 253float64 float64_cos(float64 rFm) 254{ 255 return rFm; 256 //series 257} 258 259#if 0 260float64 float64_arcsin(float64 rFm) 261{ 262//series 263} 264 265float64 float64_arctan(float64 rFm) 266{ 267 //series 268} 269#endif 270 271float64 float64_log(float64 rFm) 272{ 273 return float64_div(float64_ln(rFm),getDoubleConstant(7)); 274} 275 276float64 float64_tan(float64 rFm) 277{ 278 return float64_div(float64_sin(rFm),float64_cos(rFm)); 279} 280 281float64 float64_arccos(float64 rFm) 282{ 283return rFm; 284 //return float64_sub(halfPi,float64_arcsin(rFm)); 285} 286 287float64 float64_pow(float64 rFn,float64 rFm) 288{ 289 return float64_exp(float64_mul(rFm,float64_ln(rFn))); 290} 291 292float64 float64_pol(float64 rFn,float64 rFm) 293{ 294 return float64_arctan(float64_div(rFn,rFm)); 295} 296#endif