Statistics
| Branch: | Revision:

root / target-arm / nwfpe / fpa11.c @ d3c61721

History | View | Annotate | Download (5.5 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
24 00406dff bellard
#include "fpopcode.h"
25 00406dff bellard
26 00406dff bellard
//#include "fpmodule.h"
27 00406dff bellard
//#include "fpmodule.inl"
28 00406dff bellard
29 00406dff bellard
//#include <asm/system.h>
30 00406dff bellard
31 00406dff bellard
#include <stdio.h>
32 00406dff bellard
33 00406dff bellard
/* forward declarations */
34 00406dff bellard
unsigned int EmulateCPDO(const unsigned int);
35 00406dff bellard
unsigned int EmulateCPDT(const unsigned int);
36 00406dff bellard
unsigned int EmulateCPRT(const unsigned int);
37 00406dff bellard
38 00406dff bellard
FPA11* qemufpa=0;
39 00406dff bellard
unsigned int* user_registers=0;
40 00406dff bellard
41 00406dff bellard
/* Reset the FPA11 chip.  Called to initialize and reset the emulator. */
42 00406dff bellard
void resetFPA11(void)
43 00406dff bellard
{
44 00406dff bellard
  int i;
45 00406dff bellard
  FPA11 *fpa11 = GET_FPA11();
46 00406dff bellard
  
47 00406dff bellard
  /* initialize the register type array */
48 00406dff bellard
  for (i=0;i<=7;i++)
49 00406dff bellard
  {
50 00406dff bellard
    fpa11->fType[i] = typeNone;
51 00406dff bellard
  }
52 00406dff bellard
  
53 00406dff bellard
  /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
54 00406dff bellard
  fpa11->fpsr = FP_EMULATOR | BIT_AC;
55 00406dff bellard
  
56 00406dff bellard
  /* FPCR: set SB, AB and DA bits, clear all others */
57 00406dff bellard
#if MAINTAIN_FPCR
58 00406dff bellard
  fpa11->fpcr = MASK_RESET;
59 00406dff bellard
#endif
60 00406dff bellard
}
61 00406dff bellard
62 00406dff bellard
void SetRoundingMode(const unsigned int opcode)
63 00406dff bellard
{
64 00406dff bellard
#if MAINTAIN_FPCR
65 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
66 00406dff bellard
   fpa11->fpcr &= ~MASK_ROUNDING_MODE;
67 00406dff bellard
#endif   
68 00406dff bellard
   switch (opcode & MASK_ROUNDING_MODE)
69 00406dff bellard
   {
70 00406dff bellard
      default:
71 00406dff bellard
      case ROUND_TO_NEAREST:
72 00406dff bellard
         float_rounding_mode = float_round_nearest_even;
73 00406dff bellard
#if MAINTAIN_FPCR         
74 00406dff bellard
         fpa11->fpcr |= ROUND_TO_NEAREST;
75 00406dff bellard
#endif         
76 00406dff bellard
      break;
77 00406dff bellard
      
78 00406dff bellard
      case ROUND_TO_PLUS_INFINITY:
79 00406dff bellard
         float_rounding_mode = float_round_up;
80 00406dff bellard
#if MAINTAIN_FPCR         
81 00406dff bellard
         fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
82 00406dff bellard
#endif         
83 00406dff bellard
      break;
84 00406dff bellard
      
85 00406dff bellard
      case ROUND_TO_MINUS_INFINITY:
86 00406dff bellard
         float_rounding_mode = float_round_down;
87 00406dff bellard
#if MAINTAIN_FPCR         
88 00406dff bellard
         fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
89 00406dff bellard
#endif         
90 00406dff bellard
      break;
91 00406dff bellard
      
92 00406dff bellard
      case ROUND_TO_ZERO:
93 00406dff bellard
         float_rounding_mode = float_round_to_zero;
94 00406dff bellard
#if MAINTAIN_FPCR         
95 00406dff bellard
         fpa11->fpcr |= ROUND_TO_ZERO;
96 00406dff bellard
#endif         
97 00406dff bellard
      break;
98 00406dff bellard
  }
99 00406dff bellard
}
100 00406dff bellard
101 00406dff bellard
void SetRoundingPrecision(const unsigned int opcode)
102 00406dff bellard
{
103 00406dff bellard
#if MAINTAIN_FPCR
104 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
105 00406dff bellard
   fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
106 00406dff bellard
#endif   
107 00406dff bellard
   switch (opcode & MASK_ROUNDING_PRECISION)
108 00406dff bellard
   {
109 00406dff bellard
      case ROUND_SINGLE:
110 00406dff bellard
         floatx80_rounding_precision = 32;
111 00406dff bellard
#if MAINTAIN_FPCR         
112 00406dff bellard
         fpa11->fpcr |= ROUND_SINGLE;
113 00406dff bellard
#endif         
114 00406dff bellard
      break;
115 00406dff bellard
      
116 00406dff bellard
      case ROUND_DOUBLE:
117 00406dff bellard
         floatx80_rounding_precision = 64;
118 00406dff bellard
#if MAINTAIN_FPCR         
119 00406dff bellard
         fpa11->fpcr |= ROUND_DOUBLE;
120 00406dff bellard
#endif         
121 00406dff bellard
      break;
122 00406dff bellard
      
123 00406dff bellard
      case ROUND_EXTENDED:
124 00406dff bellard
         floatx80_rounding_precision = 80;
125 00406dff bellard
#if MAINTAIN_FPCR         
126 00406dff bellard
         fpa11->fpcr |= ROUND_EXTENDED;
127 00406dff bellard
#endif         
128 00406dff bellard
      break;
129 00406dff bellard
      
130 00406dff bellard
      default: floatx80_rounding_precision = 80;
131 00406dff bellard
  }
132 00406dff bellard
}
133 00406dff bellard
134 00406dff bellard
/* Emulate the instruction in the opcode. */
135 00406dff bellard
unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, unsigned int* qregs)
136 00406dff bellard
{
137 00406dff bellard
  unsigned int nRc = 0;
138 00406dff bellard
//  unsigned long flags;
139 00406dff bellard
  FPA11 *fpa11; 
140 00406dff bellard
//  save_flags(flags); sti();
141 00406dff bellard
142 00406dff bellard
  qemufpa=qfpa;
143 00406dff bellard
  user_registers=qregs;
144 00406dff bellard
  
145 00406dff bellard
#if 0
146 00406dff bellard
  fprintf(stderr,"emulating FP insn 0x%08x, PC=0x%08x\n",
147 00406dff bellard
          opcode, qregs[REG_PC]);
148 00406dff bellard
#endif
149 00406dff bellard
  fpa11 = GET_FPA11();
150 00406dff bellard
151 00406dff bellard
  if (fpa11->initflag == 0)                /* good place for __builtin_expect */
152 00406dff bellard
  {
153 00406dff bellard
    resetFPA11();
154 00406dff bellard
    SetRoundingMode(ROUND_TO_NEAREST);
155 00406dff bellard
    SetRoundingPrecision(ROUND_EXTENDED);
156 00406dff bellard
    fpa11->initflag = 1;
157 00406dff bellard
  }
158 00406dff bellard
159 00406dff bellard
  if (TEST_OPCODE(opcode,MASK_CPRT))
160 00406dff bellard
  {
161 00406dff bellard
    //fprintf(stderr,"emulating CPRT\n");
162 00406dff bellard
    /* Emulate conversion opcodes. */
163 00406dff bellard
    /* Emulate register transfer opcodes. */
164 00406dff bellard
    /* Emulate comparison opcodes. */
165 00406dff bellard
    nRc = EmulateCPRT(opcode);
166 00406dff bellard
  }
167 00406dff bellard
  else if (TEST_OPCODE(opcode,MASK_CPDO))
168 00406dff bellard
  {
169 00406dff bellard
    //fprintf(stderr,"emulating CPDO\n");
170 00406dff bellard
    /* Emulate monadic arithmetic opcodes. */
171 00406dff bellard
    /* Emulate dyadic arithmetic opcodes. */
172 00406dff bellard
    nRc = EmulateCPDO(opcode);
173 00406dff bellard
  }
174 00406dff bellard
  else if (TEST_OPCODE(opcode,MASK_CPDT))
175 00406dff bellard
  {
176 00406dff bellard
    //fprintf(stderr,"emulating CPDT\n");
177 00406dff bellard
    /* Emulate load/store opcodes. */
178 00406dff bellard
    /* Emulate load/store multiple opcodes. */
179 00406dff bellard
    nRc = EmulateCPDT(opcode);
180 00406dff bellard
  }
181 00406dff bellard
  else
182 00406dff bellard
  {
183 00406dff bellard
    /* Invalid instruction detected.  Return FALSE. */
184 00406dff bellard
    nRc = 0;
185 00406dff bellard
  }
186 00406dff bellard
187 00406dff bellard
//  restore_flags(flags);
188 00406dff bellard
189 00406dff bellard
  //printf("returning %d\n",nRc);
190 00406dff bellard
  return(nRc);
191 00406dff bellard
}
192 00406dff bellard
193 00406dff bellard
#if 0
194 00406dff bellard
unsigned int EmulateAll1(unsigned int opcode)
195 00406dff bellard
{
196 00406dff bellard
  switch ((opcode >> 24) & 0xf)
197 00406dff bellard
  {
198 00406dff bellard
     case 0xc:
199 00406dff bellard
     case 0xd:
200 00406dff bellard
       if ((opcode >> 20) & 0x1)
201 00406dff bellard
       {
202 00406dff bellard
          switch ((opcode >> 8) & 0xf)
203 00406dff bellard
          {
204 00406dff bellard
             case 0x1: return PerformLDF(opcode); break;
205 00406dff bellard
             case 0x2: return PerformLFM(opcode); break;
206 00406dff bellard
             default: return 0;
207 00406dff bellard
          }
208 00406dff bellard
       }
209 00406dff bellard
       else
210 00406dff bellard
       {
211 00406dff bellard
          switch ((opcode >> 8) & 0xf)
212 00406dff bellard
          {
213 00406dff bellard
             case 0x1: return PerformSTF(opcode); break;
214 00406dff bellard
             case 0x2: return PerformSFM(opcode); break;
215 00406dff bellard
             default: return 0;
216 00406dff bellard
          }
217 00406dff bellard
      }
218 00406dff bellard
     break;
219 00406dff bellard
     
220 00406dff bellard
     case 0xe: 
221 00406dff bellard
       if (opcode & 0x10)
222 00406dff bellard
         return EmulateCPDO(opcode);
223 00406dff bellard
       else
224 00406dff bellard
         return EmulateCPRT(opcode);
225 00406dff bellard
     break;
226 00406dff bellard
  
227 00406dff bellard
     default: return 0;
228 00406dff bellard
  }
229 00406dff bellard
}
230 00406dff bellard
#endif