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 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 = 0; 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); 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); 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); 100 break; 101 102 case MUF_CODE: 103 case FML_CODE: 104 fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm); 105 break; 106 107 case SUF_CODE: 108 fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm); 109 break; 110 111 case RSF_CODE: 112 fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn); 113 break; 114 115 case DVF_CODE: 116 case FDV_CODE: 117 fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm); 118 break; 119 120 case RDF_CODE: 121 case FRD_CODE: 122 fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn); 123 break; 124 125 126 case RMF_CODE: 127 fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm); 128 break; 129 130 131 /* monadic opcodes */ 132 case MVF_CODE: 133 fpa11->fpreg[Fd].fDouble = rFm; 134 break; 135 136 case MNF_CODE: 137 { 138 unsigned int *p = (unsigned int*)&rFm; 139 p[1] ^= 0x80000000; 140 fpa11->fpreg[Fd].fDouble = rFm; 141 } 142 break; 143 144 case ABS_CODE: 145 { 146 unsigned int *p = (unsigned int*)&rFm; 147 p[1] &= 0x7fffffff; 148 fpa11->fpreg[Fd].fDouble = rFm; 149 } 150 break; 151 152 case RND_CODE: 153 case URD_CODE: 154 fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm); 155 break; 156 157 case SQT_CODE: 158 fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm); 159 break; 160 161 162 case NRM_CODE: 163 break; 164 165 default: 166 { 167 nRc = 0; 168 } 169 } 170 171 if (0 != nRc) fpa11->fType[Fd] = typeDouble; 172 return nRc; 173} 174