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