/[qemu]/qemu/target-ppc/op_helper.c
ViewVC logotype

Diff of /qemu/target-ppc/op_helper.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.11 by bellard, Tue Feb 15 23:06:19 2005 UTC revision 1.12 by bellard, Sun Mar 13 17:01:22 2005 UTC
# Line 213  void do_store_fpscr (uint32_t mask) Line 213  void do_store_fpscr (uint32_t mask)
213              uint32_t u[2];              uint32_t u[2];
214          } s;          } s;
215      } u;      } u;
216      int i;      int i, rnd_type;
217    
218      u.d = FT0;      u.d = FT0;
219      if (mask & 0x80)      if (mask & 0x80)
# Line 227  void do_store_fpscr (uint32_t mask) Line 227  void do_store_fpscr (uint32_t mask)
227      switch (env->fpscr[0] & 0x3) {      switch (env->fpscr[0] & 0x3) {
228      case 0:      case 0:
229          /* Best approximation (round to nearest) */          /* Best approximation (round to nearest) */
230          fesetround(FE_TONEAREST);          rnd_type = float_round_nearest_even;
231          break;          break;
232      case 1:      case 1:
233          /* Smaller magnitude (round toward zero) */          /* Smaller magnitude (round toward zero) */
234          fesetround(FE_TOWARDZERO);          rnd_type = float_round_to_zero;
235          break;          break;
236      case 2:      case 2:
237          /* Round toward +infinite */          /* Round toward +infinite */
238          fesetround(FE_UPWARD);          rnd_type = float_round_up;
239          break;          break;
240        default:
241      case 3:      case 3:
242          /* Round toward -infinite */          /* Round toward -infinite */
243          fesetround(FE_DOWNWARD);          rnd_type = float_round_down;
244          break;          break;
245      }      }
246        set_float_rounding_mode(rnd_type, &env->fp_status);
247  }  }
248    
249  void do_fctiw (void)  void do_fctiw (void)
# Line 249  void do_fctiw (void) Line 251  void do_fctiw (void)
251      union {      union {
252          double d;          double d;
253          uint64_t i;          uint64_t i;
254      } *p = (void *)&FT1;      } p;
255    
256      if (FT0 > (double)0x7FFFFFFF)      /* XXX: higher bits are not supposed to be significant.
257          p->i = 0x7FFFFFFFULL << 32;       *      to make tests easier, return the same as a real PPC 750 (aka G3)
258      else if (FT0 < -(double)0x80000000)       */
259          p->i = 0x80000000ULL << 32;      p.i = float64_to_int32(FT0, &env->fp_status);
260      else      p.i |= 0xFFF80000ULL << 32;
261          p->i = 0;      FT0 = p.d;
     p->i |= (uint32_t)FT0;  
     FT0 = p->d;  
262  }  }
263    
264  void do_fctiwz (void)  void do_fctiwz (void)
# Line 266  void do_fctiwz (void) Line 266  void do_fctiwz (void)
266      union {      union {
267          double d;          double d;
268          uint64_t i;          uint64_t i;
269      } *p = (void *)&FT1;      } p;
     int cround = fegetround();  
270    
271      fesetround(FE_TOWARDZERO);      /* XXX: higher bits are not supposed to be significant.
272      if (FT0 > (double)0x7FFFFFFF)       *      to make tests easier, return the same as a real PPC 750 (aka G3)
273          p->i = 0x7FFFFFFFULL << 32;       */
274      else if (FT0 < -(double)0x80000000)      p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
275          p->i = 0x80000000ULL << 32;      p.i |= 0xFFF80000ULL << 32;
276      else      FT0 = p.d;
         p->i = 0;  
     p->i |= (uint32_t)FT0;  
     FT0 = p->d;  
     fesetround(cround);  
277  }  }
278    
279  void do_fnmadd (void)  void do_fnmadd (void)
280  {  {
281      FT0 = -((FT0 * FT1) + FT2);      FT0 = (FT0 * FT1) + FT2;
282        if (!isnan(FT0))
283            FT0 = -FT0;
284  }  }
285    
286  void do_fnmsub (void)  void do_fnmsub (void)
287  {  {
288      FT0 = -((FT0 * FT1) - FT2);      FT0 = (FT0 * FT1) - FT2;
289  }      if (!isnan(FT0))
290            FT0 = -FT0;
 void do_fnmadds (void)  
 {  
     FT0 = -((FTS0 * FTS1) + FTS2);  
291  }  }
292    
293  void do_fnmsubs (void)  void do_fdiv (void)
294  {  {
295      FT0 = -((FTS0 * FTS1) - FTS2);      if (FT0 == -0.0 && FT1 == -0.0)
296            FT0 = 0.0 / 0.0;
297        else
298            FT0 /= FT1;
299  }  }
300    
301  void do_fsqrt (void)  void do_fsqrt (void)
# Line 306  void do_fsqrt (void) Line 303  void do_fsqrt (void)
303      FT0 = sqrt(FT0);      FT0 = sqrt(FT0);
304  }  }
305    
 void do_fsqrts (void)  
 {  
     FT0 = (float)sqrt((float)FT0);  
 }  
   
306  void do_fres (void)  void do_fres (void)
307  {  {
308      FT0 = 1.0 / FT0;      union {
309            double d;
310            uint64_t i;
311        } p;
312    
313        if (isnormal(FT0)) {
314            FT0 = (float)(1.0 / FT0);
315        } else {
316            p.d = FT0;
317            if (p.i == 0x8000000000000000ULL) {
318                p.i = 0xFFF0000000000000ULL;
319            } else if (p.i == 0x0000000000000000ULL) {
320                p.i = 0x7FF0000000000000ULL;
321            } else if (isnan(FT0)) {
322                p.i = 0x7FF8000000000000ULL;
323            } else if (FT0 < 0.0) {
324                p.i = 0x8000000000000000ULL;
325            } else {
326                p.i = 0x0000000000000000ULL;
327            }
328            FT0 = p.d;
329        }
330  }  }
331    
332  void do_fsqrte (void)  void do_frsqrte (void)
333  {  {
334      FT0 = 1.0 / sqrt(FT0);      union {
335            double d;
336            uint64_t i;
337        } p;
338    
339        if (isnormal(FT0) && FT0 > 0.0) {
340            FT0 = (float)(1.0 / sqrt(FT0));
341        } else {
342            p.d = FT0;
343            if (p.i == 0x8000000000000000ULL) {
344                p.i = 0xFFF0000000000000ULL;
345            } else if (p.i == 0x0000000000000000ULL) {
346                p.i = 0x7FF0000000000000ULL;
347            } else if (isnan(FT0)) {
348                if (!(p.i & 0x0008000000000000ULL))
349                    p.i |= 0x000FFFFFFFFFFFFFULL;
350            } else if (FT0 < 0) {
351                p.i = 0x7FF8000000000000ULL;
352            } else {
353                p.i = 0x0000000000000000ULL;
354            }
355            FT0 = p.d;
356        }
357  }  }
358    
359  void do_fsel (void)  void do_fsel (void)
360  {  {
361      if (FT0 >= 0)      if (FT0 >= 0)
         FT0 = FT2;  
     else  
362          FT0 = FT1;          FT0 = FT1;
363        else
364            FT0 = FT2;
365  }  }
366    
367  void do_fcmpu (void)  void do_fcmpu (void)
# Line 371  void do_fcmpo (void) Line 406  void do_fcmpo (void)
406    
407  void do_fabs (void)  void do_fabs (void)
408  {  {
409      FT0 = fabsl(FT0);      union {
410            double d;
411            uint64_t i;
412        } p;
413    
414        p.d = FT0;
415        p.i &= ~0x8000000000000000ULL;
416        FT0 = p.d;
417  }  }
418    
419  void do_fnabs (void)  void do_fnabs (void)
420  {  {
421      FT0 = -fabsl(FT0);      union {
422            double d;
423            uint64_t i;
424        } p;
425    
426        p.d = FT0;
427        p.i |= 0x8000000000000000ULL;
428        FT0 = p.d;
429  }  }
430    
431  /* Instruction cache invalidation helper */  /* Instruction cache invalidation helper */

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.12

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26