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,7 +571,6 @@ struct CPUPPCState {
571 /* temporary float registers */ 571 /* temporary float registers */
572 float64 ft0; 572 float64 ft0;
573 float64 ft1; 573 float64 ft1;
574 - float64 ft2;  
575 float_status fp_status; 574 float_status fp_status;
576 /* floating point registers */ 575 /* floating point registers */
577 float64 fpr[32]; 576 float64 fpr[32];
target-ppc/exec.h
@@ -61,7 +61,6 @@ register target_ulong T2 asm(AREG3); @@ -61,7 +61,6 @@ register target_ulong T2 asm(AREG3);
61 61
62 #define FT0 (env->ft0) 62 #define FT0 (env->ft0)
63 #define FT1 (env->ft1) 63 #define FT1 (env->ft1)
64 -#define FT2 (env->ft2)  
65 64
66 #if defined (DEBUG_OP) 65 #if defined (DEBUG_OP)
67 # define RETURN() __asm__ __volatile__("nop" : : : "memory"); 66 # define RETURN() __asm__ __volatile__("nop" : : : "memory");
target-ppc/helper.h
1 #include "def-helper.h" 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 DEF_HELPER_0(load_cr, tl) 6 DEF_HELPER_0(load_cr, tl)
7 DEF_HELPER_2(store_cr, void, tl, i32) 7 DEF_HELPER_2(store_cr, void, tl, i32)
@@ -25,4 +25,42 @@ DEF_HELPER_1(cntlsw32, i32, i32) @@ -25,4 +25,42 @@ DEF_HELPER_1(cntlsw32, i32, i32)
25 DEF_HELPER_1(cntlzw32, i32, i32) 25 DEF_HELPER_1(cntlzw32, i32, i32)
26 DEF_HELPER_2(brinc, tl, tl, tl) 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 #include "def-helper.h" 66 #include "def-helper.h"
target-ppc/op.c
@@ -261,71 +261,6 @@ void OPPROTO op_store_dbatl (void) @@ -261,71 +261,6 @@ void OPPROTO op_store_dbatl (void)
261 } 261 }
262 #endif /* !defined(CONFIG_USER_ONLY) */ 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 /*** Integer shift ***/ 264 /*** Integer shift ***/
330 void OPPROTO op_srli_T1 (void) 265 void OPPROTO op_srli_T1 (void)
331 { 266 {
@@ -333,221 +268,6 @@ void OPPROTO op_srli_T1 (void) @@ -333,221 +268,6 @@ void OPPROTO op_srli_T1 (void)
333 RETURN(); 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 /* Load and store */ 271 /* Load and store */
552 #define MEMSUFFIX _raw 272 #define MEMSUFFIX _raw
553 #include "op_helper.h" 273 #include "op_helper.h"
target-ppc/op_helper.c
@@ -299,59 +299,62 @@ static always_inline int isnormal (float64 d) @@ -299,59 +299,62 @@ static always_inline int isnormal (float64 d)
299 } 299 }
300 #endif 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 int isneg; 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 /* Signaling NaN: flags are undefined */ 311 /* Signaling NaN: flags are undefined */
310 - T0 = 0x00; 312 + ret = 0x00;
311 } else { 313 } else {
312 /* Quiet NaN */ 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 /* +/- infinity */ 318 /* +/- infinity */
317 if (isneg) 319 if (isneg)
318 - T0 = 0x09; 320 + ret = 0x09;
319 else 321 else
320 - T0 = 0x05; 322 + ret = 0x05;
321 } else { 323 } else {
322 - if (iszero(FT0)) { 324 + if (iszero(farg.d)) {
323 /* +/- zero */ 325 /* +/- zero */
324 if (isneg) 326 if (isneg)
325 - T0 = 0x12; 327 + ret = 0x12;
326 else 328 else
327 - T0 = 0x02; 329 + ret = 0x02;
328 } else { 330 } else {
329 - if (isden(FT0)) { 331 + if (isden(farg.d)) {
330 /* Denormalized numbers */ 332 /* Denormalized numbers */
331 - T0 = 0x10; 333 + ret = 0x10;
332 } else { 334 } else {
333 /* Normalized numbers */ 335 /* Normalized numbers */
334 - T0 = 0x00; 336 + ret = 0x00;
335 } 337 }
336 if (isneg) { 338 if (isneg) {
337 - T0 |= 0x08; 339 + ret |= 0x08;
338 } else { 340 } else {
339 - T0 |= 0x04; 341 + ret |= 0x04;
340 } 342 }
341 } 343 }
342 } 344 }
343 if (set_fprf) { 345 if (set_fprf) {
344 /* We update FPSCR_FPRF */ 346 /* We update FPSCR_FPRF */
345 env->fpscr &= ~(0x1F << FPSCR_FPRF); 347 env->fpscr &= ~(0x1F << FPSCR_FPRF);
346 - env->fpscr |= T0 << FPSCR_FPRF; 348 + env->fpscr |= ret << FPSCR_FPRF;
347 } 349 }
348 /* We just need fpcc to update Rc1 */ 350 /* We just need fpcc to update Rc1 */
349 - T0 &= 0xF; 351 + return ret & 0xF;
350 } 352 }
351 353
352 /* Floating-point invalid operations exception */ 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 int ve; 358 int ve;
356 359
357 ve = fpscr_ve; 360 ve = fpscr_ve;
@@ -402,7 +405,7 @@ static always_inline void fload_invalid_op_excp (int op) @@ -402,7 +405,7 @@ static always_inline void fload_invalid_op_excp (int op)
402 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI)); 405 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
403 if (ve == 0) { 406 if (ve == 0) {
404 /* Set the result to quiet NaN */ 407 /* Set the result to quiet NaN */
405 - FT0 = UINT64_MAX; 408 + ret = UINT64_MAX;
406 env->fpscr &= ~(0xF << FPSCR_FPCC); 409 env->fpscr &= ~(0xF << FPSCR_FPCC);
407 env->fpscr |= 0x11 << FPSCR_FPCC; 410 env->fpscr |= 0x11 << FPSCR_FPCC;
408 } 411 }
@@ -413,7 +416,7 @@ static always_inline void fload_invalid_op_excp (int op) @@ -413,7 +416,7 @@ static always_inline void fload_invalid_op_excp (int op)
413 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI)); 416 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
414 if (ve == 0) { 417 if (ve == 0) {
415 /* Set the result to quiet NaN */ 418 /* Set the result to quiet NaN */
416 - FT0 = UINT64_MAX; 419 + ret = UINT64_MAX;
417 env->fpscr &= ~(0xF << FPSCR_FPCC); 420 env->fpscr &= ~(0xF << FPSCR_FPCC);
418 env->fpscr |= 0x11 << FPSCR_FPCC; 421 env->fpscr |= 0x11 << FPSCR_FPCC;
419 } 422 }
@@ -429,12 +432,11 @@ static always_inline void fload_invalid_op_excp (int op) @@ -429,12 +432,11 @@ static always_inline void fload_invalid_op_excp (int op)
429 if (msr_fe0 != 0 || msr_fe1 != 0) 432 if (msr_fe0 != 0 || msr_fe1 != 0)
430 do_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op); 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 env->fpscr |= 1 << FPSCR_ZX; 440 env->fpscr |= 1 << FPSCR_ZX;
439 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI)); 441 env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
440 /* Update the floating-point exception summary */ 442 /* Update the floating-point exception summary */
@@ -448,12 +450,10 @@ static always_inline void float_zero_divide_excp (void) @@ -448,12 +450,10 @@ static always_inline void float_zero_divide_excp (void)
448 } 450 }
449 } else { 451 } else {
450 /* Set the result to infinity */ 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 static always_inline void float_overflow_excp (void) 459 static always_inline void float_overflow_excp (void)
@@ -530,7 +530,7 @@ static always_inline void fpscr_set_rounding_mode (void) @@ -530,7 +530,7 @@ static always_inline void fpscr_set_rounding_mode (void)
530 set_float_rounding_mode(rnd_type, &env->fp_status); 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 int prev; 535 int prev;
536 536
@@ -645,25 +645,16 @@ void do_fpscr_setbit (int bit) @@ -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 * We use only the 32 LSB of the incoming fpr 651 * We use only the 32 LSB of the incoming fpr
659 */ 652 */
660 - CPU_DoubleU u;  
661 uint32_t prev, new; 653 uint32_t prev, new;
662 int i; 654 int i;
663 655
664 - u.d = FT0;  
665 prev = env->fpscr; 656 prev = env->fpscr;
666 - new = u.l.lower; 657 + new = (uint32_t)arg;
667 new &= ~0x90000000; 658 new &= ~0x90000000;
668 new |= prev & 0x90000000; 659 new |= prev & 0x90000000;
669 for (i = 0; i < 7; i++) { 660 for (i = 0; i < 7; i++) {
@@ -687,12 +678,10 @@ void do_store_fpscr (uint32_t mask) @@ -687,12 +678,10 @@ void do_store_fpscr (uint32_t mask)
687 env->fpscr &= ~(1 << FPSCR_FEX); 678 env->fpscr &= ~(1 << FPSCR_FEX);
688 fpscr_set_rounding_mode(); 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 if (env->exception_index == POWERPC_EXCP_PROGRAM && 685 if (env->exception_index == POWERPC_EXCP_PROGRAM &&
697 (env->error_code & POWERPC_EXCP_FP)) { 686 (env->error_code & POWERPC_EXCP_FP)) {
698 /* Differred floating-point exception after target FPR update */ 687 /* Differred floating-point exception after target FPR update */
@@ -705,455 +694,618 @@ void do_float_check_status (void) @@ -705,455 +694,618 @@ void do_float_check_status (void)
705 } else if (env->fp_status.float_exception_flags & float_flag_inexact) { 694 } else if (env->fp_status.float_exception_flags & float_flag_inexact) {
706 float_inexact_excp(); 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 #endif 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 /* sNaN addition */ 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 } else { 730 } else {
722 /* Magnitude subtraction of infinities */ 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 /* sNaN subtraction */ 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 } else { 756 } else {
737 /* Magnitude subtraction of infinities */ 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 /* sNaN multiplication */ 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 /* Multiplication of zero by infinity */ 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 } else { 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 /* sNaN division */ 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 /* Division of infinity by infinity */ 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 /* Division of zero by zero */ 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 } else { 812 } else {
771 /* Division by zero */ 813 /* Division by zero */
772 - float_zero_divide_excp(); 814 + farg1.ll = float_zero_divide_excp(farg1.d, farg2.d);
773 } 815 }
774 } else { 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 /* sNaN conversion */ 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 /* qNan / infinity conversion */ 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 } else { 868 } else {
791 - p.ll = float64_to_int32(FT0, &env->fp_status); 869 + farg.ll = float64_to_int32(farg.d, &env->fp_status);
792 #if USE_PRECISE_EMULATION 870 #if USE_PRECISE_EMULATION
793 /* XXX: higher bits are not supposed to be significant. 871 /* XXX: higher bits are not supposed to be significant.
794 * to make tests easier, return the same as a real PowerPC 750 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 #endif 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 /* sNaN conversion */ 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 /* qNan / infinity conversion */ 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 } else { 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 #if USE_PRECISE_EMULATION 894 #if USE_PRECISE_EMULATION
815 /* XXX: higher bits are not supposed to be significant. 895 /* XXX: higher bits are not supposed to be significant.
816 * to make tests easier, return the same as a real PowerPC 750 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 #endif 899 #endif
820 - FT0 = p.d;  
821 } 900 }
  901 + return farg.ll;
822 } 902 }
823 903
824 #if defined(TARGET_PPC64) 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 /* sNaN conversion */ 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 /* qNan / infinity conversion */ 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 } else { 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 /* sNaN conversion */ 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 /* qNan / infinity conversion */ 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 } else { 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 #endif 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 /* sNaN round */ 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 /* qNan / infinity round */ 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 } else { 962 } else {
876 set_float_rounding_mode(rounding_mode, &env->fp_status); 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 /* Restore rounding mode from FPSCR */ 965 /* Restore rounding mode from FPSCR */
879 fpscr_set_rounding_mode(); 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 /* sNaN operation */ 1003 /* sNaN operation */
910 - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); 1004 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
911 } else { 1005 } else {
912 #ifdef FLOAT128 1006 #ifdef FLOAT128
913 /* This is the way the PowerPC specification defines it */ 1007 /* This is the way the PowerPC specification defines it */
914 float128 ft0_128, ft1_128; 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 ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status); 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 ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status); 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 #else 1016 #else
923 /* This is OK on x86 hosts */ 1017 /* This is OK on x86 hosts */
924 - FT0 = (FT0 * FT1) + FT2; 1018 + farg1.d = (farg1.d * farg2.d) + farg3.d;
925 #endif 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 /* sNaN operation */ 1040 /* sNaN operation */
935 - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); 1041 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
936 } else { 1042 } else {
937 #ifdef FLOAT128 1043 #ifdef FLOAT128
938 /* This is the way the PowerPC specification defines it */ 1044 /* This is the way the PowerPC specification defines it */
939 float128 ft0_128, ft1_128; 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 ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status); 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 ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status); 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 #else 1053 #else
948 /* This is OK on x86 hosts */ 1054 /* This is OK on x86 hosts */
949 - FT0 = (FT0 * FT1) - FT2; 1055 + farg1.d = (farg1.d * farg2.d) - farg3.d;
950 #endif 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 /* sNaN operation */ 1077 /* sNaN operation */
961 - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); 1078 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
962 } else { 1079 } else {
963 #if USE_PRECISE_EMULATION 1080 #if USE_PRECISE_EMULATION
964 #ifdef FLOAT128 1081 #ifdef FLOAT128
965 /* This is the way the PowerPC specification defines it */ 1082 /* This is the way the PowerPC specification defines it */
966 float128 ft0_128, ft1_128; 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 ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status); 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 ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status); 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 #else 1091 #else
975 /* This is OK on x86 hosts */ 1092 /* This is OK on x86 hosts */
976 - FT0 = (FT0 * FT1) + FT2; 1093 + farg1.d = (farg1.d * farg2.d) + farg3.d;
977 #endif 1094 #endif
978 #else 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 #endif 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 /* sNaN operation */ 1117 /* sNaN operation */
993 - fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); 1118 + farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
994 } else { 1119 } else {
995 #if USE_PRECISE_EMULATION 1120 #if USE_PRECISE_EMULATION
996 #ifdef FLOAT128 1121 #ifdef FLOAT128
997 /* This is the way the PowerPC specification defines it */ 1122 /* This is the way the PowerPC specification defines it */
998 float128 ft0_128, ft1_128; 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 ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status); 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 ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status); 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 #else 1131 #else
1007 /* This is OK on x86 hosts */ 1132 /* This is OK on x86 hosts */
1008 - FT0 = (FT0 * FT1) - FT2; 1133 + farg1.d = (farg1.d * farg2.d) - farg3.d;
1009 #endif 1134 #endif
1010 #else 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 #endif 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 /* sNaN square root */ 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 } else { 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 /* sNaN square root */ 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 /* Square root of a negative nonzero number */ 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 } else { 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 /* sNaN reciprocal */ 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 /* Zero reciprocal */ 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 } else { 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 } else { 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 /* sNaN reciprocal */ 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 /* Zero reciprocal */ 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 #if USE_PRECISE_EMULATION 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 #else 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 #endif 1231 #endif
1090 } else { 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 } else { 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 /* sNaN reciprocal square root */ 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 /* Reciprocal square root of a negative nonzero number */ 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 } else { 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 } else { 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 else 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 uint32_t ret = 0; 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 /* sNaN comparison */ 1303 /* sNaN comparison */
1152 fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); 1304 fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
1153 } else { 1305 } else {
1154 - if (float64_lt(FT0, FT1, &env->fp_status)) { 1306 + if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
1155 ret = 0x08UL; 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 ret = 0x04UL; 1309 ret = 0x04UL;
1158 } else { 1310 } else {
1159 ret = 0x02UL; 1311 ret = 0x02UL;
@@ -1164,14 +1316,17 @@ uint32_t helper_fcmpu (void) @@ -1164,14 +1316,17 @@ uint32_t helper_fcmpu (void)
1164 return ret; 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 uint32_t ret = 0; 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 /* sNaN comparison */ 1330 /* sNaN comparison */
1176 fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | 1331 fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN |
1177 POWERPC_EXCP_FP_VXVC); 1332 POWERPC_EXCP_FP_VXVC);
@@ -1180,9 +1335,9 @@ uint32_t helper_fcmpo (void) @@ -1180,9 +1335,9 @@ uint32_t helper_fcmpo (void)
1180 fload_invalid_op_excp(POWERPC_EXCP_FP_VXVC); 1335 fload_invalid_op_excp(POWERPC_EXCP_FP_VXVC);
1181 } 1336 }
1182 } else { 1337 } else {
1183 - if (float64_lt(FT0, FT1, &env->fp_status)) { 1338 + if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
1184 ret = 0x08UL; 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 ret = 0x04UL; 1341 ret = 0x04UL;
1187 } else { 1342 } else {
1188 ret = 0x02UL; 1343 ret = 0x02UL;
target-ppc/translate.c
@@ -75,7 +75,7 @@ static TCGv cpu_T[3]; @@ -75,7 +75,7 @@ static TCGv cpu_T[3];
75 #else 75 #else
76 static TCGv_i64 cpu_T64[3]; 76 static TCGv_i64 cpu_T64[3];
77 #endif 77 #endif
78 -static TCGv_i64 cpu_FT[3]; 78 +static TCGv_i64 cpu_FT[2];
79 static TCGv_i64 cpu_AVRh[3], cpu_AVRl[3]; 79 static TCGv_i64 cpu_AVRh[3], cpu_AVRl[3];
80 80
81 #include "gen-icount.h" 81 #include "gen-icount.h"
@@ -120,8 +120,6 @@ void ppc_translate_init(void) @@ -120,8 +120,6 @@ void ppc_translate_init(void)
120 offsetof(CPUState, ft0), "FT0"); 120 offsetof(CPUState, ft0), "FT0");
121 cpu_FT[1] = tcg_global_mem_new_i64(TCG_AREG0, 121 cpu_FT[1] = tcg_global_mem_new_i64(TCG_AREG0,
122 offsetof(CPUState, ft1), "FT1"); 122 offsetof(CPUState, ft1), "FT1");
123 - cpu_FT[2] = tcg_global_mem_new_i64(TCG_AREG0,  
124 - offsetof(CPUState, ft2), "FT2");  
125 123
126 cpu_AVRh[0] = tcg_global_mem_new_i64(TCG_AREG0, 124 cpu_AVRh[0] = tcg_global_mem_new_i64(TCG_AREG0,
127 offsetof(CPUState, avr0.u64[0]), "AVR0H"); 125 offsetof(CPUState, avr0.u64[0]), "AVR0H");
@@ -245,27 +243,31 @@ static always_inline void gen_reset_fpstatus (void) @@ -245,27 +243,31 @@ static always_inline void gen_reset_fpstatus (void)
245 #endif 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 if (set_fprf != 0) { 250 if (set_fprf != 0) {
251 /* This case might be optimized later */ 251 /* This case might be optimized later */
252 #if defined(OPTIMIZE_FPRF_UPDATE) 252 #if defined(OPTIMIZE_FPRF_UPDATE)
253 *gen_fprf_ptr++ = gen_opc_ptr; 253 *gen_fprf_ptr++ = gen_opc_ptr;
254 #endif 254 #endif
255 - gen_op_compute_fprf(1); 255 + tcg_gen_movi_tl(t0, 1);
  256 + gen_helper_compute_fprf(t0, arg, t0);
256 if (unlikely(set_rc)) { 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 } else if (unlikely(set_rc)) { 261 } else if (unlikely(set_rc)) {
262 /* We always need to compute fpcc */ 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 if (set_fprf) 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 static always_inline void gen_optimize_fprf (void) 273 static always_inline void gen_optimize_fprf (void)
@@ -2096,16 +2098,14 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \ @@ -2096,16 +2098,14 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \
2096 GEN_EXCP_NO_FP(ctx); \ 2098 GEN_EXCP_NO_FP(ctx); \
2097 return; \ 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 gen_reset_fpstatus(); \ 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 if (isfloat) { \ 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 #define GEN_FLOAT_ACB(name, op2, set_fprf, type) \ 2111 #define GEN_FLOAT_ACB(name, op2, set_fprf, type) \
@@ -2119,15 +2119,14 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \ @@ -2119,15 +2119,14 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \
2119 GEN_EXCP_NO_FP(ctx); \ 2119 GEN_EXCP_NO_FP(ctx); \
2120 return; \ 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 gen_reset_fpstatus(); \ 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 if (isfloat) { \ 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 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type) \ 2131 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type) \
2133 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type); \ 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,15 +2139,14 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \
2140 GEN_EXCP_NO_FP(ctx); \ 2139 GEN_EXCP_NO_FP(ctx); \
2141 return; \ 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 gen_reset_fpstatus(); \ 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 if (isfloat) { \ 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 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type) \ 2151 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type) \
2154 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type); \ 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,11 +2159,10 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \
2161 GEN_EXCP_NO_FP(ctx); \ 2159 GEN_EXCP_NO_FP(ctx); \
2162 return; \ 2160 return; \
2163 } \ 2161 } \
2164 - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]); \  
2165 gen_reset_fpstatus(); \ 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 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type) \ 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,11 +2172,10 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type) \
2175 GEN_EXCP_NO_FP(ctx); \ 2172 GEN_EXCP_NO_FP(ctx); \
2176 return; \ 2173 return; \
2177 } \ 2174 } \
2178 - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]); \  
2179 gen_reset_fpstatus(); \ 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 /* fadd - fadds */ 2181 /* fadd - fadds */
@@ -2199,12 +2195,17 @@ GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES); @@ -2199,12 +2195,17 @@ GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2199 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE); 2195 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2200 2196
2201 /* frsqrtes */ 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 /* fsel */ 2210 /* fsel */
2210 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL); 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,11 +2219,9 @@ GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
2218 GEN_EXCP_NO_FP(ctx); 2219 GEN_EXCP_NO_FP(ctx);
2219 return; 2220 return;
2220 } 2221 }
2221 - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);  
2222 gen_reset_fpstatus(); 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 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT) 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,12 +2230,10 @@ GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
2231 GEN_EXCP_NO_FP(ctx); 2230 GEN_EXCP_NO_FP(ctx);
2232 return; 2231 return;
2233 } 2232 }
2234 - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);  
2235 gen_reset_fpstatus(); 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 /*** Floating-Point multiply-and-add ***/ 2239 /*** Floating-Point multiply-and-add ***/
@@ -2282,11 +2279,10 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) @@ -2282,11 +2279,10 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
2282 GEN_EXCP_NO_FP(ctx); 2279 GEN_EXCP_NO_FP(ctx);
2283 return; 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 gen_reset_fpstatus(); 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 /* fcmpu */ 2288 /* fcmpu */
@@ -2296,11 +2292,10 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) @@ -2296,11 +2292,10 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
2296 GEN_EXCP_NO_FP(ctx); 2292 GEN_EXCP_NO_FP(ctx);
2297 return; 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 gen_reset_fpstatus(); 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 /*** Floating-point move ***/ 2301 /*** Floating-point move ***/
@@ -2316,9 +2311,8 @@ GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT) @@ -2316,9 +2311,8 @@ GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
2316 GEN_EXCP_NO_FP(ctx); 2311 GEN_EXCP_NO_FP(ctx);
2317 return; 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 /* fnabs */ 2318 /* fnabs */
@@ -2342,7 +2336,7 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) @@ -2342,7 +2336,7 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
2342 bfa = 4 * (7 - crfS(ctx->opcode)); 2336 bfa = 4 * (7 - crfS(ctx->opcode));
2343 tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa); 2337 tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
2344 tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf); 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 /* mffs */ 2342 /* mffs */
@@ -2354,9 +2348,8 @@ GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) @@ -2354,9 +2348,8 @@ GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2354 } 2348 }
2355 gen_optimize_fprf(); 2349 gen_optimize_fprf();
2356 gen_reset_fpstatus(); 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 /* mtfsb0 */ 2355 /* mtfsb0 */
@@ -2372,7 +2365,7 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) @@ -2372,7 +2365,7 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2372 gen_optimize_fprf(); 2365 gen_optimize_fprf();
2373 gen_reset_fpstatus(); 2366 gen_reset_fpstatus();
2374 if (likely(crb != 30 && crb != 29)) 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 if (unlikely(Rc(ctx->opcode) != 0)) { 2369 if (unlikely(Rc(ctx->opcode) != 0)) {
2377 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); 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,37 +2384,44 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2391 gen_optimize_fprf(); 2384 gen_optimize_fprf();
2392 gen_reset_fpstatus(); 2385 gen_reset_fpstatus();
2393 /* XXX: we pretend we can only do IEEE floating-point computations */ 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 if (unlikely(Rc(ctx->opcode) != 0)) { 2392 if (unlikely(Rc(ctx->opcode) != 0)) {
2397 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); 2393 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2398 } 2394 }
2399 /* We can raise a differed exception */ 2395 /* We can raise a differed exception */
2400 - gen_op_float_check_status(); 2396 + gen_helper_float_check_status();
2401 } 2397 }
2402 2398
2403 /* mtfsf */ 2399 /* mtfsf */
2404 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) 2400 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2405 { 2401 {
  2402 + TCGv t0;
  2403 +
2406 if (unlikely(!ctx->fpu_enabled)) { 2404 if (unlikely(!ctx->fpu_enabled)) {
2407 GEN_EXCP_NO_FP(ctx); 2405 GEN_EXCP_NO_FP(ctx);
2408 return; 2406 return;
2409 } 2407 }
2410 gen_optimize_fprf(); 2408 gen_optimize_fprf();
2411 - tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);  
2412 gen_reset_fpstatus(); 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 if (unlikely(Rc(ctx->opcode) != 0)) { 2413 if (unlikely(Rc(ctx->opcode) != 0)) {
2415 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); 2414 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2416 } 2415 }
2417 /* We can raise a differed exception */ 2416 /* We can raise a differed exception */
2418 - gen_op_float_check_status(); 2417 + gen_helper_float_check_status();
2419 } 2418 }
2420 2419
2421 /* mtfsfi */ 2420 /* mtfsfi */
2422 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) 2421 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2423 { 2422 {
2424 int bf, sh; 2423 int bf, sh;
  2424 + TCGv t0, t1;
2425 2425
2426 if (unlikely(!ctx->fpu_enabled)) { 2426 if (unlikely(!ctx->fpu_enabled)) {
2427 GEN_EXCP_NO_FP(ctx); 2427 GEN_EXCP_NO_FP(ctx);
@@ -2430,14 +2430,17 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) @@ -2430,14 +2430,17 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2430 bf = crbD(ctx->opcode) >> 2; 2430 bf = crbD(ctx->opcode) >> 2;
2431 sh = 7 - bf; 2431 sh = 7 - bf;
2432 gen_optimize_fprf(); 2432 gen_optimize_fprf();
2433 - tcg_gen_movi_i64(cpu_FT[0], FPIMM(ctx->opcode) << (4 * sh));  
2434 gen_reset_fpstatus(); 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 if (unlikely(Rc(ctx->opcode) != 0)) { 2439 if (unlikely(Rc(ctx->opcode) != 0)) {
2437 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); 2440 tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2438 } 2441 }
2439 /* We can raise a differed exception */ 2442 /* We can raise a differed exception */
2440 - gen_op_float_check_status(); 2443 + gen_helper_float_check_status();
2441 } 2444 }
2442 2445
2443 /*** Addressing modes ***/ 2446 /*** Addressing modes ***/