| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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; //FIXME - should be 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); | 
 | 80 |       break; | 
 | 81 |  | 
 | 82 |       case MUF_CODE: | 
 | 83 |       case FML_CODE: | 
 | 84 |         fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm); | 
 | 85 |       break; | 
 | 86 |  | 
 | 87 |       case SUF_CODE: | 
 | 88 |          fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm); | 
 | 89 |       break; | 
 | 90 |  | 
 | 91 |       case RSF_CODE: | 
 | 92 |          fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn); | 
 | 93 |       break; | 
 | 94 |  | 
 | 95 |       case DVF_CODE: | 
 | 96 |       case FDV_CODE: | 
 | 97 |          fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm); | 
 | 98 |       break; | 
 | 99 |  | 
 | 100 |       case RDF_CODE: | 
 | 101 |       case FRD_CODE: | 
 | 102 |          fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn); | 
 | 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); | 
 | 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); | 
 | 143 |       break; | 
 | 144 |  | 
 | 145 |       case SQT_CODE: | 
 | 146 |          fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm); | 
 | 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 |