Commit af12906f77f37a3dd7da158d5b42d90a59d6fc7a

Authored by aurel32
1 parent a3d6841f

target-ppc: convert fp ops to TCG

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5754 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/cpu.h
... ... @@ -571,7 +571,6 @@ struct CPUPPCState {
571 571 /* temporary float registers */
572 572 float64 ft0;
573 573 float64 ft1;
574   - float64 ft2;
575 574 float_status fp_status;
576 575 /* floating point registers */
577 576 float64 fpr[32];
... ...
target-ppc/exec.h
... ... @@ -61,7 +61,6 @@ register target_ulong T2 asm(AREG3);
61 61  
62 62 #define FT0 (env->ft0)
63 63 #define FT1 (env->ft1)
64   -#define FT2 (env->ft2)
65 64  
66 65 #if defined (DEBUG_OP)
67 66 # define RETURN() __asm__ __volatile__("nop" : : : "memory");
... ...
target-ppc/helper.h
1 1 #include "def-helper.h"
2 2  
3   -DEF_HELPER_0(fcmpo, i32)
4   -DEF_HELPER_0(fcmpu, i32)
  3 +DEF_HELPER_2(fcmpo, i32, i64, i64)
  4 +DEF_HELPER_2(fcmpu, i32, i64, i64)
5 5  
6 6 DEF_HELPER_0(load_cr, tl)
7 7 DEF_HELPER_2(store_cr, void, tl, i32)
... ... @@ -25,4 +25,42 @@ DEF_HELPER_1(cntlsw32, i32, i32)
25 25 DEF_HELPER_1(cntlzw32, i32, i32)
26 26 DEF_HELPER_2(brinc, tl, tl, tl)
27 27  
  28 +DEF_HELPER_0(float_check_status, void)
  29 +#ifdef CONFIG_SOFTFLOAT
  30 +DEF_HELPER_0(reset_fpstatus, void)
  31 +#endif
  32 +DEF_HELPER_2(compute_fprf, i32, i64, i32)
  33 +DEF_HELPER_2(store_fpscr, void, i64, i32)
  34 +DEF_HELPER_1(fpscr_setbit, void, i32)
  35 +
  36 +DEF_HELPER_1(fctiw, i64, i64)
  37 +DEF_HELPER_1(fctiwz, i64, i64)
  38 +#if defined(TARGET_PPC64)
  39 +DEF_HELPER_1(fcfid, i64, i64)
  40 +DEF_HELPER_1(fctid, i64, i64)
  41 +DEF_HELPER_1(fctidz, i64, i64)
  42 +#endif
  43 +DEF_HELPER_1(frsp, i64, i64)
  44 +DEF_HELPER_1(frin, i64, i64)
  45 +DEF_HELPER_1(friz, i64, i64)
  46 +DEF_HELPER_1(frip, i64, i64)
  47 +DEF_HELPER_1(frim, i64, i64)
  48 +
  49 +DEF_HELPER_2(fadd, i64, i64, i64)
  50 +DEF_HELPER_2(fsub, i64, i64, i64)
  51 +DEF_HELPER_2(fmul, i64, i64, i64)
  52 +DEF_HELPER_2(fdiv, i64, i64, i64)
  53 +DEF_HELPER_3(fmadd, i64, i64, i64, i64)
  54 +DEF_HELPER_3(fmsub, i64, i64, i64, i64)
  55 +DEF_HELPER_3(fnmadd, i64, i64, i64, i64)
  56 +DEF_HELPER_3(fnmsub, i64, i64, i64, i64)
  57 +DEF_HELPER_1(fabs, i64, i64)
  58 +DEF_HELPER_1(fnabs, i64, i64)
  59 +DEF_HELPER_1(fneg, i64, i64)
  60 +DEF_HELPER_1(fsqrt, i64, i64);
  61 +DEF_HELPER_1(fre, i64, i64);
  62 +DEF_HELPER_1(fres, i64, i64);
  63 +DEF_HELPER_1(frsqrte, i64, i64);
  64 +DEF_HELPER_3(fsel, i64, i64, i64, i64)
  65 +
28 66 #include "def-helper.h"
... ...
target-ppc/op.c
... ... @@ -261,71 +261,6 @@ void OPPROTO op_store_dbatl (void)
261 261 }
262 262 #endif /* !defined(CONFIG_USER_ONLY) */
263 263  
264   -/* FPSCR */
265   -#ifdef CONFIG_SOFTFLOAT
266   -void OPPROTO op_reset_fpstatus (void)
267   -{
268   - env->fp_status.float_exception_flags = 0;
269   - RETURN();
270   -}
271   -#endif
272   -
273   -void OPPROTO op_compute_fprf (void)
274   -{
275   - do_compute_fprf(PARAM1);
276   - RETURN();
277   -}
278   -
279   -#ifdef CONFIG_SOFTFLOAT
280   -void OPPROTO op_float_check_status (void)
281   -{
282   - do_float_check_status();
283   - RETURN();
284   -}
285   -#else
286   -void OPPROTO op_float_check_status (void)
287   -{
288   - if (env->exception_index == POWERPC_EXCP_PROGRAM &&
289   - (env->error_code & POWERPC_EXCP_FP)) {
290   - /* Differred floating-point exception after target FPR update */
291   - if (msr_fe0 != 0 || msr_fe1 != 0)
292   - do_raise_exception_err(env->exception_index, env->error_code);
293   - }
294   - RETURN();
295   -}
296   -#endif
297   -
298   -void OPPROTO op_load_fpscr_FT0 (void)
299   -{
300   - /* The 32 MSB of the target fpr are undefined.
301   - * They'll be zero...
302   - */
303   - CPU_DoubleU u;
304   -
305   - u.l.upper = 0;
306   - u.l.lower = env->fpscr;
307   - FT0 = u.d;
308   - RETURN();
309   -}
310   -
311   -void OPPROTO op_fpscr_resetbit (void)
312   -{
313   - env->fpscr &= PARAM1;
314   - RETURN();
315   -}
316   -
317   -void OPPROTO op_fpscr_setbit (void)
318   -{
319   - do_fpscr_setbit(PARAM1);
320   - RETURN();
321   -}
322   -
323   -void OPPROTO op_store_fpscr (void)
324   -{
325   - do_store_fpscr(PARAM1);
326   - RETURN();
327   -}
328   -
329 264 /*** Integer shift ***/
330 265 void OPPROTO op_srli_T1 (void)
331 266 {
... ... @@ -333,221 +268,6 @@ void OPPROTO op_srli_T1 (void)
333 268 RETURN();
334 269 }
335 270  
336   -/*** Floating-Point arithmetic ***/
337   -/* fadd - fadd. */
338   -void OPPROTO op_fadd (void)
339   -{
340   -#if USE_PRECISE_EMULATION
341   - do_fadd();
342   -#else
343   - FT0 = float64_add(FT0, FT1, &env->fp_status);
344   -#endif
345   - RETURN();
346   -}
347   -
348   -/* fsub - fsub. */
349   -void OPPROTO op_fsub (void)
350   -{
351   -#if USE_PRECISE_EMULATION
352   - do_fsub();
353   -#else
354   - FT0 = float64_sub(FT0, FT1, &env->fp_status);
355   -#endif
356   - RETURN();
357   -}
358   -
359   -/* fmul - fmul. */
360   -void OPPROTO op_fmul (void)
361   -{
362   -#if USE_PRECISE_EMULATION
363   - do_fmul();
364   -#else
365   - FT0 = float64_mul(FT0, FT1, &env->fp_status);
366   -#endif
367   - RETURN();
368   -}
369   -
370   -/* fdiv - fdiv. */
371   -void OPPROTO op_fdiv (void)
372   -{
373   -#if USE_PRECISE_EMULATION
374   - do_fdiv();
375   -#else
376   - FT0 = float64_div(FT0, FT1, &env->fp_status);
377   -#endif
378   - RETURN();
379   -}
380   -
381   -/* fsqrt - fsqrt. */
382   -void OPPROTO op_fsqrt (void)
383   -{
384   - do_fsqrt();
385   - RETURN();
386   -}
387   -
388   -/* fre - fre. */
389   -void OPPROTO op_fre (void)
390   -{
391   - do_fre();
392   - RETURN();
393   -}
394   -
395   -/* fres - fres. */
396   -void OPPROTO op_fres (void)
397   -{
398   - do_fres();
399   - RETURN();
400   -}
401   -
402   -/* frsqrte - frsqrte. */
403   -void OPPROTO op_frsqrte (void)
404   -{
405   - do_frsqrte();
406   - RETURN();
407   -}
408   -
409   -/* fsel - fsel. */
410   -void OPPROTO op_fsel (void)
411   -{
412   - do_fsel();
413   - RETURN();
414   -}
415   -
416   -/*** Floating-Point multiply-and-add ***/
417   -/* fmadd - fmadd. */
418   -void OPPROTO op_fmadd (void)
419   -{
420   -#if USE_PRECISE_EMULATION
421   - do_fmadd();
422   -#else
423   - FT0 = float64_mul(FT0, FT1, &env->fp_status);
424   - FT0 = float64_add(FT0, FT2, &env->fp_status);
425   -#endif
426   - RETURN();
427   -}
428   -
429   -/* fmsub - fmsub. */
430   -void OPPROTO op_fmsub (void)
431   -{
432   -#if USE_PRECISE_EMULATION
433   - do_fmsub();
434   -#else
435   - FT0 = float64_mul(FT0, FT1, &env->fp_status);
436   - FT0 = float64_sub(FT0, FT2, &env->fp_status);
437   -#endif
438   - RETURN();
439   -}
440   -
441   -/* fnmadd - fnmadd. - fnmadds - fnmadds. */
442   -void OPPROTO op_fnmadd (void)
443   -{
444   - do_fnmadd();
445   - RETURN();
446   -}
447   -
448   -/* fnmsub - fnmsub. */
449   -void OPPROTO op_fnmsub (void)
450   -{
451   - do_fnmsub();
452   - RETURN();
453   -}
454   -
455   -/*** Floating-Point round & convert ***/
456   -/* frsp - frsp. */
457   -void OPPROTO op_frsp (void)
458   -{
459   -#if USE_PRECISE_EMULATION
460   - do_frsp();
461   -#else
462   - FT0 = float64_to_float32(FT0, &env->fp_status);
463   -#endif
464   - RETURN();
465   -}
466   -
467   -/* fctiw - fctiw. */
468   -void OPPROTO op_fctiw (void)
469   -{
470   - do_fctiw();
471   - RETURN();
472   -}
473   -
474   -/* fctiwz - fctiwz. */
475   -void OPPROTO op_fctiwz (void)
476   -{
477   - do_fctiwz();
478   - RETURN();
479   -}
480   -
481   -#if defined(TARGET_PPC64)
482   -/* fcfid - fcfid. */
483   -void OPPROTO op_fcfid (void)
484   -{
485   - do_fcfid();
486   - RETURN();
487   -}
488   -
489   -/* fctid - fctid. */
490   -void OPPROTO op_fctid (void)
491   -{
492   - do_fctid();
493   - RETURN();
494   -}
495   -
496   -/* fctidz - fctidz. */
497   -void OPPROTO op_fctidz (void)
498   -{
499   - do_fctidz();
500   - RETURN();
501   -}
502   -#endif
503   -
504   -void OPPROTO op_frin (void)
505   -{
506   - do_frin();
507   - RETURN();
508   -}
509   -
510   -void OPPROTO op_friz (void)
511   -{
512   - do_friz();
513   - RETURN();
514   -}
515   -
516   -void OPPROTO op_frip (void)
517   -{
518   - do_frip();
519   - RETURN();
520   -}
521   -
522   -void OPPROTO op_frim (void)
523   -{
524   - do_frim();
525   - RETURN();
526   -}
527   -
528   -/*** Floating-point move ***/
529   -/* fabs */
530   -void OPPROTO op_fabs (void)
531   -{
532   - FT0 = float64_abs(FT0);
533   - RETURN();
534   -}
535   -
536   -/* fnabs */
537   -void OPPROTO op_fnabs (void)
538   -{
539   - FT0 = float64_abs(FT0);
540   - FT0 = float64_chs(FT0);
541   - RETURN();
542   -}
543   -
544   -/* fneg */
545   -void OPPROTO op_fneg (void)
546   -{
547   - FT0 = float64_chs(FT0);
548   - RETURN();
549   -}
550   -
551 271 /* Load and store */
552 272 #define MEMSUFFIX _raw
553 273 #include "op_helper.h"
... ...
target-ppc/op_helper.c
... ... @@ -299,59 +299,62 @@ static always_inline int isnormal (float64 d)
299 299 }
300 300 #endif
301 301  
302   -void do_compute_fprf (int set_fprf)
  302 +uint32_t helper_compute_fprf (uint64_t arg, uint32_t set_fprf)
303 303 {
  304 + CPU_DoubleU farg;
304 305 int isneg;
305   -
306   - isneg = fpisneg(FT0);
307   - if (unlikely(float64_is_nan(FT0))) {
308   - if (float64_is_signaling_nan(FT0)) {
  306 + int ret;
  307 + farg.ll = arg;
  308 + isneg = fpisneg(farg.d);
  309 + if (unlikely(float64_is_nan(farg.d))) {
  310 + if (float64_is_signaling_nan(farg.d)) {
309 311 /* Signaling NaN: flags are undefined */
310   - T0 = 0x00;
  312 + ret = 0x00;
311 313 } else {
312 314 /* Quiet NaN */
313   - T0 = 0x11;
  315 + ret = 0x11;
314 316 }
315   - } else if (unlikely(isinfinity(FT0))) {
  317 + } else if (unlikely(isinfinity(farg.d))) {
316 318 /* +/- infinity */
317 319 if (isneg)
318   - T0 = 0x09;
  320 + ret = 0x09;
319 321 else
320   - T0 = 0x05;
  322 + ret = 0x05;
321 323 } else {
322   - if (iszero(FT0)) {
  324 + if (iszero(farg.d)) {
323 325 /* +/- zero */
324 326 if (isneg)
325   - T0 = 0x12;
  327 + ret = 0x12;
326 328 else
327   - T0 = 0x02;
  329 + ret = 0x02;
328 330 } else {
329   - if (isden(FT0)) {
  331 + if (isden(farg.d)) {
330 332 /* Denormalized numbers */
331   - T0 = 0x10;
  333 + ret = 0x10;
332 334 } else {
333 335 /* Normalized numbers */
334   - T0 = 0x00;
  336 + ret = 0x00;
335 337 }
336 338 if (isneg) {
337   - T0 |= 0x08;
  339 + ret |= 0x08;
338 340 } else {
339   - T0 |= 0x04;
  341 + ret |= 0x04;
340 342 }
341 343 }
342 344 }
343 345 if (set_fprf) {
344 346 /* We update FPSCR_FPRF */
345 347 env->fpscr &= ~(0x1F << FPSCR_FPRF);
346   - env->fpscr |= T0 << FPSCR_FPRF;
  348 + env->fpscr |= ret << FPSCR_FPRF;
347 349 }
348 350 /* We just need fpcc to update Rc1 */
349   - T0 &= 0xF;
  351 + return ret & 0xF;
350 352 }
351 353  
352 354 /* Floating-point invalid operations exception */
353   -static always_inline void fload_invalid_op_excp (int op)
  355 +static always_inline uint64_t fload_invalid_op_excp (int op)
354 356 {
  357 + uint64_t ret = 0;
355 358 int ve;
356 359  
357 360 ve = fpscr_ve;
... ... @@ -402,7 +405,7 @@ static always_inline void fload_invalid_op_excp (int op)
402 405 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
403 406 if (ve == 0) {
404 407 /* Set the result to quiet NaN */
405   - FT0 = UINT64_MAX;
  408 + ret = UINT64_MAX;
406 409 env->fpscr &= ~(0xF << FPSCR_FPCC);
407 410 env->fpscr |= 0x11 << FPSCR_FPCC;
408 411 }
... ... @@ -413,7 +416,7 @@ static always_inline void fload_invalid_op_excp (int op)
413 416 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
414 417 if (ve == 0) {
415 418 /* Set the result to quiet NaN */
416   - FT0 = UINT64_MAX;
  419 + ret = UINT64_MAX;
417 420 env->fpscr &= ~(0xF << FPSCR_FPCC);
418 421 env->fpscr |= 0x11 << FPSCR_FPCC;
419 422 }
... ... @@ -429,12 +432,11 @@ static always_inline void fload_invalid_op_excp (int op)
429 432 if (msr_fe0 != 0 || msr_fe1 != 0)
430 433 do_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op);
431 434 }
  435 + return ret;
432 436 }
433 437  
434   -static always_inline void float_zero_divide_excp (void)
  438 +static always_inline uint64_t float_zero_divide_excp (uint64_t arg1, uint64_t arg2)
435 439 {
436   - CPU_DoubleU u0, u1;
437   -
438 440 env->fpscr |= 1 << FPSCR_ZX;
439 441 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
440 442 /* Update the floating-point exception summary */
... ... @@ -448,12 +450,10 @@ static always_inline void float_zero_divide_excp (void)
448 450 }
449 451 } else {
450 452 /* Set the result to infinity */
451   - u0.d = FT0;
452   - u1.d = FT1;
453   - u0.ll = ((u0.ll ^ u1.ll) & 0x8000000000000000ULL);
454   - u0.ll |= 0x7FFULL << 52;
455   - FT0 = u0.d;
  453 + arg1 = ((arg1 ^ arg2) & 0x8000000000000000ULL);
  454 + arg1 |= 0x7FFULL << 52;
456 455 }
  456 + return arg1;
457 457 }
458 458  
459 459 static always_inline void float_overflow_excp (void)
... ... @@ -530,7 +530,7 @@ static always_inline void fpscr_set_rounding_mode (void)
530 530 set_float_rounding_mode(rnd_type, &env->fp_status);
531 531 }
532 532  
533   -void do_fpscr_setbit (int bit)
  533 +void helper_fpscr_setbit (uint32_t bit)
534 534 {
535 535 int prev;
536 536  
... ... @@ -645,25 +645,16 @@ void do_fpscr_setbit (int bit)
645 645 }
646 646 }
647 647  
648   -#if defined(WORDS_BIGENDIAN)
649   -#define WORD0 0
650   -#define WORD1 1
651   -#else
652   -#define WORD0 1
653   -#define WORD1 0
654   -#endif
655   -void do_store_fpscr (uint32_t mask)
  648 +void helper_store_fpscr (uint64_t arg, uint32_t mask)
656 649 {
657 650 /*
658 651 * We use only the 32 LSB of the incoming fpr
659 652 */
660   - CPU_DoubleU u;
661 653 uint32_t prev, new;
662 654 int i;
663 655  
664   - u.d = FT0;
665 656 prev = env->fpscr;
666   - new = u.l.lower;
  657 + new = (uint32_t)arg;
667 658 new &= ~0x90000000;
668 659 new |= prev & 0x90000000;
669 660 for (i = 0; i < 7; i++) {
... ... @@ -687,12 +678,10 @@ void do_store_fpscr (uint32_t mask)
687 678 env->fpscr &= ~(1 << FPSCR_FEX);
688 679 fpscr_set_rounding_mode();
689 680 }
690   -#undef WORD0
691   -#undef WORD1
692 681  
693   -#ifdef CONFIG_SOFTFLOAT
694   -void do_float_check_status (void)
  682 +void helper_float_check_status (void)
695 683 {
  684 +#ifdef CONFIG_SOFTFLOAT
696 685 if (env->exception_index == POWERPC_EXCP_PROGRAM &&
697 686 (env->error_code & POWERPC_EXCP_FP)) {
698 687 /* Differred floating-point exception after target FPR update */
... ... @@ -705,455 +694,618 @@ void do_float_check_status (void)
705 694 } else if (env->fp_status.float_exception_flags & float_flag_inexact) {
706 695 float_inexact_excp();
707 696 }
  697 +#else
  698 + if (env->exception_index == POWERPC_EXCP_PROGRAM &&
  699 + (env->error_code & POWERPC_EXCP_FP)) {
  700 + /* Differred floating-point exception after target FPR update */
  701 + if (msr_fe0 != 0 || msr_fe1 != 0)
  702 + do_raise_exception_err(env->exception_index, env->error_code);
  703 + }
  704 + RETURN();
  705 +#endif
  706 +}
  707 +
  708 +#ifdef CONFIG_SOFTFLOAT
  709 +void helper_reset_fpstatus (void)
  710 +{
  711 + env->fp_status.float_exception_flags = 0;
708 712 }
709 713 #endif
710 714  
711   -#if USE_PRECISE_EMULATION
712   -void do_fadd (void)
  715 +/* fadd - fadd. */
  716 +uint64_t helper_fadd (uint64_t arg1, uint64_t arg2)
713 717 {
714   - if (unlikely(float64_is_signaling_nan(FT0) ||
715   - float64_is_signaling_nan(FT1))) {
  718 + CPU_DoubleU farg1, farg2;
  719 +
  720 + farg1.ll = arg1;
  721 + farg2.ll = arg2;
  722 +#if USE_PRECISE_EMULATION
  723 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  724 + float64_is_signaling_nan(farg2.d))) {
716 725 /* sNaN addition */
717   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
718   - } else if (likely(isfinite(FT0) || isfinite(FT1) ||
719   - fpisneg(FT0) == fpisneg(FT1))) {
720   - FT0 = float64_add(FT0, FT1, &env->fp_status);
  726 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  727 + } else if (likely(isfinite(farg1.d) || isfinite(farg2.d) ||
  728 + fpisneg(farg1.d) == fpisneg(farg2.d))) {
  729 + farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status);
721 730 } else {
722 731 /* Magnitude subtraction of infinities */
723   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);
  732 + farg1.ll == fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);
724 733 }
  734 +#else
  735 + farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status);
  736 +#endif
  737 + return farg1.ll;
725 738 }
726 739  
727   -void do_fsub (void)
  740 +/* fsub - fsub. */
  741 +uint64_t helper_fsub (uint64_t arg1, uint64_t arg2)
728 742 {
729   - if (unlikely(float64_is_signaling_nan(FT0) ||
730   - float64_is_signaling_nan(FT1))) {
  743 + CPU_DoubleU farg1, farg2;
  744 +
  745 + farg1.ll = arg1;
  746 + farg2.ll = arg2;
  747 +#if USE_PRECISE_EMULATION
  748 +{
  749 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  750 + float64_is_signaling_nan(farg2.d))) {
731 751 /* sNaN subtraction */
732   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
733   - } else if (likely(isfinite(FT0) || isfinite(FT1) ||
734   - fpisneg(FT0) != fpisneg(FT1))) {
735   - FT0 = float64_sub(FT0, FT1, &env->fp_status);
  752 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  753 + } else if (likely(isfinite(farg1.d) || isfinite(farg2.d) ||
  754 + fpisneg(farg1.d) != fpisneg(farg2.d))) {
  755 + farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status);
736 756 } else {
737 757 /* Magnitude subtraction of infinities */
738   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);
  758 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);
739 759 }
740 760 }
  761 +#else
  762 + farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status);
  763 +#endif
  764 + return farg1.ll;
  765 +}
741 766  
742   -void do_fmul (void)
  767 +/* fmul - fmul. */
  768 +uint64_t helper_fmul (uint64_t arg1, uint64_t arg2)
743 769 {
744   - if (unlikely(float64_is_signaling_nan(FT0) ||
745   - float64_is_signaling_nan(FT1))) {
  770 + CPU_DoubleU farg1, farg2;
  771 +
  772 + farg1.ll = arg1;
  773 + farg2.ll = arg2;
  774 +#if USE_PRECISE_EMULATION
  775 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  776 + float64_is_signaling_nan(farg2.d))) {
746 777 /* sNaN multiplication */
747   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
748   - } else if (unlikely((isinfinity(FT0) && iszero(FT1)) ||
749   - (iszero(FT0) && isinfinity(FT1)))) {
  778 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  779 + } else if (unlikely((isinfinity(farg1.d) && iszero(farg2.d)) ||
  780 + (iszero(farg1.d) && isinfinity(farg2.d)))) {
750 781 /* Multiplication of zero by infinity */
751   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXIMZ);
  782 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXIMZ);
752 783 } else {
753   - FT0 = float64_mul(FT0, FT1, &env->fp_status);
  784 + farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
754 785 }
755 786 }
  787 +#else
  788 + farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
  789 +#endif
  790 + return farg1.ll;
  791 +}
756 792  
757   -void do_fdiv (void)
  793 +/* fdiv - fdiv. */
  794 +uint64_t helper_fdiv (uint64_t arg1, uint64_t arg2)
758 795 {
759   - if (unlikely(float64_is_signaling_nan(FT0) ||
760   - float64_is_signaling_nan(FT1))) {
  796 + CPU_DoubleU farg1, farg2;
  797 +
  798 + farg1.ll = arg1;
  799 + farg2.ll = arg2;
  800 +#if USE_PRECISE_EMULATION
  801 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  802 + float64_is_signaling_nan(farg2.d))) {
761 803 /* sNaN division */
762   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
763   - } else if (unlikely(isinfinity(FT0) && isinfinity(FT1))) {
  804 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  805 + } else if (unlikely(isinfinity(farg1.d) && isinfinity(farg2.d))) {
764 806 /* Division of infinity by infinity */
765   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXIDI);
766   - } else if (unlikely(iszero(FT1))) {
767   - if (iszero(FT0)) {
  807 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXIDI);
  808 + } else if (unlikely(iszero(farg2.d))) {
  809 + if (iszero(farg1.d)) {
768 810 /* Division of zero by zero */
769   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXZDZ);
  811 + farg1.ll fload_invalid_op_excp(POWERPC_EXCP_FP_VXZDZ);
770 812 } else {
771 813 /* Division by zero */
772   - float_zero_divide_excp();
  814 + farg1.ll = float_zero_divide_excp(farg1.d, farg2.d);
773 815 }
774 816 } else {
775   - FT0 = float64_div(FT0, FT1, &env->fp_status);
  817 + farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status);
776 818 }
  819 +#else
  820 + farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status);
  821 +#endif
  822 + return farg1.ll;
777 823 }
778   -#endif /* USE_PRECISE_EMULATION */
779 824  
780   -void do_fctiw (void)
  825 +/* fabs */
  826 +uint64_t helper_fabs (uint64_t arg)
781 827 {
782   - CPU_DoubleU p;
  828 + CPU_DoubleU farg;
783 829  
784   - if (unlikely(float64_is_signaling_nan(FT0))) {
  830 + farg.ll = arg;
  831 + farg.d = float64_abs(farg.d);
  832 + return farg.ll;
  833 +}
  834 +
  835 +/* fnabs */
  836 +uint64_t helper_fnabs (uint64_t arg)
  837 +{
  838 + CPU_DoubleU farg;
  839 +
  840 + farg.ll = arg;
  841 + farg.d = float64_abs(farg.d);
  842 + farg.d = float64_chs(farg.d);
  843 + return farg.ll;
  844 +}
  845 +
  846 +/* fneg */
  847 +uint64_t helper_fneg (uint64_t arg)
  848 +{
  849 + CPU_DoubleU farg;
  850 +
  851 + farg.ll = arg;
  852 + farg.d = float64_chs(farg.d);
  853 + return farg.ll;
  854 +}
  855 +
  856 +/* fctiw - fctiw. */
  857 +uint64_t helper_fctiw (uint64_t arg)
  858 +{
  859 + CPU_DoubleU farg;
  860 + farg.ll = arg;
  861 +
  862 + if (unlikely(float64_is_signaling_nan(farg.d))) {
785 863 /* sNaN conversion */
786   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
787   - } else if (unlikely(float64_is_nan(FT0) || isinfinity(FT0))) {
  864 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
  865 + } else if (unlikely(float64_is_nan(farg.d) || isinfinity(farg.d))) {
788 866 /* qNan / infinity conversion */
789   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
  867 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
790 868 } else {
791   - p.ll = float64_to_int32(FT0, &env->fp_status);
  869 + farg.ll = float64_to_int32(farg.d, &env->fp_status);
792 870 #if USE_PRECISE_EMULATION
793 871 /* XXX: higher bits are not supposed to be significant.
794 872 * to make tests easier, return the same as a real PowerPC 750
795 873 */
796   - p.ll |= 0xFFF80000ULL << 32;
  874 + farg.ll |= 0xFFF80000ULL << 32;
797 875 #endif
798   - FT0 = p.d;
799 876 }
  877 + return farg.ll;
800 878 }
801 879  
802   -void do_fctiwz (void)
  880 +/* fctiwz - fctiwz. */
  881 +uint64_t helper_fctiwz (uint64_t arg)
803 882 {
804   - CPU_DoubleU p;
  883 + CPU_DoubleU farg;
  884 + farg.ll = arg;
805 885  
806   - if (unlikely(float64_is_signaling_nan(FT0))) {
  886 + if (unlikely(float64_is_signaling_nan(farg.d))) {
807 887 /* sNaN conversion */
808   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
809   - } else if (unlikely(float64_is_nan(FT0) || isinfinity(FT0))) {
  888 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
  889 + } else if (unlikely(float64_is_nan(farg.d) || isinfinity(farg.d))) {
810 890 /* qNan / infinity conversion */
811   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
  891 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
812 892 } else {
813   - p.ll = float64_to_int32_round_to_zero(FT0, &env->fp_status);
  893 + farg.ll = float64_to_int32_round_to_zero(farg.d, &env->fp_status);
814 894 #if USE_PRECISE_EMULATION
815 895 /* XXX: higher bits are not supposed to be significant.
816 896 * to make tests easier, return the same as a real PowerPC 750
817 897 */
818   - p.ll |= 0xFFF80000ULL << 32;
  898 + farg.ll |= 0xFFF80000ULL << 32;
819 899 #endif
820   - FT0 = p.d;
821 900 }
  901 + return farg.ll;
822 902 }
823 903  
824 904 #if defined(TARGET_PPC64)
825   -void do_fcfid (void)
  905 +/* fcfid - fcfid. */
  906 +uint64_t helper_fcfid (uint64_t arg)
826 907 {
827   - CPU_DoubleU p;
828   -
829   - p.d = FT0;
830   - FT0 = int64_to_float64(p.ll, &env->fp_status);
  908 + CPU_DoubleU farg;
  909 + farg.d = int64_to_float64(arg, &env->fp_status);
  910 + return farg.ll;
831 911 }
832 912  
833   -void do_fctid (void)
  913 +/* fctid - fctid. */
  914 +uint64_t helper_fctid (uint64_t arg)
834 915 {
835   - CPU_DoubleU p;
  916 + CPU_DoubleU farg;
  917 + farg.ll = arg;
836 918  
837   - if (unlikely(float64_is_signaling_nan(FT0))) {
  919 + if (unlikely(float64_is_signaling_nan(farg.d))) {
838 920 /* sNaN conversion */
839   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
840   - } else if (unlikely(float64_is_nan(FT0) || isinfinity(FT0))) {
  921 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
  922 + } else if (unlikely(float64_is_nan(farg.d) || isinfinity(farg.d))) {
841 923 /* qNan / infinity conversion */
842   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
  924 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
843 925 } else {
844   - p.ll = float64_to_int64(FT0, &env->fp_status);
845   - FT0 = p.d;
  926 + farg.ll = float64_to_int64(farg.d, &env->fp_status);
846 927 }
  928 + return farg.ll;
847 929 }
848 930  
849   -void do_fctidz (void)
  931 +/* fctidz - fctidz. */
  932 +uint64_t helper_fctidz (uint64_t arg)
850 933 {
851   - CPU_DoubleU p;
  934 + CPU_DoubleU farg;
  935 + farg.ll = arg;
852 936  
853   - if (unlikely(float64_is_signaling_nan(FT0))) {
  937 + if (unlikely(float64_is_signaling_nan(farg.d))) {
854 938 /* sNaN conversion */
855   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
856   - } else if (unlikely(float64_is_nan(FT0) || isinfinity(FT0))) {
  939 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
  940 + } else if (unlikely(float64_is_nan(farg.d) || isinfinity(farg.d))) {
857 941 /* qNan / infinity conversion */
858   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
  942 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
859 943 } else {
860   - p.ll = float64_to_int64_round_to_zero(FT0, &env->fp_status);
861   - FT0 = p.d;
  944 + farg.ll = float64_to_int64_round_to_zero(farg.d, &env->fp_status);
862 945 }
  946 + return farg.ll;
863 947 }
864 948  
865 949 #endif
866 950  
867   -static always_inline void do_fri (int rounding_mode)
  951 +static always_inline uint64_t do_fri (uint64_t arg, int rounding_mode)
868 952 {
869   - if (unlikely(float64_is_signaling_nan(FT0))) {
  953 + CPU_DoubleU farg;
  954 + farg.ll = arg;
  955 +
  956 + if (unlikely(float64_is_signaling_nan(farg.d))) {
870 957 /* sNaN round */
871   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
872   - } else if (unlikely(float64_is_nan(FT0) || isinfinity(FT0))) {
  958 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);
  959 + } else if (unlikely(float64_is_nan(farg.d) || isinfinity(farg.d))) {
873 960 /* qNan / infinity round */
874   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
  961 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
875 962 } else {
876 963 set_float_rounding_mode(rounding_mode, &env->fp_status);
877   - FT0 = float64_round_to_int(FT0, &env->fp_status);
  964 + farg.ll = float64_round_to_int(farg.d, &env->fp_status);
878 965 /* Restore rounding mode from FPSCR */
879 966 fpscr_set_rounding_mode();
880 967 }
  968 + return farg.ll;
881 969 }
882 970  
883   -void do_frin (void)
  971 +uint64_t helper_frin (uint64_t arg)
884 972 {
885   - do_fri(float_round_nearest_even);
  973 + return do_fri(arg, float_round_nearest_even);
886 974 }
887 975  
888   -void do_friz (void)
  976 +uint64_t helper_friz (uint64_t arg)
889 977 {
890   - do_fri(float_round_to_zero);
  978 + return do_fri(arg, float_round_to_zero);
891 979 }
892 980  
893   -void do_frip (void)
  981 +uint64_t helper_frip (uint64_t arg)
894 982 {
895   - do_fri(float_round_up);
  983 + return do_fri(arg, float_round_up);
896 984 }
897 985  
898   -void do_frim (void)
  986 +uint64_t helper_frim (uint64_t arg)
899 987 {
900   - do_fri(float_round_down);
  988 + return do_fri(arg, float_round_down);
901 989 }
902 990  
903   -#if USE_PRECISE_EMULATION
904   -void do_fmadd (void)
  991 +/* fmadd - fmadd. */
  992 +uint64_t helper_fmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3)
905 993 {
906   - if (unlikely(float64_is_signaling_nan(FT0) ||
907   - float64_is_signaling_nan(FT1) ||
908   - float64_is_signaling_nan(FT2))) {
  994 + CPU_DoubleU farg1, farg2, farg3;
  995 +
  996 + farg1.ll = arg1;
  997 + farg2.ll = arg2;
  998 + farg3.ll = arg3;
  999 +#if USE_PRECISE_EMULATION
  1000 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  1001 + float64_is_signaling_nan(farg2.d) ||
  1002 + float64_is_signaling_nan(farg3.d))) {
909 1003 /* sNaN operation */
910   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1004 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
911 1005 } else {
912 1006 #ifdef FLOAT128
913 1007 /* This is the way the PowerPC specification defines it */
914 1008 float128 ft0_128, ft1_128;
915 1009  
916   - ft0_128 = float64_to_float128(FT0, &env->fp_status);
917   - ft1_128 = float64_to_float128(FT1, &env->fp_status);
  1010 + ft0_128 = float64_to_float128(farg1.d, &env->fp_status);
  1011 + ft1_128 = float64_to_float128(farg2.d, &env->fp_status);
918 1012 ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
919   - ft1_128 = float64_to_float128(FT2, &env->fp_status);
  1013 + ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
920 1014 ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
921   - FT0 = float128_to_float64(ft0_128, &env->fp_status);
  1015 + farg1.d = float128_to_float64(ft0_128, &env->fp_status);
922 1016 #else
923 1017 /* This is OK on x86 hosts */
924   - FT0 = (FT0 * FT1) + FT2;
  1018 + farg1.d = (farg1.d * farg2.d) + farg3.d;
925 1019 #endif
926 1020 }
  1021 +#else
  1022 + farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
  1023 + farg1.d = float64_add(farg1.d, farg3.d, &env->fp_status);
  1024 +#endif
  1025 + return farg1.ll;
927 1026 }
928 1027  
929   -void do_fmsub (void)
  1028 +/* fmsub - fmsub. */
  1029 +uint64_t helper_fmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)
930 1030 {
931   - if (unlikely(float64_is_signaling_nan(FT0) ||
932   - float64_is_signaling_nan(FT1) ||
933   - float64_is_signaling_nan(FT2))) {
  1031 + CPU_DoubleU farg1, farg2, farg3;
  1032 +
  1033 + farg1.ll = arg1;
  1034 + farg2.ll = arg2;
  1035 + farg3.ll = arg3;
  1036 +#if USE_PRECISE_EMULATION
  1037 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  1038 + float64_is_signaling_nan(farg2.d) ||
  1039 + float64_is_signaling_nan(farg3.d))) {
934 1040 /* sNaN operation */
935   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1041 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
936 1042 } else {
937 1043 #ifdef FLOAT128
938 1044 /* This is the way the PowerPC specification defines it */
939 1045 float128 ft0_128, ft1_128;
940 1046  
941   - ft0_128 = float64_to_float128(FT0, &env->fp_status);
942   - ft1_128 = float64_to_float128(FT1, &env->fp_status);
  1047 + ft0_128 = float64_to_float128(farg1.d, &env->fp_status);
  1048 + ft1_128 = float64_to_float128(farg2.d, &env->fp_status);
943 1049 ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
944   - ft1_128 = float64_to_float128(FT2, &env->fp_status);
  1050 + ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
945 1051 ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
946   - FT0 = float128_to_float64(ft0_128, &env->fp_status);
  1052 + farg1.d = float128_to_float64(ft0_128, &env->fp_status);
947 1053 #else
948 1054 /* This is OK on x86 hosts */
949   - FT0 = (FT0 * FT1) - FT2;
  1055 + farg1.d = (farg1.d * farg2.d) - farg3.d;
950 1056 #endif
951 1057 }
  1058 +#else
  1059 + farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
  1060 + farg1.d = float64_sub(farg1.d, farg3.d, &env->fp_status);
  1061 +#endif
  1062 + return farg1.ll;
952 1063 }
953   -#endif /* USE_PRECISE_EMULATION */
954 1064  
955   -void do_fnmadd (void)
  1065 +/* fnmadd - fnmadd. */
  1066 +uint64_t helper_fnmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3)
956 1067 {
957   - if (unlikely(float64_is_signaling_nan(FT0) ||
958   - float64_is_signaling_nan(FT1) ||
959   - float64_is_signaling_nan(FT2))) {
  1068 + CPU_DoubleU farg1, farg2, farg3;
  1069 +
  1070 + farg1.ll = arg1;
  1071 + farg2.ll = arg2;
  1072 + farg3.ll = arg3;
  1073 +
  1074 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  1075 + float64_is_signaling_nan(farg2.d) ||
  1076 + float64_is_signaling_nan(farg3.d))) {
960 1077 /* sNaN operation */
961   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1078 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
962 1079 } else {
963 1080 #if USE_PRECISE_EMULATION
964 1081 #ifdef FLOAT128
965 1082 /* This is the way the PowerPC specification defines it */
966 1083 float128 ft0_128, ft1_128;
967 1084  
968   - ft0_128 = float64_to_float128(FT0, &env->fp_status);
969   - ft1_128 = float64_to_float128(FT1, &env->fp_status);
  1085 + ft0_128 = float64_to_float128(farg1.d, &env->fp_status);
  1086 + ft1_128 = float64_to_float128(farg2.d, &env->fp_status);
970 1087 ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
971   - ft1_128 = float64_to_float128(FT2, &env->fp_status);
  1088 + ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
972 1089 ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
973   - FT0 = float128_to_float64(ft0_128, &env->fp_status);
  1090 + farg1.d= float128_to_float64(ft0_128, &env->fp_status);
974 1091 #else
975 1092 /* This is OK on x86 hosts */
976   - FT0 = (FT0 * FT1) + FT2;
  1093 + farg1.d = (farg1.d * farg2.d) + farg3.d;
977 1094 #endif
978 1095 #else
979   - FT0 = float64_mul(FT0, FT1, &env->fp_status);
980   - FT0 = float64_add(FT0, FT2, &env->fp_status);
  1096 + farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
  1097 + farg1.d = float64_add(farg1.d, farg3.d, &env->fp_status);
981 1098 #endif
982   - if (likely(!isnan(FT0)))
983   - FT0 = float64_chs(FT0);
  1099 + if (likely(!isnan(farg1.d)))
  1100 + farg1.d = float64_chs(farg1.d);
984 1101 }
  1102 + return farg1.ll;
985 1103 }
986 1104  
987   -void do_fnmsub (void)
  1105 +/* fnmsub - fnmsub. */
  1106 +uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)
988 1107 {
989   - if (unlikely(float64_is_signaling_nan(FT0) ||
990   - float64_is_signaling_nan(FT1) ||
991   - float64_is_signaling_nan(FT2))) {
  1108 + CPU_DoubleU farg1, farg2, farg3;
  1109 +
  1110 + farg1.ll = arg1;
  1111 + farg2.ll = arg2;
  1112 + farg3.ll = arg3;
  1113 +
  1114 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  1115 + float64_is_signaling_nan(farg2.d) ||
  1116 + float64_is_signaling_nan(farg3.d))) {
992 1117 /* sNaN operation */
993   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1118 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
994 1119 } else {
995 1120 #if USE_PRECISE_EMULATION
996 1121 #ifdef FLOAT128
997 1122 /* This is the way the PowerPC specification defines it */
998 1123 float128 ft0_128, ft1_128;
999 1124  
1000   - ft0_128 = float64_to_float128(FT0, &env->fp_status);
1001   - ft1_128 = float64_to_float128(FT1, &env->fp_status);
  1125 + ft0_128 = float64_to_float128(farg1.d, &env->fp_status);
  1126 + ft1_128 = float64_to_float128(farg2.d, &env->fp_status);
1002 1127 ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
1003   - ft1_128 = float64_to_float128(FT2, &env->fp_status);
  1128 + ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
1004 1129 ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
1005   - FT0 = float128_to_float64(ft0_128, &env->fp_status);
  1130 + farg1.d = float128_to_float64(ft0_128, &env->fp_status);
1006 1131 #else
1007 1132 /* This is OK on x86 hosts */
1008   - FT0 = (FT0 * FT1) - FT2;
  1133 + farg1.d = (farg1.d * farg2.d) - farg3.d;
1009 1134 #endif
1010 1135 #else
1011   - FT0 = float64_mul(FT0, FT1, &env->fp_status);
1012   - FT0 = float64_sub(FT0, FT2, &env->fp_status);
  1136 + farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
  1137 + farg1.d = float64_sub(farg1.d, farg3.d, &env->fp_status);
1013 1138 #endif
1014   - if (likely(!isnan(FT0)))
1015   - FT0 = float64_chs(FT0);
  1139 + if (likely(!isnan(farg1.d)))
  1140 + farg1.d = float64_chs(farg1.d);
1016 1141 }
  1142 + return farg1.ll;
1017 1143 }
1018 1144  
1019   -#if USE_PRECISE_EMULATION
1020   -void do_frsp (void)
  1145 +
  1146 +/* frsp - frsp. */
  1147 +uint64_t helper_frsp (uint64_t arg)
1021 1148 {
1022   - if (unlikely(float64_is_signaling_nan(FT0))) {
  1149 + CPU_DoubleU farg;
  1150 + farg.ll = arg;
  1151 +
  1152 +#if USE_PRECISE_EMULATION
  1153 + if (unlikely(float64_is_signaling_nan(farg.d))) {
1023 1154 /* sNaN square root */
1024   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1155 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
1025 1156 } else {
1026   - FT0 = float64_to_float32(FT0, &env->fp_status);
  1157 + fard.d = float64_to_float32(farg.d, &env->fp_status);
1027 1158 }
  1159 +#else
  1160 + farg.d = float64_to_float32(farg.d, &env->fp_status);
  1161 +#endif
  1162 + return farg.ll;
1028 1163 }
1029   -#endif /* USE_PRECISE_EMULATION */
1030 1164  
1031   -void do_fsqrt (void)
  1165 +/* fsqrt - fsqrt. */
  1166 +uint64_t helper_fsqrt (uint64_t arg)
1032 1167 {
1033   - if (unlikely(float64_is_signaling_nan(FT0))) {
  1168 + CPU_DoubleU farg;
  1169 + farg.ll = arg;
  1170 +
  1171 + if (unlikely(float64_is_signaling_nan(farg.d))) {
1034 1172 /* sNaN square root */
1035   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
1036   - } else if (unlikely(fpisneg(FT0) && !iszero(FT0))) {
  1173 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1174 + } else if (unlikely(fpisneg(farg.d) && !iszero(farg.d))) {
1037 1175 /* Square root of a negative nonzero number */
1038   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSQRT);
  1176 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSQRT);
1039 1177 } else {
1040   - FT0 = float64_sqrt(FT0, &env->fp_status);
  1178 + farg.d = float64_sqrt(farg.d, &env->fp_status);
1041 1179 }
  1180 + return farg.ll;
1042 1181 }
1043 1182  
1044   -void do_fre (void)
  1183 +/* fre - fre. */
  1184 +uint64_t helper_fre (uint64_t arg)
1045 1185 {
1046   - CPU_DoubleU p;
  1186 + CPU_DoubleU farg;
  1187 + farg.ll = arg;
1047 1188  
1048   - if (unlikely(float64_is_signaling_nan(FT0))) {
  1189 + if (unlikely(float64_is_signaling_nan(farg.d))) {
1049 1190 /* sNaN reciprocal */
1050   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
1051   - } else if (unlikely(iszero(FT0))) {
  1191 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1192 + } else if (unlikely(iszero(farg.d))) {
1052 1193 /* Zero reciprocal */
1053   - float_zero_divide_excp();
1054   - } else if (likely(isnormal(FT0))) {
1055   - FT0 = float64_div(1.0, FT0, &env->fp_status);
  1194 + farg.ll = float_zero_divide_excp(1.0, farg.d);
  1195 + } else if (likely(isnormal(farg.d))) {
  1196 + farg.d = float64_div(1.0, farg.d, &env->fp_status);
1056 1197 } else {
1057   - p.d = FT0;
1058   - if (p.ll == 0x8000000000000000ULL) {
1059   - p.ll = 0xFFF0000000000000ULL;
1060   - } else if (p.ll == 0x0000000000000000ULL) {
1061   - p.ll = 0x7FF0000000000000ULL;
1062   - } else if (isnan(FT0)) {
1063   - p.ll = 0x7FF8000000000000ULL;
1064   - } else if (fpisneg(FT0)) {
1065   - p.ll = 0x8000000000000000ULL;
  1198 + if (farg.ll == 0x8000000000000000ULL) {
  1199 + farg.ll = 0xFFF0000000000000ULL;
  1200 + } else if (farg.ll == 0x0000000000000000ULL) {
  1201 + farg.ll = 0x7FF0000000000000ULL;
  1202 + } else if (isnan(farg.d)) {
  1203 + farg.ll = 0x7FF8000000000000ULL;
  1204 + } else if (fpisneg(farg.d)) {
  1205 + farg.ll = 0x8000000000000000ULL;
1066 1206 } else {
1067   - p.ll = 0x0000000000000000ULL;
  1207 + farg.ll = 0x0000000000000000ULL;
1068 1208 }
1069   - FT0 = p.d;
1070 1209 }
  1210 + return farg.d;
1071 1211 }
1072 1212  
1073   -void do_fres (void)
  1213 +/* fres - fres. */
  1214 +uint64_t helper_fres (uint64_t arg)
1074 1215 {
1075   - CPU_DoubleU p;
  1216 + CPU_DoubleU farg;
  1217 + farg.ll = arg;
1076 1218  
1077   - if (unlikely(float64_is_signaling_nan(FT0))) {
  1219 + if (unlikely(float64_is_signaling_nan(farg.d))) {
1078 1220 /* sNaN reciprocal */
1079   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
1080   - } else if (unlikely(iszero(FT0))) {
  1221 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1222 + } else if (unlikely(iszero(farg.d))) {
1081 1223 /* Zero reciprocal */
1082   - float_zero_divide_excp();
1083   - } else if (likely(isnormal(FT0))) {
  1224 + farg.ll = float_zero_divide_excp(1.0, farg.d);
  1225 + } else if (likely(isnormal(farg.d))) {
1084 1226 #if USE_PRECISE_EMULATION
1085   - FT0 = float64_div(1.0, FT0, &env->fp_status);
1086   - FT0 = float64_to_float32(FT0, &env->fp_status);
  1227 + farg.d = float64_div(1.0, farg.d, &env->fp_status);
  1228 + farg.d = float64_to_float32(farg.d, &env->fp_status);
1087 1229 #else
1088   - FT0 = float32_div(1.0, FT0, &env->fp_status);
  1230 + farg.d = float32_div(1.0, farg.d, &env->fp_status);
1089 1231 #endif
1090 1232 } else {
1091   - p.d = FT0;
1092   - if (p.ll == 0x8000000000000000ULL) {
1093   - p.ll = 0xFFF0000000000000ULL;
1094   - } else if (p.ll == 0x0000000000000000ULL) {
1095   - p.ll = 0x7FF0000000000000ULL;
1096   - } else if (isnan(FT0)) {
1097   - p.ll = 0x7FF8000000000000ULL;
1098   - } else if (fpisneg(FT0)) {
1099   - p.ll = 0x8000000000000000ULL;
  1233 + if (farg.ll == 0x8000000000000000ULL) {
  1234 + farg.ll = 0xFFF0000000000000ULL;
  1235 + } else if (farg.ll == 0x0000000000000000ULL) {
  1236 + farg.ll = 0x7FF0000000000000ULL;
  1237 + } else if (isnan(farg.d)) {
  1238 + farg.ll = 0x7FF8000000000000ULL;
  1239 + } else if (fpisneg(farg.d)) {
  1240 + farg.ll = 0x8000000000000000ULL;
1100 1241 } else {
1101   - p.ll = 0x0000000000000000ULL;
  1242 + farg.ll = 0x0000000000000000ULL;
1102 1243 }
1103   - FT0 = p.d;
1104 1244 }
  1245 + return farg.ll;
1105 1246 }
1106 1247  
1107   -void do_frsqrte (void)
  1248 +/* frsqrte - frsqrte. */
  1249 +uint64_t helper_frsqrte (uint64_t arg)
1108 1250 {
1109   - CPU_DoubleU p;
  1251 + CPU_DoubleU farg;
  1252 + farg.ll = arg;
1110 1253  
1111   - if (unlikely(float64_is_signaling_nan(FT0))) {
  1254 + if (unlikely(float64_is_signaling_nan(farg.d))) {
1112 1255 /* sNaN reciprocal square root */
1113   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
1114   - } else if (unlikely(fpisneg(FT0) && !iszero(FT0))) {
  1256 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
  1257 + } else if (unlikely(fpisneg(farg.d) && !iszero(farg.d))) {
1115 1258 /* Reciprocal square root of a negative nonzero number */
1116   - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSQRT);
1117   - } else if (likely(isnormal(FT0))) {
1118   - FT0 = float64_sqrt(FT0, &env->fp_status);
1119   - FT0 = float32_div(1.0, FT0, &env->fp_status);
  1259 + farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSQRT);
  1260 + } else if (likely(isnormal(farg.d))) {
  1261 + farg.d = float64_sqrt(farg.d, &env->fp_status);
  1262 + farg.d = float32_div(1.0, farg.d, &env->fp_status);
1120 1263 } else {
1121   - p.d = FT0;
1122   - if (p.ll == 0x8000000000000000ULL) {
1123   - p.ll = 0xFFF0000000000000ULL;
1124   - } else if (p.ll == 0x0000000000000000ULL) {
1125   - p.ll = 0x7FF0000000000000ULL;
1126   - } else if (isnan(FT0)) {
1127   - p.ll |= 0x000FFFFFFFFFFFFFULL;
1128   - } else if (fpisneg(FT0)) {
1129   - p.ll = 0x7FF8000000000000ULL;
  1264 + if (farg.ll == 0x8000000000000000ULL) {
  1265 + farg.ll = 0xFFF0000000000000ULL;
  1266 + } else if (farg.ll == 0x0000000000000000ULL) {
  1267 + farg.ll = 0x7FF0000000000000ULL;
  1268 + } else if (isnan(farg.d)) {
  1269 + farg.ll |= 0x000FFFFFFFFFFFFFULL;
  1270 + } else if (fpisneg(farg.d)) {
  1271 + farg.ll = 0x7FF8000000000000ULL;
1130 1272 } else {
1131   - p.ll = 0x0000000000000000ULL;
  1273 + farg.ll = 0x0000000000000000ULL;
1132 1274 }
1133   - FT0 = p.d;
1134 1275 }
  1276 + return farg.ll;
1135 1277 }
1136 1278  
1137   -void do_fsel (void)
  1279 +/* fsel - fsel. */
  1280 +uint64_t helper_fsel (uint64_t arg1, uint64_t arg2, uint64_t arg3)
1138 1281 {
1139   - if (!fpisneg(FT0) || iszero(FT0))
1140   - FT0 = FT1;
  1282 + CPU_DoubleU farg1, farg2, farg3;
  1283 +
  1284 + farg1.ll = arg1;
  1285 + farg2.ll = arg2;
  1286 + farg3.ll = arg3;
  1287 +
  1288 + if (!fpisneg(farg1.d) || iszero(farg1.d))
  1289 + return farg2.ll;
1141 1290 else
1142   - FT0 = FT2;
  1291 + return farg2.ll;
1143 1292 }
1144 1293  
1145   -uint32_t helper_fcmpu (void)
  1294 +uint32_t helper_fcmpu (uint64_t arg1, uint64_t arg2)
1146 1295 {
  1296 + CPU_DoubleU farg1, farg2;
1147 1297 uint32_t ret = 0;
  1298 + farg1.ll = arg1;
  1299 + farg2.ll = arg2;
1148 1300  
1149   - if (unlikely(float64_is_signaling_nan(FT0) ||
1150   - float64_is_signaling_nan(FT1))) {
  1301 + if (unlikely(float64_is_signaling_nan(farg1.d) ||
  1302 + float64_is_signaling_nan(farg2.d))) {
1151 1303 /* sNaN comparison */
1152 1304 fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
1153 1305 } else {
1154   - if (float64_lt(FT0, FT1, &env->fp_status)) {
  1306 + if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
1155 1307 ret = 0x08UL;
1156   - } else if (!float64_le(FT0, FT1, &env->fp_status)) {
  1308 + } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {
1157 1309 ret = 0x04UL;
1158 1310 } else {
1159 1311 ret = 0x02UL;
... ... @@ -1164,14 +1316,17 @@ uint32_t helper_fcmpu (void)
1164 1316 return ret;
1165 1317 }
1166 1318  
1167   -uint32_t helper_fcmpo (void)
  1319 +uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2)
1168 1320 {
  1321 + CPU_DoubleU farg1, farg2;
1169 1322 uint32_t ret = 0;
  1323 + farg1.ll = arg1;
  1324 + farg2.ll = arg2;
1170 1325  
1171   - if (unlikely(float64_is_nan(FT0) ||
1172   - float64_is_nan(FT1))) {
1173   - if (float64_is_signaling_nan(FT0) ||
1174   - float64_is_signaling_nan(FT1)) {
  1326 + if (unlikely(float64_is_nan(farg1.d) ||
  1327 + float64_is_nan(farg2.d))) {
  1328 + if (float64_is_signaling_nan(farg1.d) ||
  1329 + float64_is_signaling_nan(farg2.d)) {
1175 1330 /* sNaN comparison */
1176 1331 fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN |
1177 1332 POWERPC_EXCP_FP_VXVC);
... ... @@ -1180,9 +1335,9 @@ uint32_t helper_fcmpo (void)
1180 1335 fload_invalid_op_excp(POWERPC_EXCP_FP_VXVC);
1181 1336 }
1182 1337 } else {
1183   - if (float64_lt(FT0, FT1, &env->fp_status)) {
  1338 + if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
1184 1339 ret = 0x08UL;
1185   - } else if (!float64_le(FT0, FT1, &env->fp_status)) {
  1340 + } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {
1186 1341 ret = 0x04UL;
1187 1342 } else {
1188 1343 ret = 0x02UL;
... ...
target-ppc/translate.c
... ... @@ -75,7 +75,7 @@ static TCGv cpu_T[3];
75 75 #else
76 76 static TCGv_i64 cpu_T64[3];
77 77 #endif
78   -static TCGv_i64 cpu_FT[3];
  78 +static TCGv_i64 cpu_FT[2];
79 79 static TCGv_i64 cpu_AVRh[3], cpu_AVRl[3];
80 80  
81 81 #include "gen-icount.h"
... ... @@ -120,8 +120,6 @@ void ppc_translate_init(void)
120 120 offsetof(CPUState, ft0), "FT0");
121 121 cpu_FT[1] = tcg_global_mem_new_i64(TCG_AREG0,
122 122 offsetof(CPUState, ft1), "FT1");
123   - cpu_FT[2] = tcg_global_mem_new_i64(TCG_AREG0,
124   - offsetof(CPUState, ft2), "FT2");
125 123  
126 124 cpu_AVRh[0] = tcg_global_mem_new_i64(TCG_AREG0,
127 125 offsetof(CPUState, avr0.u64[0]), "AVR0H");
... ... @@ -245,27 +243,31 @@ static always_inline void gen_reset_fpstatus (void)
245 243 #endif
246 244 }
247 245  
248   -static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
  246 +static always_inline void gen_compute_fprf (TCGv arg, int set_fprf, int set_rc)
249 247 {
  248 + TCGv t0 = tcg_temp_new_i32();
  249 +
250 250 if (set_fprf != 0) {
251 251 /* This case might be optimized later */
252 252 #if defined(OPTIMIZE_FPRF_UPDATE)
253 253 *gen_fprf_ptr++ = gen_opc_ptr;
254 254 #endif
255   - gen_op_compute_fprf(1);
  255 + tcg_gen_movi_tl(t0, 1);
  256 + gen_helper_compute_fprf(t0, arg, t0);
256 257 if (unlikely(set_rc)) {
257   - tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_T[0]);
258   - tcg_gen_andi_i32(cpu_crf[1], cpu_crf[1], 0xf);
  258 + tcg_gen_movi_i32(cpu_crf[1], t0);
259 259 }
260   - gen_op_float_check_status();
  260 + gen_helper_float_check_status();
261 261 } else if (unlikely(set_rc)) {
262 262 /* We always need to compute fpcc */
263   - gen_op_compute_fprf(0);
264   - tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_T[0]);
265   - tcg_gen_andi_i32(cpu_crf[1], cpu_crf[1], 0xf);
  263 + tcg_gen_movi_tl(t0, 0);
  264 + gen_helper_compute_fprf(t0, arg, t0);
  265 + tcg_gen_movi_i32(cpu_crf[1], t0);
266 266 if (set_fprf)
267   - gen_op_float_check_status();
  267 + gen_helper_float_check_status();
268 268 }
  269 +
  270 + tcg_temp_free(t0);
269 271 }
270 272  
271 273 static always_inline void gen_optimize_fprf (void)
... ... @@ -2096,16 +2098,14 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \
2096 2098 GEN_EXCP_NO_FP(ctx); \
2097 2099 return; \
2098 2100 } \
2099   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]); \
2100   - tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]); \
2101   - tcg_gen_mov_i64(cpu_FT[2], cpu_fpr[rB(ctx->opcode)]); \
2102 2101 gen_reset_fpstatus(); \
2103   - gen_op_f##op(); \
  2102 + gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)], \
  2103 + cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \
2104 2104 if (isfloat) { \
2105   - gen_op_frsp(); \
  2105 + gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]); \
2106 2106 } \
2107   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]); \
2108   - gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0); \
  2107 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf, \
  2108 + Rc(ctx->opcode) != 0); \
2109 2109 }
2110 2110  
2111 2111 #define GEN_FLOAT_ACB(name, op2, set_fprf, type) \
... ... @@ -2119,15 +2119,14 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \
2119 2119 GEN_EXCP_NO_FP(ctx); \
2120 2120 return; \
2121 2121 } \
2122   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]); \
2123   - tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]); \
2124 2122 gen_reset_fpstatus(); \
2125   - gen_op_f##op(); \
  2123 + gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)], \
  2124 + cpu_fpr[rB(ctx->opcode)]); \
2126 2125 if (isfloat) { \
2127   - gen_op_frsp(); \
  2126 + gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]); \
2128 2127 } \
2129   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]); \
2130   - gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0); \
  2128 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], \
  2129 + set_fprf, Rc(ctx->opcode) != 0); \
2131 2130 }
2132 2131 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type) \
2133 2132 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type); \
... ... @@ -2140,15 +2139,14 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \
2140 2139 GEN_EXCP_NO_FP(ctx); \
2141 2140 return; \
2142 2141 } \
2143   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]); \
2144   - tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]); \
2145 2142 gen_reset_fpstatus(); \
2146   - gen_op_f##op(); \
  2143 + gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)], \
  2144 + cpu_fpr[rC(ctx->opcode)]); \
2147 2145 if (isfloat) { \
2148   - gen_op_frsp(); \
  2146 + gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]); \
2149 2147 } \
2150   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]); \
2151   - gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0); \
  2148 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], \
  2149 + set_fprf, Rc(ctx->opcode) != 0); \
2152 2150 }
2153 2151 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type) \
2154 2152 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type); \
... ... @@ -2161,11 +2159,10 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \
2161 2159 GEN_EXCP_NO_FP(ctx); \
2162 2160 return; \
2163 2161 } \
2164   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]); \
2165 2162 gen_reset_fpstatus(); \
2166   - gen_op_f##name(); \
2167   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]); \
2168   - gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0); \
  2163 + gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \
  2164 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], \
  2165 + set_fprf, Rc(ctx->opcode) != 0); \
2169 2166 }
2170 2167  
2171 2168 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type) \
... ... @@ -2175,11 +2172,10 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type) \
2175 2172 GEN_EXCP_NO_FP(ctx); \
2176 2173 return; \
2177 2174 } \
2178   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]); \
2179 2175 gen_reset_fpstatus(); \
2180   - gen_op_f##name(); \
2181   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]); \
2182   - gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0); \
  2176 + gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \
  2177 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], \
  2178 + set_fprf, Rc(ctx->opcode) != 0); \
2183 2179 }
2184 2180  
2185 2181 /* fadd - fadds */
... ... @@ -2199,12 +2195,17 @@ GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2199 2195 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2200 2196  
2201 2197 /* frsqrtes */
2202   -static always_inline void gen_op_frsqrtes (void)
  2198 +GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES)
2203 2199 {
2204   - gen_op_frsqrte();
2205   - gen_op_frsp();
  2200 + if (unlikely(!ctx->fpu_enabled)) {
  2201 + GEN_EXCP_NO_FP(ctx);
  2202 + return;
  2203 + }
  2204 + gen_reset_fpstatus();
  2205 + gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
  2206 + gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
  2207 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2206 2208 }
2207   -GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
2208 2209  
2209 2210 /* fsel */
2210 2211 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
... ... @@ -2218,11 +2219,9 @@ GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
2218 2219 GEN_EXCP_NO_FP(ctx);
2219 2220 return;
2220 2221 }
2221   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2222 2222 gen_reset_fpstatus();
2223   - gen_op_fsqrt();
2224   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2225   - gen_compute_fprf(1, Rc(ctx->opcode) != 0);
  2223 + gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
  2224 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2226 2225 }
2227 2226  
2228 2227 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
... ... @@ -2231,12 +2230,10 @@ GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
2231 2230 GEN_EXCP_NO_FP(ctx);
2232 2231 return;
2233 2232 }
2234   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2235 2233 gen_reset_fpstatus();
2236   - gen_op_fsqrt();
2237   - gen_op_frsp();
2238   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2239   - gen_compute_fprf(1, Rc(ctx->opcode) != 0);
  2234 + gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
  2235 + gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
  2236 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2240 2237 }
2241 2238  
2242 2239 /*** Floating-Point multiply-and-add ***/
... ... @@ -2282,11 +2279,10 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
2282 2279 GEN_EXCP_NO_FP(ctx);
2283 2280 return;
2284 2281 }
2285   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
2286   - tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
2287 2282 gen_reset_fpstatus();
2288   - gen_helper_fcmpo(cpu_crf[crfD(ctx->opcode)]);
2289   - gen_op_float_check_status();
  2283 + gen_helper_fcmpo(cpu_crf[crfD(ctx->opcode)],
  2284 + cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
  2285 + gen_helper_float_check_status();
2290 2286 }
2291 2287  
2292 2288 /* fcmpu */
... ... @@ -2296,11 +2292,10 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
2296 2292 GEN_EXCP_NO_FP(ctx);
2297 2293 return;
2298 2294 }
2299   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
2300   - tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
2301 2295 gen_reset_fpstatus();
2302   - gen_helper_fcmpu(cpu_crf[crfD(ctx->opcode)]);
2303   - gen_op_float_check_status();
  2296 + gen_helper_fcmpu(cpu_crf[crfD(ctx->opcode)],
  2297 + cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
  2298 + gen_helper_float_check_status();
2304 2299 }
2305 2300  
2306 2301 /*** Floating-point move ***/
... ... @@ -2316,9 +2311,8 @@ GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
2316 2311 GEN_EXCP_NO_FP(ctx);
2317 2312 return;
2318 2313 }
2319   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2320   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2321   - gen_compute_fprf(0, Rc(ctx->opcode) != 0);
  2314 + tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
  2315 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2322 2316 }
2323 2317  
2324 2318 /* fnabs */
... ... @@ -2342,7 +2336,7 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
2342 2336 bfa = 4 * (7 - crfS(ctx->opcode));
2343 2337 tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
2344 2338 tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2345   - gen_op_fpscr_resetbit(~(0xF << bfa));
  2339 + tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
2346 2340 }
2347 2341  
2348 2342 /* mffs */
... ... @@ -2354,9 +2348,8 @@ GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2354 2348 }
2355 2349 gen_optimize_fprf();
2356 2350 gen_reset_fpstatus();
2357   - gen_op_load_fpscr_FT0();
2358   - tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2359   - gen_compute_fprf(0, Rc(ctx->opcode) != 0);
  2351 + tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
  2352 + gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2360 2353 }
2361 2354  
2362 2355 /* mtfsb0 */
... ... @@ -2372,7 +2365,7 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2372 2365 gen_optimize_fprf();
2373 2366 gen_reset_fpstatus();
2374 2367 if (likely(crb != 30 && crb != 29))
2375   - gen_op_fpscr_resetbit(~(1 << crb));
  2368 + tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(1 << crb));
2376 2369 if (unlikely(Rc(ctx->opcode) != 0)) {
2377 2370 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2378 2371 }
... ... @@ -2391,37 +2384,44 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2391 2384 gen_optimize_fprf();
2392 2385 gen_reset_fpstatus();
2393 2386 /* XXX: we pretend we can only do IEEE floating-point computations */
2394   - if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2395   - gen_op_fpscr_setbit(crb);
  2387 + if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
  2388 + TCGv t0 = tcg_const_tl(crb);
  2389 + gen_helper_fpscr_setbit(t0);
  2390 + tcg_temp_free(t0);
  2391 + }
2396 2392 if (unlikely(Rc(ctx->opcode) != 0)) {
2397 2393 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2398 2394 }
2399 2395 /* We can raise a differed exception */
2400   - gen_op_float_check_status();
  2396 + gen_helper_float_check_status();
2401 2397 }
2402 2398  
2403 2399 /* mtfsf */
2404 2400 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2405 2401 {
  2402 + TCGv t0;
  2403 +
2406 2404 if (unlikely(!ctx->fpu_enabled)) {
2407 2405 GEN_EXCP_NO_FP(ctx);
2408 2406 return;
2409 2407 }
2410 2408 gen_optimize_fprf();
2411   - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2412 2409 gen_reset_fpstatus();
2413   - gen_op_store_fpscr(FM(ctx->opcode));
  2410 + t0 = tcg_const_i32(FM(ctx->opcode));
  2411 + gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
  2412 + tcg_temp_free(t0);
2414 2413 if (unlikely(Rc(ctx->opcode) != 0)) {
2415 2414 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2416 2415 }
2417 2416 /* We can raise a differed exception */
2418   - gen_op_float_check_status();
  2417 + gen_helper_float_check_status();
2419 2418 }
2420 2419  
2421 2420 /* mtfsfi */
2422 2421 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2423 2422 {
2424 2423 int bf, sh;
  2424 + TCGv t0, t1;
2425 2425  
2426 2426 if (unlikely(!ctx->fpu_enabled)) {
2427 2427 GEN_EXCP_NO_FP(ctx);
... ... @@ -2430,14 +2430,17 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2430 2430 bf = crbD(ctx->opcode) >> 2;
2431 2431 sh = 7 - bf;
2432 2432 gen_optimize_fprf();
2433   - tcg_gen_movi_i64(cpu_FT[0], FPIMM(ctx->opcode) << (4 * sh));
2434 2433 gen_reset_fpstatus();
2435   - gen_op_store_fpscr(1 << sh);
  2434 + t0 = tcg_const_tl(FPIMM(ctx->opcode) << (4 * sh));
  2435 + t1 = tcg_const_i32(1 << sh);
  2436 + gen_helper_store_fpscr(t0, t1);
  2437 + tcg_temp_free(t0);
  2438 + tcg_temp_free(t1);
2436 2439 if (unlikely(Rc(ctx->opcode) != 0)) {
2437 2440 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2438 2441 }
2439 2442 /* We can raise a differed exception */
2440   - gen_op_float_check_status();
  2443 + gen_helper_float_check_status();
2441 2444 }
2442 2445  
2443 2446 /*** Addressing modes ***/
... ...