Commit 477023a6038e8f457c604b138198f76d093b9a87

Authored by j_mayer
1 parent bfa1e5cf

Improve single-precision floats load & stores:

as the PowerPC registers only store double-precision floats,
  use float64_to_float32 & float32_to_float64 to do the appropriate conversion.
Implement stfiwx.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3280 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/op_mem.h
... ... @@ -403,11 +403,30 @@ void OPPROTO glue(glue(glue(op_st, name), _64), MEMSUFFIX) (void) \
403 403 }
404 404 #endif
405 405  
  406 +static inline void glue(stfs, MEMSUFFIX) (target_ulong EA, double d)
  407 +{
  408 + glue(stfl, MEMSUFFIX)(EA, float64_to_float32(d, &env->fp_status));
  409 +}
  410 +
  411 +static inline void glue(stfiwx, MEMSUFFIX) (target_ulong EA, double d)
  412 +{
  413 + union {
  414 + double d;
  415 + uint64_t u;
  416 + } u;
  417 +
  418 + /* Store the low order 32 bits without any conversion */
  419 + u.d = d;
  420 + glue(stl, MEMSUFFIX)(EA, u.u);
  421 +}
  422 +
406 423 PPC_STF_OP(fd, stfq);
407   -PPC_STF_OP(fs, stfl);
  424 +PPC_STF_OP(fs, stfs);
  425 +PPC_STF_OP(fiwx, stfiwx);
408 426 #if defined(TARGET_PPC64)
409 427 PPC_STF_OP_64(fd, stfq);
410   -PPC_STF_OP_64(fs, stfl);
  428 +PPC_STF_OP_64(fs, stfs);
  429 +PPC_STF_OP_64(fiwx, stfiwx);
411 430 #endif
412 431  
413 432 static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
... ... @@ -429,14 +448,14 @@ static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
429 448 glue(stfq, MEMSUFFIX)(EA, u.d);
430 449 }
431 450  
432   -static inline void glue(stflr, MEMSUFFIX) (target_ulong EA, float f)
  451 +static inline void glue(stfsr, MEMSUFFIX) (target_ulong EA, double d)
433 452 {
434 453 union {
435 454 float f;
436 455 uint32_t u;
437 456 } u;
438 457  
439   - u.f = f;
  458 + u.f = float64_to_float32(d, &env->fp_status);
440 459 u.u = ((u.u & 0xFF000000UL) >> 24) |
441 460 ((u.u & 0x00FF0000ULL) >> 8) |
442 461 ((u.u & 0x0000FF00UL) << 8) |
... ... @@ -444,11 +463,30 @@ static inline void glue(stflr, MEMSUFFIX) (target_ulong EA, float f)
444 463 glue(stfl, MEMSUFFIX)(EA, u.f);
445 464 }
446 465  
  466 +static inline void glue(stfiwxr, MEMSUFFIX) (target_ulong EA, double d)
  467 +{
  468 + union {
  469 + double d;
  470 + uint64_t u;
  471 + } u;
  472 +
  473 + /* Store the low order 32 bits without any conversion */
  474 + u.d = d;
  475 + u.u = ((u.u & 0xFF000000UL) >> 24) |
  476 + ((u.u & 0x00FF0000ULL) >> 8) |
  477 + ((u.u & 0x0000FF00UL) << 8) |
  478 + ((u.u & 0x000000FFULL) << 24);
  479 + glue(stl, MEMSUFFIX)(EA, u.u);
  480 +}
  481 +
  482 +
447 483 PPC_STF_OP(fd_le, stfqr);
448   -PPC_STF_OP(fs_le, stflr);
  484 +PPC_STF_OP(fs_le, stfsr);
  485 +PPC_STF_OP(fiwx_le, stfiwxr);
449 486 #if defined(TARGET_PPC64)
450 487 PPC_STF_OP_64(fd_le, stfqr);
451   -PPC_STF_OP_64(fs_le, stflr);
  488 +PPC_STF_OP_64(fs_le, stfsr);
  489 +PPC_STF_OP_64(fiwx_le, stfiwxr);
452 490 #endif
453 491  
454 492 /*** Floating-point load ***/
... ... @@ -468,11 +506,16 @@ void OPPROTO glue(glue(glue(op_l, name), _64), MEMSUFFIX) (void) \
468 506 }
469 507 #endif
470 508  
  509 +static inline double glue(ldfs, MEMSUFFIX) (target_ulong EA)
  510 +{
  511 + return float32_to_float64(glue(ldfl, MEMSUFFIX)(EA), &env->fp_status);
  512 +}
  513 +
471 514 PPC_LDF_OP(fd, ldfq);
472   -PPC_LDF_OP(fs, ldfl);
  515 +PPC_LDF_OP(fs, ldfs);
473 516 #if defined(TARGET_PPC64)
474 517 PPC_LDF_OP_64(fd, ldfq);
475   -PPC_LDF_OP_64(fs, ldfl);
  518 +PPC_LDF_OP_64(fs, ldfs);
476 519 #endif
477 520  
478 521 static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
... ... @@ -495,7 +538,7 @@ static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
495 538 return u.d;
496 539 }
497 540  
498   -static inline float glue(ldflr, MEMSUFFIX) (target_ulong EA)
  541 +static inline double glue(ldfsr, MEMSUFFIX) (target_ulong EA)
499 542 {
500 543 union {
501 544 float f;
... ... @@ -508,14 +551,14 @@ static inline float glue(ldflr, MEMSUFFIX) (target_ulong EA)
508 551 ((u.u & 0x0000FF00UL) << 8) |
509 552 ((u.u & 0x000000FFULL) << 24);
510 553  
511   - return u.f;
  554 + return float32_to_float64(u.f, &env->fp_status);
512 555 }
513 556  
514 557 PPC_LDF_OP(fd_le, ldfqr);
515   -PPC_LDF_OP(fs_le, ldflr);
  558 +PPC_LDF_OP(fs_le, ldfsr);
516 559 #if defined(TARGET_PPC64)
517 560 PPC_LDF_OP_64(fd_le, ldfqr);
518   -PPC_LDF_OP_64(fs_le, ldflr);
  561 +PPC_LDF_OP_64(fs_le, ldfsr);
519 562 #endif
520 563  
521 564 /* Load and set reservation */
... ...
target-ppc/translate.c
... ... @@ -2581,8 +2581,8 @@ GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03CF0801, PPC_MEM_SYNC)
2581 2581 }
2582 2582  
2583 2583 /*** Floating-point load ***/
2584   -#define GEN_LDF(width, opc) \
2585   -GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
  2584 +#define GEN_LDF(width, opc, type) \
  2585 +GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
2586 2586 { \
2587 2587 if (unlikely(!ctx->fpu_enabled)) { \
2588 2588 GEN_EXCP_NO_FP(ctx); \
... ... @@ -2593,8 +2593,8 @@ GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2593 2593 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2594 2594 }
2595 2595  
2596   -#define GEN_LDUF(width, opc) \
2597   -GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
  2596 +#define GEN_LDUF(width, opc, type) \
  2597 +GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
2598 2598 { \
2599 2599 if (unlikely(!ctx->fpu_enabled)) { \
2600 2600 GEN_EXCP_NO_FP(ctx); \
... ... @@ -2610,8 +2610,8 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2610 2610 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2611 2611 }
2612 2612  
2613   -#define GEN_LDUXF(width, opc) \
2614   -GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
  2613 +#define GEN_LDUXF(width, opc, type) \
  2614 +GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type) \
2615 2615 { \
2616 2616 if (unlikely(!ctx->fpu_enabled)) { \
2617 2617 GEN_EXCP_NO_FP(ctx); \
... ... @@ -2627,8 +2627,8 @@ GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2627 2627 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2628 2628 }
2629 2629  
2630   -#define GEN_LDXF(width, opc2, opc3) \
2631   -GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
  2630 +#define GEN_LDXF(width, opc2, opc3, type) \
  2631 +GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
2632 2632 { \
2633 2633 if (unlikely(!ctx->fpu_enabled)) { \
2634 2634 GEN_EXCP_NO_FP(ctx); \
... ... @@ -2639,21 +2639,21 @@ GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2639 2639 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2640 2640 }
2641 2641  
2642   -#define GEN_LDFS(width, op) \
  2642 +#define GEN_LDFS(width, op, type) \
2643 2643 OP_LD_TABLE(width); \
2644   -GEN_LDF(width, op | 0x20); \
2645   -GEN_LDUF(width, op | 0x21); \
2646   -GEN_LDUXF(width, op | 0x01); \
2647   -GEN_LDXF(width, 0x17, op | 0x00)
  2644 +GEN_LDF(width, op | 0x20, type); \
  2645 +GEN_LDUF(width, op | 0x21, type); \
  2646 +GEN_LDUXF(width, op | 0x01, type); \
  2647 +GEN_LDXF(width, 0x17, op | 0x00, type)
2648 2648  
2649 2649 /* lfd lfdu lfdux lfdx */
2650   -GEN_LDFS(fd, 0x12);
  2650 +GEN_LDFS(fd, 0x12, PPC_FLOAT);
2651 2651 /* lfs lfsu lfsux lfsx */
2652   -GEN_LDFS(fs, 0x10);
  2652 +GEN_LDFS(fs, 0x10, PPC_FLOAT);
2653 2653  
2654 2654 /*** Floating-point store ***/
2655   -#define GEN_STF(width, opc) \
2656   -GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
  2655 +#define GEN_STF(width, opc, type) \
  2656 +GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
2657 2657 { \
2658 2658 if (unlikely(!ctx->fpu_enabled)) { \
2659 2659 GEN_EXCP_NO_FP(ctx); \
... ... @@ -2664,8 +2664,8 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2664 2664 op_ldst(st##width); \
2665 2665 }
2666 2666  
2667   -#define GEN_STUF(width, opc) \
2668   -GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
  2667 +#define GEN_STUF(width, opc, type) \
  2668 +GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
2669 2669 { \
2670 2670 if (unlikely(!ctx->fpu_enabled)) { \
2671 2671 GEN_EXCP_NO_FP(ctx); \
... ... @@ -2681,8 +2681,8 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2681 2681 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2682 2682 }
2683 2683  
2684   -#define GEN_STUXF(width, opc) \
2685   -GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
  2684 +#define GEN_STUXF(width, opc, type) \
  2685 +GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type) \
2686 2686 { \
2687 2687 if (unlikely(!ctx->fpu_enabled)) { \
2688 2688 GEN_EXCP_NO_FP(ctx); \
... ... @@ -2698,8 +2698,8 @@ GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2698 2698 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2699 2699 }
2700 2700  
2701   -#define GEN_STXF(width, opc2, opc3) \
2702   -GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
  2701 +#define GEN_STXF(width, opc2, opc3, type) \
  2702 +GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
2703 2703 { \
2704 2704 if (unlikely(!ctx->fpu_enabled)) { \
2705 2705 GEN_EXCP_NO_FP(ctx); \
... ... @@ -2710,30 +2710,22 @@ GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2710 2710 op_ldst(st##width); \
2711 2711 }
2712 2712  
2713   -#define GEN_STFS(width, op) \
  2713 +#define GEN_STFS(width, op, type) \
2714 2714 OP_ST_TABLE(width); \
2715   -GEN_STF(width, op | 0x20); \
2716   -GEN_STUF(width, op | 0x21); \
2717   -GEN_STUXF(width, op | 0x01); \
2718   -GEN_STXF(width, 0x17, op | 0x00)
  2715 +GEN_STF(width, op | 0x20, type); \
  2716 +GEN_STUF(width, op | 0x21, type); \
  2717 +GEN_STUXF(width, op | 0x01, type); \
  2718 +GEN_STXF(width, 0x17, op | 0x00, type)
2719 2719  
2720 2720 /* stfd stfdu stfdux stfdx */
2721   -GEN_STFS(fd, 0x16);
  2721 +GEN_STFS(fd, 0x16, PPC_FLOAT);
2722 2722 /* stfs stfsu stfsux stfsx */
2723   -GEN_STFS(fs, 0x14);
  2723 +GEN_STFS(fs, 0x14, PPC_FLOAT);
2724 2724  
2725 2725 /* Optional: */
2726 2726 /* stfiwx */
2727   -GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT_STFIWX)
2728   -{
2729   - if (unlikely(!ctx->fpu_enabled)) {
2730   - GEN_EXCP_NO_FP(ctx);
2731   - return;
2732   - }
2733   - gen_addr_reg_index(ctx);
2734   - /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2735   - GEN_EXCP_INVAL(ctx);
2736   -}
  2727 +OP_ST_TABLE(fiwx);
  2728 +GEN_STXF(fiwx, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2737 2729  
2738 2730 /*** Branch ***/
2739 2731 static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
... ...