qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

ppc: Add support for 'mffscrn','mffscrni' instructions

ISA 3.0B added a set of Floating-Point Status and Control Register (FPSCR)
instructions: mffsce, mffscdrn, mffscdrni, mffscrn, mffscrni, mffsl.
This patch adds support for 'mffscrn' and 'mffscrni' instructions.

'mffscrn' and 'mffscrni' are similar to 'mffsl', except they do not return
the status bits (FI, FR, FPRF) and they also set the rounding mode in the
FPSCR.

On CPUs without support for 'mffscrn'/'mffscrni' (below ISA 3.0), the
instructions will execute identically to 'mffs'.

Signed-off-by: Paul A. Clarke <pc@us.ibm.com>
Message-Id: <1568817081-1345-1-git-send-email-pc@us.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

authored by

Paul A. Clarke and committed by
David Gibson
a2735cf4 4c3539d4

+84 -3
+8 -1
target/ppc/cpu.h
··· 559 559 560 560 /*****************************************************************************/ 561 561 /* Floating point status and control register */ 562 + #define FPSCR_DRN2 34 /* Decimal Floating-Point rounding control */ 563 + #define FPSCR_DRN1 33 /* Decimal Floating-Point rounding control */ 564 + #define FPSCR_DRN0 32 /* Decimal Floating-Point rounding control */ 562 565 #define FPSCR_FX 31 /* Floating-point exception summary */ 563 566 #define FPSCR_FEX 30 /* Floating-point enabled exception summary */ 564 567 #define FPSCR_VX 29 /* Floating-point invalid operation exception summ. */ ··· 592 595 #define FPSCR_NI 2 /* Floating-point non-IEEE mode */ 593 596 #define FPSCR_RN1 1 594 597 #define FPSCR_RN0 0 /* Floating-point rounding control */ 598 + #define fpscr_drn (((env->fpscr) & FP_DRN) >> FPSCR_DRN0) 595 599 #define fpscr_fex (((env->fpscr) >> FPSCR_FEX) & 0x1) 596 600 #define fpscr_vx (((env->fpscr) >> FPSCR_VX) & 0x1) 597 601 #define fpscr_ox (((env->fpscr) >> FPSCR_OX) & 0x1) ··· 627 631 #define fpscr_eex (((env->fpscr) >> FPSCR_XX) & ((env->fpscr) >> FPSCR_XE) & \ 628 632 0x1F) 629 633 634 + #define FP_DRN2 (1ull << FPSCR_DRN2) 635 + #define FP_DRN1 (1ull << FPSCR_DRN1) 636 + #define FP_DRN0 (1ull << FPSCR_DRN0) 637 + #define FP_DRN (FP_DRN2 | FP_DRN1 | FP_DRN0) 630 638 #define FP_FX (1ull << FPSCR_FX) 631 639 #define FP_FEX (1ull << FPSCR_FEX) 632 640 #define FP_VX (1ull << FPSCR_VX) ··· 662 670 #define FP_RN0 (1ull << FPSCR_RN0) 663 671 #define FP_RN (FP_RN1 | FP_RN0) 664 672 665 - #define FP_MODE FP_RN 666 673 #define FP_ENABLES (FP_VE | FP_OE | FP_UE | FP_ZE | FP_XE) 667 674 #define FP_STATUS (FP_FR | FP_FI | FP_FPRF) 668 675
+1 -1
target/ppc/dfp_helper.c
··· 48 48 { 49 49 enum rounding rnd; 50 50 51 - switch ((fpscr >> 32) & 0x7) { 51 + switch ((fpscr & FP_DRN) >> FPSCR_DRN0) { 52 52 case 0: 53 53 rnd = DEC_ROUND_HALF_EVEN; 54 54 break;
+3
target/ppc/internal.h
··· 157 157 EXTRACT_HELPER(FPFLM, 17, 8); 158 158 EXTRACT_HELPER(FPW, 16, 1); 159 159 160 + /* mffscrni */ 161 + EXTRACT_HELPER(RM, 11, 2); 162 + 160 163 /* addpcis */ 161 164 EXTRACT_HELPER_SPLIT_3(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0) 162 165 #if defined(TARGET_PPC64)
+68 -1
target/ppc/translate/fp-impl.inc.c
··· 634 634 gen_reset_fpstatus(); 635 635 tcg_gen_extu_tl_i64(t0, cpu_fpscr); 636 636 /* Mask everything except mode, status, and enables. */ 637 - tcg_gen_andi_i64(t0, t0, FP_MODE | FP_STATUS | FP_ENABLES); 637 + tcg_gen_andi_i64(t0, t0, FP_DRN | FP_STATUS | FP_ENABLES | FP_RN); 638 638 set_fpr(rD(ctx->opcode), t0); 639 639 tcg_temp_free_i64(t0); 640 + } 641 + 642 + static void gen_helper_mffscrn(DisasContext *ctx, TCGv_i64 t1) 643 + { 644 + TCGv_i64 t0 = tcg_temp_new_i64(); 645 + TCGv_i32 mask = tcg_const_i32(0x0001); 646 + 647 + gen_reset_fpstatus(); 648 + tcg_gen_extu_tl_i64(t0, cpu_fpscr); 649 + tcg_gen_andi_i64(t0, t0, FP_DRN | FP_ENABLES | FP_RN); 650 + set_fpr(rD(ctx->opcode), t0); 651 + 652 + /* Mask FPSCR value to clear RN. */ 653 + tcg_gen_andi_i64(t0, t0, ~FP_RN); 654 + 655 + /* Merge RN into FPSCR value. */ 656 + tcg_gen_or_i64(t0, t0, t1); 657 + 658 + gen_helper_store_fpscr(cpu_env, t0, mask); 659 + 660 + tcg_temp_free_i32(mask); 661 + tcg_temp_free_i64(t0); 662 + } 663 + 664 + /* mffscrn */ 665 + static void gen_mffscrn(DisasContext *ctx) 666 + { 667 + TCGv_i64 t1; 668 + 669 + if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { 670 + return gen_mffs(ctx); 671 + } 672 + 673 + if (unlikely(!ctx->fpu_enabled)) { 674 + gen_exception(ctx, POWERPC_EXCP_FPU); 675 + return; 676 + } 677 + 678 + t1 = tcg_temp_new_i64(); 679 + get_fpr(t1, rB(ctx->opcode)); 680 + /* Mask FRB to get just RN. */ 681 + tcg_gen_andi_i64(t1, t1, FP_RN); 682 + 683 + gen_helper_mffscrn(ctx, t1); 684 + 685 + tcg_temp_free_i64(t1); 686 + } 687 + 688 + /* mffscrni */ 689 + static void gen_mffscrni(DisasContext *ctx) 690 + { 691 + TCGv_i64 t1; 692 + 693 + if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { 694 + return gen_mffs(ctx); 695 + } 696 + 697 + if (unlikely(!ctx->fpu_enabled)) { 698 + gen_exception(ctx, POWERPC_EXCP_FPU); 699 + return; 700 + } 701 + 702 + t1 = tcg_const_i64((uint64_t)RM(ctx->opcode)); 703 + 704 + gen_helper_mffscrn(ctx, t1); 705 + 706 + tcg_temp_free_i64(t1); 640 707 } 641 708 642 709 /* mtfsb0 */
+4
target/ppc/translate/fp-ops.inc.c
··· 107 107 GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE), 108 108 GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT, 109 109 PPC2_ISA300), 110 + GEN_HANDLER_E_2(mffscrn, 0x3F, 0x07, 0x12, 0x16, 0x00000000, PPC_FLOAT, 111 + PPC_NONE), 112 + GEN_HANDLER_E_2(mffscrni, 0x3F, 0x07, 0x12, 0x17, 0x00000000, PPC_FLOAT, 113 + PPC_NONE), 110 114 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT), 111 115 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT), 112 116 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),