symbian-qemu-0.9.1-12/qemu-symbian-svp/linux-user/arm/nwfpe/double_cpdo.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 float64 float64_exp(float64 Fm);
       
    27 float64 float64_ln(float64 Fm);
       
    28 float64 float64_sin(float64 rFm);
       
    29 float64 float64_cos(float64 rFm);
       
    30 float64 float64_arcsin(float64 rFm);
       
    31 float64 float64_arctan(float64 rFm);
       
    32 float64 float64_log(float64 rFm);
       
    33 float64 float64_tan(float64 rFm);
       
    34 float64 float64_arccos(float64 rFm);
       
    35 float64 float64_pow(float64 rFn,float64 rFm);
       
    36 float64 float64_pol(float64 rFn,float64 rFm);
       
    37 
       
    38 unsigned 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 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 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
       
   235 float64 float64_exp(float64 rFm)
       
   236 {
       
   237   return rFm;
       
   238 //series
       
   239 }
       
   240 
       
   241 float64 float64_ln(float64 rFm)
       
   242 {
       
   243   return rFm;
       
   244 //series
       
   245 }
       
   246 
       
   247 float64 float64_sin(float64 rFm)
       
   248 {
       
   249   return rFm;
       
   250 //series
       
   251 }
       
   252 
       
   253 float64 float64_cos(float64 rFm)
       
   254 {
       
   255    return rFm;
       
   256    //series
       
   257 }
       
   258 
       
   259 #if 0
       
   260 float64 float64_arcsin(float64 rFm)
       
   261 {
       
   262 //series
       
   263 }
       
   264 
       
   265 float64 float64_arctan(float64 rFm)
       
   266 {
       
   267   //series
       
   268 }
       
   269 #endif
       
   270 
       
   271 float64 float64_log(float64 rFm)
       
   272 {
       
   273   return float64_div(float64_ln(rFm),getDoubleConstant(7));
       
   274 }
       
   275 
       
   276 float64 float64_tan(float64 rFm)
       
   277 {
       
   278   return float64_div(float64_sin(rFm),float64_cos(rFm));
       
   279 }
       
   280 
       
   281 float64 float64_arccos(float64 rFm)
       
   282 {
       
   283 return rFm;
       
   284    //return float64_sub(halfPi,float64_arcsin(rFm));
       
   285 }
       
   286 
       
   287 float64 float64_pow(float64 rFn,float64 rFm)
       
   288 {
       
   289   return float64_exp(float64_mul(rFm,float64_ln(rFn)));
       
   290 }
       
   291 
       
   292 float64 float64_pol(float64 rFn,float64 rFm)
       
   293 {
       
   294   return float64_arctan(float64_div(rFn,rFm));
       
   295 }
       
   296 #endif