qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

double_cpdo.c (6553B)


      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 
     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 #if HOST_BIG_ENDIAN
    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 #if HOST_BIG_ENDIAN
    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