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,11 +403,30 @@ void OPPROTO glue(glue(glue(op_st, name), _64), MEMSUFFIX) (void) \
403 } 403 }
404 #endif 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 PPC_STF_OP(fd, stfq); 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 #if defined(TARGET_PPC64) 426 #if defined(TARGET_PPC64)
409 PPC_STF_OP_64(fd, stfq); 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 #endif 430 #endif
412 431
413 static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d) 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,14 +448,14 @@ static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
429 glue(stfq, MEMSUFFIX)(EA, u.d); 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 union { 453 union {
435 float f; 454 float f;
436 uint32_t u; 455 uint32_t u;
437 } u; 456 } u;
438 457
439 - u.f = f; 458 + u.f = float64_to_float32(d, &env->fp_status);
440 u.u = ((u.u & 0xFF000000UL) >> 24) | 459 u.u = ((u.u & 0xFF000000UL) >> 24) |
441 ((u.u & 0x00FF0000ULL) >> 8) | 460 ((u.u & 0x00FF0000ULL) >> 8) |
442 ((u.u & 0x0000FF00UL) << 8) | 461 ((u.u & 0x0000FF00UL) << 8) |
@@ -444,11 +463,30 @@ static inline void glue(stflr, MEMSUFFIX) (target_ulong EA, float f) @@ -444,11 +463,30 @@ static inline void glue(stflr, MEMSUFFIX) (target_ulong EA, float f)
444 glue(stfl, MEMSUFFIX)(EA, u.f); 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 PPC_STF_OP(fd_le, stfqr); 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 #if defined(TARGET_PPC64) 486 #if defined(TARGET_PPC64)
450 PPC_STF_OP_64(fd_le, stfqr); 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 #endif 490 #endif
453 491
454 /*** Floating-point load ***/ 492 /*** Floating-point load ***/
@@ -468,11 +506,16 @@ void OPPROTO glue(glue(glue(op_l, name), _64), MEMSUFFIX) (void) \ @@ -468,11 +506,16 @@ void OPPROTO glue(glue(glue(op_l, name), _64), MEMSUFFIX) (void) \
468 } 506 }
469 #endif 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 PPC_LDF_OP(fd, ldfq); 514 PPC_LDF_OP(fd, ldfq);
472 -PPC_LDF_OP(fs, ldfl); 515 +PPC_LDF_OP(fs, ldfs);
473 #if defined(TARGET_PPC64) 516 #if defined(TARGET_PPC64)
474 PPC_LDF_OP_64(fd, ldfq); 517 PPC_LDF_OP_64(fd, ldfq);
475 -PPC_LDF_OP_64(fs, ldfl); 518 +PPC_LDF_OP_64(fs, ldfs);
476 #endif 519 #endif
477 520
478 static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) 521 static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
@@ -495,7 +538,7 @@ static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) @@ -495,7 +538,7 @@ static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
495 return u.d; 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 union { 543 union {
501 float f; 544 float f;
@@ -508,14 +551,14 @@ static inline float glue(ldflr, MEMSUFFIX) (target_ulong EA) @@ -508,14 +551,14 @@ static inline float glue(ldflr, MEMSUFFIX) (target_ulong EA)
508 ((u.u & 0x0000FF00UL) << 8) | 551 ((u.u & 0x0000FF00UL) << 8) |
509 ((u.u & 0x000000FFULL) << 24); 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 PPC_LDF_OP(fd_le, ldfqr); 557 PPC_LDF_OP(fd_le, ldfqr);
515 -PPC_LDF_OP(fs_le, ldflr); 558 +PPC_LDF_OP(fs_le, ldfsr);
516 #if defined(TARGET_PPC64) 559 #if defined(TARGET_PPC64)
517 PPC_LDF_OP_64(fd_le, ldfqr); 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 #endif 562 #endif
520 563
521 /* Load and set reservation */ 564 /* Load and set reservation */
target-ppc/translate.c
@@ -2581,8 +2581,8 @@ GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03CF0801, PPC_MEM_SYNC) @@ -2581,8 +2581,8 @@ GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03CF0801, PPC_MEM_SYNC)
2581 } 2581 }
2582 2582
2583 /*** Floating-point load ***/ 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 if (unlikely(!ctx->fpu_enabled)) { \ 2587 if (unlikely(!ctx->fpu_enabled)) { \
2588 GEN_EXCP_NO_FP(ctx); \ 2588 GEN_EXCP_NO_FP(ctx); \
@@ -2593,8 +2593,8 @@ GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2593,8 +2593,8 @@ GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2593 gen_op_store_FT0_fpr(rD(ctx->opcode)); \ 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 if (unlikely(!ctx->fpu_enabled)) { \ 2599 if (unlikely(!ctx->fpu_enabled)) { \
2600 GEN_EXCP_NO_FP(ctx); \ 2600 GEN_EXCP_NO_FP(ctx); \
@@ -2610,8 +2610,8 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2610,8 +2610,8 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2610 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 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 if (unlikely(!ctx->fpu_enabled)) { \ 2616 if (unlikely(!ctx->fpu_enabled)) { \
2617 GEN_EXCP_NO_FP(ctx); \ 2617 GEN_EXCP_NO_FP(ctx); \
@@ -2627,8 +2627,8 @@ GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ @@ -2627,8 +2627,8 @@ GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2627 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 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 if (unlikely(!ctx->fpu_enabled)) { \ 2633 if (unlikely(!ctx->fpu_enabled)) { \
2634 GEN_EXCP_NO_FP(ctx); \ 2634 GEN_EXCP_NO_FP(ctx); \
@@ -2639,21 +2639,21 @@ GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \ @@ -2639,21 +2639,21 @@ GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2639 gen_op_store_FT0_fpr(rD(ctx->opcode)); \ 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 OP_LD_TABLE(width); \ 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 /* lfd lfdu lfdux lfdx */ 2649 /* lfd lfdu lfdux lfdx */
2650 -GEN_LDFS(fd, 0x12); 2650 +GEN_LDFS(fd, 0x12, PPC_FLOAT);
2651 /* lfs lfsu lfsux lfsx */ 2651 /* lfs lfsu lfsux lfsx */
2652 -GEN_LDFS(fs, 0x10); 2652 +GEN_LDFS(fs, 0x10, PPC_FLOAT);
2653 2653
2654 /*** Floating-point store ***/ 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 if (unlikely(!ctx->fpu_enabled)) { \ 2658 if (unlikely(!ctx->fpu_enabled)) { \
2659 GEN_EXCP_NO_FP(ctx); \ 2659 GEN_EXCP_NO_FP(ctx); \
@@ -2664,8 +2664,8 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2664,8 +2664,8 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2664 op_ldst(st##width); \ 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 if (unlikely(!ctx->fpu_enabled)) { \ 2670 if (unlikely(!ctx->fpu_enabled)) { \
2671 GEN_EXCP_NO_FP(ctx); \ 2671 GEN_EXCP_NO_FP(ctx); \
@@ -2681,8 +2681,8 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2681,8 +2681,8 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2681 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 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 if (unlikely(!ctx->fpu_enabled)) { \ 2687 if (unlikely(!ctx->fpu_enabled)) { \
2688 GEN_EXCP_NO_FP(ctx); \ 2688 GEN_EXCP_NO_FP(ctx); \
@@ -2698,8 +2698,8 @@ GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ @@ -2698,8 +2698,8 @@ GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2698 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 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 if (unlikely(!ctx->fpu_enabled)) { \ 2704 if (unlikely(!ctx->fpu_enabled)) { \
2705 GEN_EXCP_NO_FP(ctx); \ 2705 GEN_EXCP_NO_FP(ctx); \
@@ -2710,30 +2710,22 @@ GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \ @@ -2710,30 +2710,22 @@ GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2710 op_ldst(st##width); \ 2710 op_ldst(st##width); \
2711 } 2711 }
2712 2712
2713 -#define GEN_STFS(width, op) \ 2713 +#define GEN_STFS(width, op, type) \
2714 OP_ST_TABLE(width); \ 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 /* stfd stfdu stfdux stfdx */ 2720 /* stfd stfdu stfdux stfdx */
2721 -GEN_STFS(fd, 0x16); 2721 +GEN_STFS(fd, 0x16, PPC_FLOAT);
2722 /* stfs stfsu stfsux stfsx */ 2722 /* stfs stfsu stfsux stfsx */
2723 -GEN_STFS(fs, 0x14); 2723 +GEN_STFS(fs, 0x14, PPC_FLOAT);
2724 2724
2725 /* Optional: */ 2725 /* Optional: */
2726 /* stfiwx */ 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 /*** Branch ***/ 2730 /*** Branch ***/
2739 static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest) 2731 static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)