Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (9.1 kB)

1 00406dff bellard
/*
2 00406dff bellard
    NetWinder Floating Point Emulator
3 00406dff bellard
    (c) Rebel.com, 1998-1999
4 00406dff bellard
    (c) Philip Blundell, 1998
5 00406dff bellard

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

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

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

18 00406dff bellard
    You should have received a copy of the GNU General Public License
19 00406dff bellard
    along with this program; if not, write to the Free Software
20 00406dff bellard
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 00406dff bellard
*/
22 00406dff bellard
23 00406dff bellard
#include "fpa11.h"
24 00406dff bellard
#include "softfloat.h"
25 00406dff bellard
#include "fpopcode.h"
26 00406dff bellard
//#include "fpmodule.h"
27 00406dff bellard
//#include "fpmodule.inl"
28 00406dff bellard
29 00406dff bellard
//#include <asm/uaccess.h>
30 00406dff bellard
31 00406dff bellard
static inline
32 00406dff bellard
void loadSingle(const unsigned int Fn,const unsigned int *pMem)
33 00406dff bellard
{
34 53a5960a pbrook
   target_ulong addr = (target_ulong)(long)pMem;
35 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
36 00406dff bellard
   fpa11->fType[Fn] = typeSingle;
37 53a5960a pbrook
   fpa11->fpreg[Fn].fSingle = tget32(addr);
38 00406dff bellard
}
39 00406dff bellard
40 00406dff bellard
static inline
41 00406dff bellard
void loadDouble(const unsigned int Fn,const unsigned int *pMem)
42 00406dff bellard
{
43 53a5960a pbrook
   target_ulong addr = (target_ulong)(long)pMem;
44 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
45 00406dff bellard
   unsigned int *p;
46 00406dff bellard
   p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
47 00406dff bellard
   fpa11->fType[Fn] = typeDouble;
48 a8d3431a bellard
#ifdef WORDS_BIGENDIAN
49 53a5960a pbrook
   p[0] = tget32(addr); /* sign & exponent */
50 53a5960a pbrook
   p[1] = tget32(addr + 4);
51 a8d3431a bellard
#else
52 53a5960a pbrook
   p[0] = tget32(addr + 4);
53 53a5960a pbrook
   p[1] = tget32(addr); /* sign & exponent */
54 a8d3431a bellard
#endif
55 5fafdf24 ths
}  
56 00406dff bellard
57 00406dff bellard
static inline
58 00406dff bellard
void loadExtended(const unsigned int Fn,const unsigned int *pMem)
59 00406dff bellard
{
60 53a5960a pbrook
   target_ulong addr = (target_ulong)(long)pMem;
61 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
62 00406dff bellard
   unsigned int *p;
63 00406dff bellard
   p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
64 00406dff bellard
   fpa11->fType[Fn] = typeExtended;
65 53a5960a pbrook
   p[0] = tget32(addr);  /* sign & exponent */
66 53a5960a pbrook
   p[1] = tget32(addr + 8);  /* ls bits */
67 53a5960a pbrook
   p[2] = tget32(addr + 4);  /* ms bits */
68 5fafdf24 ths
}  
69 00406dff bellard
70 00406dff bellard
static inline
71 00406dff bellard
void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
72 00406dff bellard
{
73 53a5960a pbrook
   target_ulong addr = (target_ulong)(long)pMem;
74 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
75 00406dff bellard
   register unsigned int *p;
76 00406dff bellard
   unsigned long x;
77 00406dff bellard
78 00406dff bellard
   p = (unsigned int*)&(fpa11->fpreg[Fn]);
79 53a5960a pbrook
   x = tget32(addr);
80 00406dff bellard
   fpa11->fType[Fn] = (x >> 14) & 0x00000003;
81 5fafdf24 ths
  
82 00406dff bellard
   switch (fpa11->fType[Fn])
83 00406dff bellard
   {
84 00406dff bellard
      case typeSingle:
85 00406dff bellard
      case typeDouble:
86 00406dff bellard
      {
87 53a5960a pbrook
         p[0] = tget32(addr + 8);  /* Single */
88 53a5960a pbrook
         p[1] = tget32(addr + 4);  /* double msw */
89 00406dff bellard
         p[2] = 0;        /* empty */
90 00406dff bellard
      }
91 5fafdf24 ths
      break;
92 5fafdf24 ths
  
93 00406dff bellard
      case typeExtended:
94 00406dff bellard
      {
95 53a5960a pbrook
         p[1] = tget32(addr + 8);
96 53a5960a pbrook
         p[2] = tget32(addr + 4);  /* msw */
97 5fafdf24 ths
         p[0] = (x & 0x80003fff);     
98 00406dff bellard
      }
99 00406dff bellard
      break;
100 00406dff bellard
   }
101 00406dff bellard
}
102 00406dff bellard
103 00406dff bellard
static inline
104 00406dff bellard
void storeSingle(const unsigned int Fn,unsigned int *pMem)
105 00406dff bellard
{
106 53a5960a pbrook
   target_ulong addr = (target_ulong)(long)pMem;
107 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
108 00406dff bellard
   float32 val;
109 00406dff bellard
   register unsigned int *p = (unsigned int*)&val;
110 5fafdf24 ths
  
111 00406dff bellard
   switch (fpa11->fType[Fn])
112 00406dff bellard
   {
113 5fafdf24 ths
      case typeDouble:
114 20495218 bellard
         val = float64_to_float32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
115 00406dff bellard
      break;
116 00406dff bellard
117 5fafdf24 ths
      case typeExtended:
118 20495218 bellard
         val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
119 00406dff bellard
      break;
120 00406dff bellard
121 00406dff bellard
      default: val = fpa11->fpreg[Fn].fSingle;
122 00406dff bellard
   }
123 5fafdf24 ths
 
124 53a5960a pbrook
   tput32(addr, p[0]);
125 5fafdf24 ths
}  
126 00406dff bellard
127 00406dff bellard
static inline
128 00406dff bellard
void storeDouble(const unsigned int Fn,unsigned int *pMem)
129 00406dff bellard
{
130 53a5960a pbrook
   target_ulong addr = (target_ulong)(long)pMem;
131 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
132 00406dff bellard
   float64 val;
133 00406dff bellard
   register unsigned int *p = (unsigned int*)&val;
134 00406dff bellard
135 00406dff bellard
   switch (fpa11->fType[Fn])
136 00406dff bellard
   {
137 5fafdf24 ths
      case typeSingle:
138 20495218 bellard
         val = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
139 00406dff bellard
      break;
140 00406dff bellard
141 00406dff bellard
      case typeExtended:
142 20495218 bellard
         val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
143 00406dff bellard
      break;
144 00406dff bellard
145 00406dff bellard
      default: val = fpa11->fpreg[Fn].fDouble;
146 00406dff bellard
   }
147 a8d3431a bellard
#ifdef WORDS_BIGENDIAN
148 53a5960a pbrook
   tput32(addr, p[0]);        /* msw */
149 53a5960a pbrook
   tput32(addr + 4, p[1]);        /* lsw */
150 a8d3431a bellard
#else
151 53a5960a pbrook
   tput32(addr, p[1]);        /* msw */
152 53a5960a pbrook
   tput32(addr + 4, p[0]);        /* lsw */
153 a8d3431a bellard
#endif
154 5fafdf24 ths
}  
155 00406dff bellard
156 00406dff bellard
static inline
157 00406dff bellard
void storeExtended(const unsigned int Fn,unsigned int *pMem)
158 00406dff bellard
{
159 53a5960a pbrook
   target_ulong addr = (target_ulong)(long)pMem;
160 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
161 00406dff bellard
   floatx80 val;
162 00406dff bellard
   register unsigned int *p = (unsigned int*)&val;
163 5fafdf24 ths
  
164 00406dff bellard
   switch (fpa11->fType[Fn])
165 00406dff bellard
   {
166 5fafdf24 ths
      case typeSingle:
167 20495218 bellard
         val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
168 00406dff bellard
      break;
169 00406dff bellard
170 5fafdf24 ths
      case typeDouble:
171 20495218 bellard
         val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
172 00406dff bellard
      break;
173 00406dff bellard
174 00406dff bellard
      default: val = fpa11->fpreg[Fn].fExtended;
175 00406dff bellard
   }
176 5fafdf24 ths
  
177 53a5960a pbrook
   tput32(addr, p[0]); /* sign & exp */
178 53a5960a pbrook
   tput32(addr + 8, p[1]);
179 53a5960a pbrook
   tput32(addr + 4, p[2]); /* msw */
180 5fafdf24 ths
}  
181 00406dff bellard
182 00406dff bellard
static inline
183 00406dff bellard
void storeMultiple(const unsigned int Fn,unsigned int *pMem)
184 00406dff bellard
{
185 53a5960a pbrook
   target_ulong addr = (target_ulong)(long)pMem;
186 00406dff bellard
   FPA11 *fpa11 = GET_FPA11();
187 00406dff bellard
   register unsigned int nType, *p;
188 5fafdf24 ths
  
189 00406dff bellard
   p = (unsigned int*)&(fpa11->fpreg[Fn]);
190 00406dff bellard
   nType = fpa11->fType[Fn];
191 5fafdf24 ths
  
192 00406dff bellard
   switch (nType)
193 00406dff bellard
   {
194 00406dff bellard
      case typeSingle:
195 00406dff bellard
      case typeDouble:
196 00406dff bellard
      {
197 53a5960a pbrook
         tput32(addr + 8, p[0]); /* single */
198 53a5960a pbrook
         tput32(addr + 4, p[1]); /* double msw */
199 53a5960a pbrook
         tput32(addr, nType << 14);
200 00406dff bellard
      }
201 5fafdf24 ths
      break;
202 5fafdf24 ths
  
203 00406dff bellard
      case typeExtended:
204 00406dff bellard
      {
205 53a5960a pbrook
         tput32(addr + 4, p[2]); /* msw */
206 53a5960a pbrook
         tput32(addr + 8, p[1]);
207 53a5960a pbrook
         tput32(addr, (p[0] & 0x80003fff) | (nType << 14));
208 00406dff bellard
      }
209 00406dff bellard
      break;
210 00406dff bellard
   }
211 00406dff bellard
}
212 00406dff bellard
213 00406dff bellard
unsigned int PerformLDF(const unsigned int opcode)
214 00406dff bellard
{
215 00406dff bellard
   unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
216 00406dff bellard
     write_back = WRITE_BACK(opcode);
217 00406dff bellard
218 00406dff bellard
   //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
219 00406dff bellard
220 00406dff bellard
   pBase = (unsigned int*)readRegister(getRn(opcode));
221 00406dff bellard
   if (REG_PC == getRn(opcode))
222 00406dff bellard
   {
223 00406dff bellard
     pBase += 2;
224 00406dff bellard
     write_back = 0;
225 00406dff bellard
   }
226 00406dff bellard
227 00406dff bellard
   pFinal = pBase;
228 00406dff bellard
   if (BIT_UP_SET(opcode))
229 00406dff bellard
     pFinal += getOffset(opcode);
230 00406dff bellard
   else
231 00406dff bellard
     pFinal -= getOffset(opcode);
232 00406dff bellard
233 00406dff bellard
   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
234 00406dff bellard
235 00406dff bellard
   switch (opcode & MASK_TRANSFER_LENGTH)
236 00406dff bellard
   {
237 00406dff bellard
      case TRANSFER_SINGLE  : loadSingle(getFd(opcode),pAddress);   break;
238 00406dff bellard
      case TRANSFER_DOUBLE  : loadDouble(getFd(opcode),pAddress);   break;
239 00406dff bellard
      case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
240 00406dff bellard
      default: nRc = 0;
241 00406dff bellard
   }
242 5fafdf24 ths
  
243 00406dff bellard
   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
244 00406dff bellard
   return nRc;
245 00406dff bellard
}
246 00406dff bellard
247 00406dff bellard
unsigned int PerformSTF(const unsigned int opcode)
248 00406dff bellard
{
249 00406dff bellard
   unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
250 00406dff bellard
     write_back = WRITE_BACK(opcode);
251 5fafdf24 ths
  
252 00406dff bellard
   //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
253 00406dff bellard
   SetRoundingMode(ROUND_TO_NEAREST);
254 5fafdf24 ths
  
255 00406dff bellard
   pBase = (unsigned int*)readRegister(getRn(opcode));
256 00406dff bellard
   if (REG_PC == getRn(opcode))
257 00406dff bellard
   {
258 00406dff bellard
     pBase += 2;
259 00406dff bellard
     write_back = 0;
260 00406dff bellard
   }
261 00406dff bellard
262 00406dff bellard
   pFinal = pBase;
263 00406dff bellard
   if (BIT_UP_SET(opcode))
264 00406dff bellard
     pFinal += getOffset(opcode);
265 00406dff bellard
   else
266 00406dff bellard
     pFinal -= getOffset(opcode);
267 00406dff bellard
268 00406dff bellard
   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
269 00406dff bellard
270 00406dff bellard
   switch (opcode & MASK_TRANSFER_LENGTH)
271 00406dff bellard
   {
272 00406dff bellard
      case TRANSFER_SINGLE  : storeSingle(getFd(opcode),pAddress);   break;
273 00406dff bellard
      case TRANSFER_DOUBLE  : storeDouble(getFd(opcode),pAddress);   break;
274 00406dff bellard
      case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
275 00406dff bellard
      default: nRc = 0;
276 00406dff bellard
   }
277 5fafdf24 ths
  
278 00406dff bellard
   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
279 00406dff bellard
   return nRc;
280 00406dff bellard
}
281 00406dff bellard
282 00406dff bellard
unsigned int PerformLFM(const unsigned int opcode)
283 00406dff bellard
{
284 00406dff bellard
   unsigned int i, Fd, *pBase, *pAddress, *pFinal,
285 00406dff bellard
     write_back = WRITE_BACK(opcode);
286 00406dff bellard
287 00406dff bellard
   pBase = (unsigned int*)readRegister(getRn(opcode));
288 00406dff bellard
   if (REG_PC == getRn(opcode))
289 00406dff bellard
   {
290 00406dff bellard
     pBase += 2;
291 00406dff bellard
     write_back = 0;
292 00406dff bellard
   }
293 00406dff bellard
294 00406dff bellard
   pFinal = pBase;
295 00406dff bellard
   if (BIT_UP_SET(opcode))
296 00406dff bellard
     pFinal += getOffset(opcode);
297 00406dff bellard
   else
298 00406dff bellard
     pFinal -= getOffset(opcode);
299 00406dff bellard
300 00406dff bellard
   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
301 00406dff bellard
302 00406dff bellard
   Fd = getFd(opcode);
303 00406dff bellard
   for (i=getRegisterCount(opcode);i>0;i--)
304 00406dff bellard
   {
305 00406dff bellard
     loadMultiple(Fd,pAddress);
306 00406dff bellard
     pAddress += 3; Fd++;
307 00406dff bellard
     if (Fd == 8) Fd = 0;
308 00406dff bellard
   }
309 00406dff bellard
310 00406dff bellard
   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
311 00406dff bellard
   return 1;
312 00406dff bellard
}
313 00406dff bellard
314 00406dff bellard
unsigned int PerformSFM(const unsigned int opcode)
315 00406dff bellard
{
316 00406dff bellard
   unsigned int i, Fd, *pBase, *pAddress, *pFinal,
317 00406dff bellard
     write_back = WRITE_BACK(opcode);
318 5fafdf24 ths
  
319 00406dff bellard
   pBase = (unsigned int*)readRegister(getRn(opcode));
320 00406dff bellard
   if (REG_PC == getRn(opcode))
321 00406dff bellard
   {
322 00406dff bellard
     pBase += 2;
323 00406dff bellard
     write_back = 0;
324 00406dff bellard
   }
325 5fafdf24 ths
  
326 00406dff bellard
   pFinal = pBase;
327 00406dff bellard
   if (BIT_UP_SET(opcode))
328 00406dff bellard
     pFinal += getOffset(opcode);
329 00406dff bellard
   else
330 00406dff bellard
     pFinal -= getOffset(opcode);
331 00406dff bellard
332 00406dff bellard
   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
333 00406dff bellard
334 00406dff bellard
   Fd = getFd(opcode);
335 00406dff bellard
   for (i=getRegisterCount(opcode);i>0;i--)
336 00406dff bellard
   {
337 00406dff bellard
     storeMultiple(Fd,pAddress);
338 00406dff bellard
     pAddress += 3; Fd++;
339 00406dff bellard
     if (Fd == 8) Fd = 0;
340 00406dff bellard
   }
341 00406dff bellard
342 00406dff bellard
   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
343 00406dff bellard
   return 1;
344 00406dff bellard
}
345 00406dff bellard
346 00406dff bellard
#if 1
347 00406dff bellard
unsigned int EmulateCPDT(const unsigned int opcode)
348 00406dff bellard
{
349 00406dff bellard
  unsigned int nRc = 0;
350 00406dff bellard
351 00406dff bellard
  //printk("EmulateCPDT(0x%08x)\n",opcode);
352 5fafdf24 ths
 
353 00406dff bellard
  if (LDF_OP(opcode))
354 00406dff bellard
  {
355 00406dff bellard
    nRc = PerformLDF(opcode);
356 00406dff bellard
  }
357 00406dff bellard
  else if (LFM_OP(opcode))
358 00406dff bellard
  {
359 00406dff bellard
    nRc = PerformLFM(opcode);
360 00406dff bellard
  }
361 00406dff bellard
  else if (STF_OP(opcode))
362 00406dff bellard
  {
363 00406dff bellard
    nRc = PerformSTF(opcode);
364 5fafdf24 ths
  }
365 00406dff bellard
  else if (SFM_OP(opcode))
366 00406dff bellard
  {
367 00406dff bellard
    nRc = PerformSFM(opcode);
368 00406dff bellard
  }
369 00406dff bellard
  else
370 00406dff bellard
  {
371 00406dff bellard
    nRc = 0;
372 00406dff bellard
  }
373 5fafdf24 ths
 
374 00406dff bellard
  return nRc;
375 00406dff bellard
}
376 00406dff bellard
#endif