Annotation of qemu/linux-user/arm/nwfpe/fpa11_cpdo.c, revision 1.1.1.1

1.1       root        1: /*
                      2:     NetWinder Floating Point Emulator
                      3:     (c) Rebel.COM, 1998,1999
                      4: 
                      5:     Direct questions, comments to Scott Bambrough <[email protected]>
                      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 "fpopcode.h"
                     24: 
                     25: unsigned int SingleCPDO(const unsigned int opcode);
                     26: unsigned int DoubleCPDO(const unsigned int opcode);
                     27: unsigned int ExtendedCPDO(const unsigned int opcode);
                     28: 
                     29: unsigned int EmulateCPDO(const unsigned int opcode)
                     30: {
                     31:    FPA11 *fpa11 = GET_FPA11();
                     32:    unsigned int Fd, nType, nDest, nRc = 1;
                     33: 
                     34:    //printk("EmulateCPDO(0x%08x)\n",opcode);
                     35: 
                     36:    /* Get the destination size.  If not valid let Linux perform
                     37:       an invalid instruction trap. */
                     38:    nDest = getDestinationSize(opcode);
                     39:    if (typeNone == nDest) return 0;
                     40: 
                     41:    SetRoundingMode(opcode);
                     42: 
                     43:    /* Compare the size of the operands in Fn and Fm.
                     44:       Choose the largest size and perform operations in that size,
                     45:       in order to make use of all the precision of the operands.
                     46:       If Fm is a constant, we just grab a constant of a size
                     47:       matching the size of the operand in Fn. */
                     48:    if (MONADIC_INSTRUCTION(opcode))
                     49:      nType = nDest;
                     50:    else
                     51:      nType = fpa11->fType[getFn(opcode)];
                     52: 
                     53:    if (!CONSTANT_FM(opcode))
                     54:    {
                     55:      register unsigned int Fm = getFm(opcode);
                     56:      if (nType < fpa11->fType[Fm])
                     57:      {
                     58:         nType = fpa11->fType[Fm];
                     59:      }
                     60:    }
                     61: 
                     62:    switch (nType)
                     63:    {
                     64:       case typeSingle   : nRc = SingleCPDO(opcode);   break;
                     65:       case typeDouble   : nRc = DoubleCPDO(opcode);   break;
                     66:       case typeExtended : nRc = ExtendedCPDO(opcode); break;
                     67:       default           : nRc = 0;
                     68:    }
                     69: 
                     70:    /* If the operation succeeded, check to see if the result in the
                     71:       destination register is the correct size.  If not force it
                     72:       to be. */
                     73:    Fd = getFd(opcode);
                     74:    nType = fpa11->fType[Fd];
                     75:    if ((0 != nRc) && (nDest != nType))
                     76:    {
                     77:      switch (nDest)
                     78:      {
                     79:        case typeSingle:
                     80:        {
                     81:          if (typeDouble == nType)
                     82:            fpa11->fpreg[Fd].fSingle =
                     83:               float64_to_float32(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status);
                     84:          else
                     85:            fpa11->fpreg[Fd].fSingle =
                     86:               floatx80_to_float32(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
                     87:        }
                     88:        break;
                     89: 
                     90:        case typeDouble:
                     91:        {
                     92:          if (typeSingle == nType)
                     93:            fpa11->fpreg[Fd].fDouble =
                     94:               float32_to_float64(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status);
                     95:          else
                     96:            fpa11->fpreg[Fd].fDouble =
                     97:               floatx80_to_float64(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
                     98:        }
                     99:        break;
                    100: 
                    101:        case typeExtended:
                    102:        {
                    103:          if (typeSingle == nType)
                    104:            fpa11->fpreg[Fd].fExtended =
                    105:               float32_to_floatx80(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status);
                    106:          else
                    107:            fpa11->fpreg[Fd].fExtended =
                    108:               float64_to_floatx80(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status);
                    109:        }
                    110:        break;
                    111:      }
                    112: 
                    113:      fpa11->fType[Fd] = nDest;
                    114:    }
                    115: 
                    116:    return nRc;
                    117: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.