Statistics
| Branch: | Revision:

root / target-arm / nwfpe / fpa11_cpdo.c @ 5fafdf24

History | View | Annotate | Download (3.6 kB)

1 00406dff bellard
/*
2 00406dff bellard
    NetWinder Floating Point Emulator
3 00406dff bellard
    (c) Rebel.COM, 1998,1999
4 00406dff bellard

5 00406dff bellard
    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6 00406dff bellard

7 00406dff bellard
    This program is free software; you can redistribute it and/or modify
8 00406dff bellard
    it under the terms of the GNU General Public License as published by
9 00406dff bellard
    the Free Software Foundation; either version 2 of the License, or
10 00406dff bellard
    (at your option) any later version.
11 00406dff bellard

12 00406dff bellard
    This program is distributed in the hope that it will be useful,
13 00406dff bellard
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 00406dff bellard
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 00406dff bellard
    GNU General Public License for more details.
16 00406dff bellard

17 00406dff bellard
    You should have received a copy of the GNU General Public License
18 00406dff bellard
    along with this program; if not, write to the Free Software
19 00406dff bellard
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 00406dff bellard
*/
21 00406dff bellard
22 00406dff bellard
#include "fpa11.h"
23 00406dff bellard
#include "fpopcode.h"
24 00406dff bellard
25 00406dff bellard
unsigned int SingleCPDO(const unsigned int opcode);
26 00406dff bellard
unsigned int DoubleCPDO(const unsigned int opcode);
27 00406dff bellard
unsigned int ExtendedCPDO(const unsigned int opcode);
28 00406dff bellard
29 00406dff bellard
unsigned int EmulateCPDO(const unsigned int opcode)
30 00406dff bellard
{
31 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
32 00406dff bellard
   unsigned int Fd, nType, nDest, nRc = 1;
33 5fafdf24 ths
  
34 00406dff bellard
   //printk("EmulateCPDO(0x%08x)\n",opcode);
35 00406dff bellard
36 00406dff bellard
   /* Get the destination size.  If not valid let Linux perform
37 00406dff bellard
      an invalid instruction trap. */
38 00406dff bellard
   nDest = getDestinationSize(opcode);
39 00406dff bellard
   if (typeNone == nDest) return 0;
40 5fafdf24 ths
  
41 00406dff bellard
   SetRoundingMode(opcode);
42 5fafdf24 ths
    
43 00406dff bellard
   /* Compare the size of the operands in Fn and Fm.
44 00406dff bellard
      Choose the largest size and perform operations in that size,
45 5fafdf24 ths
      in order to make use of all the precision of the operands.
46 5fafdf24 ths
      If Fm is a constant, we just grab a constant of a size
47 00406dff bellard
      matching the size of the operand in Fn. */
48 00406dff bellard
   if (MONADIC_INSTRUCTION(opcode))
49 00406dff bellard
     nType = nDest;
50 00406dff bellard
   else
51 00406dff bellard
     nType = fpa11->fType[getFn(opcode)];
52 5fafdf24 ths
  
53 00406dff bellard
   if (!CONSTANT_FM(opcode))
54 00406dff bellard
   {
55 00406dff bellard
     register unsigned int Fm = getFm(opcode);
56 00406dff bellard
     if (nType < fpa11->fType[Fm])
57 00406dff bellard
     {
58 00406dff bellard
        nType = fpa11->fType[Fm];
59 00406dff bellard
     }
60 00406dff bellard
   }
61 00406dff bellard
62 00406dff bellard
   switch (nType)
63 00406dff bellard
   {
64 00406dff bellard
      case typeSingle   : nRc = SingleCPDO(opcode);   break;
65 00406dff bellard
      case typeDouble   : nRc = DoubleCPDO(opcode);   break;
66 00406dff bellard
      case typeExtended : nRc = ExtendedCPDO(opcode); break;
67 00406dff bellard
      default           : nRc = 0;
68 00406dff bellard
   }
69 00406dff bellard
70 00406dff bellard
   /* If the operation succeeded, check to see if the result in the
71 00406dff bellard
      destination register is the correct size.  If not force it
72 00406dff bellard
      to be. */
73 00406dff bellard
   Fd = getFd(opcode);
74 00406dff bellard
   nType = fpa11->fType[Fd];
75 00406dff bellard
   if ((0 != nRc) && (nDest != nType))
76 00406dff bellard
   {
77 00406dff bellard
     switch (nDest)
78 00406dff bellard
     {
79 00406dff bellard
       case typeSingle:
80 00406dff bellard
       {
81 00406dff bellard
         if (typeDouble == nType)
82 5fafdf24 ths
           fpa11->fpreg[Fd].fSingle =
83 20495218 bellard
              float64_to_float32(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status);
84 00406dff bellard
         else
85 5fafdf24 ths
           fpa11->fpreg[Fd].fSingle =
86 20495218 bellard
              floatx80_to_float32(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
87 00406dff bellard
       }
88 00406dff bellard
       break;
89 5fafdf24 ths
         
90 00406dff bellard
       case typeDouble:
91 00406dff bellard
       {
92 00406dff bellard
         if (typeSingle == nType)
93 5fafdf24 ths
           fpa11->fpreg[Fd].fDouble =
94 20495218 bellard
              float32_to_float64(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status);
95 00406dff bellard
         else
96 5fafdf24 ths
           fpa11->fpreg[Fd].fDouble =
97 20495218 bellard
              floatx80_to_float64(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
98 00406dff bellard
       }
99 00406dff bellard
       break;
100 5fafdf24 ths
         
101 00406dff bellard
       case typeExtended:
102 00406dff bellard
       {
103 00406dff bellard
         if (typeSingle == nType)
104 5fafdf24 ths
           fpa11->fpreg[Fd].fExtended =
105 20495218 bellard
              float32_to_floatx80(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status);
106 00406dff bellard
         else
107 5fafdf24 ths
           fpa11->fpreg[Fd].fExtended =
108 20495218 bellard
              float64_to_floatx80(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status);
109 00406dff bellard
       }
110 00406dff bellard
       break;
111 00406dff bellard
     }
112 5fafdf24 ths
    
113 00406dff bellard
     fpa11->fType[Fd] = nDest;
114 00406dff bellard
   }
115 5fafdf24 ths
  
116 00406dff bellard
   return nRc;
117 00406dff bellard
}