Changeset 103896 in vbox for trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-3.c32
- Timestamp:
- Mar 18, 2024 2:59:49 PM (11 months ago)
- svn:sync-xref-src-repo-rev:
- 162268
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-3.c32
r103887 r103896 145 145 /** Buffer of g_cbBuf size. */ 146 146 static uint8_t BS3_FAR *g_pbBuf; 147 /** RW alias for the buffer memory at g_pbBuf. Set up by bs3CpuInstr3BufSetup. */ 148 static uint8_t BS3_FAR *g_pbBufAlias; 149 /** RW alias for the memory at g_pbBuf. */ 150 static uint8_t BS3_FAR *g_pbBufAliasAlloc; 147 151 148 152 /** Exception type \#1 test configurations, 16 & 32 bytes strictly aligned. */ … … 480 484 if (BS3_MODE_IS_PAGED(bMode)) 481 485 { 486 int rc; 482 487 uint32_t cbBuf = *pcbBuf; 483 488 Bs3PagingProtectPtr(&pbBuf[0], X86_PAGE_SIZE, 0, X86_PTE_P); … … 486 491 cbBuf -= X86_PAGE_SIZE * 2; 487 492 *pcbBuf = cbBuf; 493 494 g_pbBufAlias = g_pbBufAliasAlloc; 495 rc = Bs3PagingAlias((uintptr_t)g_pbBufAlias, (uintptr_t)pbBuf, cbBuf + X86_PAGE_SIZE, /* must include the tail guard pg */ 496 X86_PTE_P | X86_PTE_A | X86_PTE_D | X86_PTE_RW); 497 if (RT_FAILURE(rc)) 498 Bs3TestFailedF("Bs3PagingAlias failed on %p/%p LB %#x: %d", g_pbBufAlias, pbBuf, cbBuf, rc); 488 499 } 500 else 501 g_pbBufAlias = pbBuf; 489 502 return pbBuf; 490 503 } … … 518 531 * @param cbAlign The operand alignment restriction. 519 532 * @param pConfig The configuration. 533 * @param fPageFault The \#PF test setting. 520 534 */ 521 535 DECLINLINE(PRTUINT256U) bs3CpuInstr3BufForOperand(uint8_t BS3_FAR *pbBuf, uint32_t cbBuf, uint8_t cbMemOp, uint8_t cbAlign, 522 PCBS3CPUINSTR3_CONFIG_T pConfig) 523 { 536 PCBS3CPUINSTR3_CONFIG_T pConfig, unsigned fPageFault) 537 { 538 /* All allocations are at the tail end of the buffer, so that we've got a 539 guard page following the operand. When asked to consistenly trigger 540 a #PF, we slide the buffer into that guard page. */ 541 if (fPageFault) 542 cbBuf += X86_PAGE_SIZE; 543 524 544 if (pConfig->fAligned) 525 545 { … … 714 734 for (;;) 715 735 { 716 unsigned iCfg;717 for (iCfg = 0; iCfg < cConfigs; iCfg++)736 unsigned fPf = 0; 737 do 718 738 { 719 unsigned iTest; 720 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 721 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 722 continue; /* unsupported config */ 723 724 /* 725 * Iterate the tests. 726 */ 727 for (iTest = 0; iTest < cTests; iTest++) 739 unsigned iCfg; 740 for (iCfg = 0; iCfg < cConfigs; iCfg++) 728 741 { 729 BS3CPUINSTR3_TEST1_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 730 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 731 unsigned const cValues = paTests[iTest].cValues; 732 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 733 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 734 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 735 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 736 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 737 uint8_t const cbMemOp = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm); 738 uint8_t const cbAlign = cbMemOp; 739 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]); 740 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 741 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 742 : fSseInstr ? paConfigs[iCfg].bXcptSse 743 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 744 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 745 unsigned cRecompRuns = 0; 746 unsigned iVal; 747 748 /* If testing unaligned memory accesses, skip register-only tests. This allows 749 setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 750 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck)) 751 continue; 752 753 /* #AC is only raised in ring-3.: */ 754 if (bXcptExpect == X86_XCPT_AC) 742 unsigned iTest; 743 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 744 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 745 continue; /* unsupported config */ 746 747 /* 748 * Iterate the tests. 749 */ 750 for (iTest = 0; iTest < cTests; iTest++) 755 751 { 756 if (bRing != 3) 757 bXcptExpect = X86_XCPT_DB; 758 else if (fAvxInstr) 759 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 752 BS3CPUINSTR3_TEST1_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 753 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 754 unsigned const cValues = paTests[iTest].cValues; 755 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 756 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 757 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 758 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 759 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 760 uint8_t const cbMemOp = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm); 761 uint8_t const cbAlign = cbMemOp; 762 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf); 763 PRTUINT256U puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf]; 764 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 765 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 766 : fSseInstr ? paConfigs[iCfg].bXcptSse 767 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 768 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 769 unsigned cRecompRuns = 0; 770 unsigned iVal; 771 772 /* If testing unaligned memory accesses (or #PF), skip register-only tests. This 773 allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 774 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf)) 775 continue; 776 777 /* #AC is only raised in ring-3.: */ 778 if (bXcptExpect == X86_XCPT_AC) 779 { 780 if (bRing != 3) 781 bXcptExpect = X86_XCPT_DB; 782 else if (fAvxInstr) 783 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 784 } 785 786 if (fPf && bXcptExpect == X86_XCPT_DB) 787 bXcptExpect = X86_XCPT_PF; 788 789 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 790 791 /* 792 * Iterate the test values and do the actual testing. 793 */ 794 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 795 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 796 { 797 uint16_t cErrors; 798 uint16_t uSavedFtw = 0xff; 799 RTUINT256U uMemOpExpect; 800 801 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 802 803 /* 804 * Set up the context and some expectations. 805 */ 806 /* dest */ 807 if (paTests[iTest].iRegDst == UINT8_MAX) 808 { 809 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 810 Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp); 811 if (bXcptExpect == X86_XCPT_DB) 812 uMemOpExpect = paValues[iVal].uDstOut; 813 else 814 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 815 } 816 else if (fMmxInstr) 817 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 818 819 /* source #1 (/ destination for MMX and SSE) */ 820 if (paTests[iTest].iRegSrc1 == UINT8_MAX) 821 { 822 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 823 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc1, cbMemOp); 824 if (paTests[iTest].iRegDst == UINT8_MAX) 825 BS3_ASSERT(fSseInstr); 826 else 827 uMemOpExpect = paValues[iVal].uSrc1; 828 } 829 else if (fMmxInstr) 830 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 831 else if (fSseInstr) 832 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0); 833 else 834 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32); 835 836 /* source #2 */ 837 if (paTests[iTest].iRegSrc2 == UINT8_MAX) 838 { 839 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 840 BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX); 841 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc2, cbMemOp); 842 uMemOpExpect = paValues[iVal].uSrc2; 843 } 844 else if (fMmxInstr) 845 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 846 else if (fSseInstr) 847 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0); 848 else 849 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32); 850 851 /* Memory pointer. */ 852 if (paTests[iTest].enmRm >= RM_MEM) 853 { 854 BS3_ASSERT( paTests[iTest].iRegDst == UINT8_MAX 855 || paTests[iTest].iRegSrc1 == UINT8_MAX 856 || paTests[iTest].iRegSrc2 == UINT8_MAX); 857 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 858 } 859 860 /* 861 * Execute. 862 */ 863 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 864 865 /* 866 * Check the result: 867 */ 868 cErrors = Bs3TestSubErrorCount(); 869 870 if (fMmxInstr && bXcptExpect == X86_XCPT_DB) 871 { 872 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 873 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); /* Observed on 10980xe after pxor mm1, mm2. */ 874 } 875 if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX) 876 { 877 if (fMmxInstr) 878 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET); 879 else if (fSseInstr) 880 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0); 881 else 882 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand); 883 } 884 #if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */ 885 if ( pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE 886 && pExtCtx->Ctx.x.Hdr.bmXState == 0x7 887 && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3) 888 pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7; 889 #endif 890 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 891 892 if (TrapFrame.bXcpt != bXcptExpect) 893 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 894 895 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 896 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 897 { 898 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 899 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 900 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 901 } 902 if (bXcptExpect == X86_XCPT_PF) 903 Ctx.cr2.u = (uintptr_t)puMemOp; 904 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 905 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 906 pszMode, idTestStep); 907 Ctx.cr2.u = 0; 908 909 if ( paTests[iTest].enmRm >= RM_MEM 910 && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0) 911 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias); 912 913 if (cErrors != Bs3TestSubErrorCount()) 914 { 915 if (paConfigs[iCfg].fAligned) 916 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 917 bRing, iCfg, iTest, iVal, bXcptExpect); 918 else 919 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 920 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 921 Bs3TestPrintf("\n"); 922 } 923 924 if (uSavedFtw != 0xff) 925 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 926 } 760 927 } 761 928 762 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 763 764 /* 765 * Iterate the test values and do the actual testing. 766 */ 767 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 768 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 769 { 770 uint16_t cErrors; 771 uint16_t uSavedFtw = 0xff; 772 RTUINT256U uMemOpExpect; 773 774 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 775 776 /* 777 * Set up the context and some expectations. 778 */ 779 /* dest */ 780 if (paTests[iTest].iRegDst == UINT8_MAX) 781 { 782 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 783 Bs3MemSet(puMemOp, 0xcc, cbMemOp); 784 if (bXcptExpect == X86_XCPT_DB) 785 uMemOpExpect = paValues[iVal].uDstOut; 786 else 787 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 788 } 789 else if (fMmxInstr) 790 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 791 792 /* source #1 (/ destination for MMX and SSE) */ 793 if (paTests[iTest].iRegSrc1 == UINT8_MAX) 794 { 795 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 796 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc1, cbMemOp); 797 if (paTests[iTest].iRegDst == UINT8_MAX) 798 BS3_ASSERT(fSseInstr); 799 else 800 uMemOpExpect = paValues[iVal].uSrc1; 801 } 802 else if (fMmxInstr) 803 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 804 else if (fSseInstr) 805 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0); 806 else 807 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32); 808 809 /* source #2 */ 810 if (paTests[iTest].iRegSrc2 == UINT8_MAX) 811 { 812 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 813 BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX); 814 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc2, cbMemOp); 815 uMemOpExpect = paValues[iVal].uSrc2; 816 } 817 else if (fMmxInstr) 818 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 819 else if (fSseInstr) 820 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0); 821 else 822 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32); 823 824 /* Memory pointer. */ 825 if (paTests[iTest].enmRm >= RM_MEM) 826 { 827 BS3_ASSERT( paTests[iTest].iRegDst == UINT8_MAX 828 || paTests[iTest].iRegSrc1 == UINT8_MAX 829 || paTests[iTest].iRegSrc2 == UINT8_MAX); 830 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 831 } 832 833 /* 834 * Execute. 835 */ 836 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 837 838 /* 839 * Check the result: 840 */ 841 cErrors = Bs3TestSubErrorCount(); 842 843 if (fMmxInstr && bXcptExpect == X86_XCPT_DB) 844 { 845 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 846 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); /* Observed on 10980xe after pxor mm1, mm2. */ 847 } 848 if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX) 849 { 850 if (fMmxInstr) 851 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET); 852 else if (fSseInstr) 853 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0); 854 else 855 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand); 856 } 857 #if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */ 858 if ( pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE 859 && pExtCtx->Ctx.x.Hdr.bmXState == 0x7 860 && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3) 861 pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7; 862 #endif 863 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 864 865 if (TrapFrame.bXcpt != bXcptExpect) 866 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 867 868 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 869 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 870 { 871 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 872 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 873 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 874 } 875 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 876 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 877 pszMode, idTestStep); 878 879 if ( paTests[iTest].enmRm >= RM_MEM 880 && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0) 881 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp); 882 883 if (cErrors != Bs3TestSubErrorCount()) 884 { 885 if (paConfigs[iCfg].fAligned) 886 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 887 bRing, iCfg, iTest, iVal, bXcptExpect); 888 else 889 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 890 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 891 Bs3TestPrintf("\n"); 892 } 893 894 if (uSavedFtw != 0xff) 895 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 896 } 929 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 897 930 } 898 899 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 900 } 931 } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode)); 901 932 902 933 /* … … 9187 9218 for (;;) 9188 9219 { 9189 unsigned iCfg;9190 for (iCfg = 0; iCfg < cConfigs; iCfg++)9220 unsigned fPf = 0; 9221 do 9191 9222 { 9192 unsigned iTest; 9193 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 9194 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 9195 continue; /* unsupported config */ 9196 9197 /* 9198 * Iterate the tests. 9199 */ 9200 for (iTest = 0; iTest < cTests; iTest++) 9223 unsigned iCfg; 9224 for (iCfg = 0; iCfg < cConfigs; iCfg++) 9201 9225 { 9202 BS3CPUINSTR3_TEST2_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 9203 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 9204 unsigned const cValues = paTests[iTest].cValues; 9205 bool const fGprDst = paTests[iTest].fGprDst; 9206 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 9207 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 9208 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 9209 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 9210 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 9211 uint8_t const cbMemOp = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm); 9212 uint8_t const cbAlign = RT_MIN(cbOperand, 16); 9213 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]); 9214 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] 9215 || paTests[iTest].fInvalidEncoding ? X86_XCPT_UD 9216 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 9217 : fSseInstr ? paConfigs[iCfg].bXcptSse 9218 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 9219 uint64_t const fGprValMask = paTests[iTest].cBitsGprValMask == 64 ? UINT64_MAX 9220 : RT_BIT_64(paTests[iTest].cBitsGprValMask) - 1; 9221 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 9222 unsigned cRecompRuns = 0; 9223 unsigned iVal; 9224 9225 /* If testing unaligned memory accesses, skip register-only tests. This allows 9226 setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 9227 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck)) 9228 continue; 9229 9230 /* #AC is only raised in ring-3.: */ 9231 if (bXcptExpect == X86_XCPT_AC) 9226 unsigned iTest; 9227 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 9228 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 9229 continue; /* unsupported config */ 9230 9231 /* 9232 * Iterate the tests. 9233 */ 9234 for (iTest = 0; iTest < cTests; iTest++) 9232 9235 { 9233 if (bRing != 3) 9234 bXcptExpect = X86_XCPT_DB; 9235 else if (fAvxInstr) 9236 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 9237 } 9238 9239 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 9240 9241 /* 9242 * Iterate the test values and do the actual testing. 9243 */ 9244 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 9245 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 9236 BS3CPUINSTR3_TEST2_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 9237 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 9238 unsigned const cValues = paTests[iTest].cValues; 9239 bool const fGprDst = paTests[iTest].fGprDst; 9240 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 9241 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 9242 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 9243 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 9244 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 9245 uint8_t const cbMemOp = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm); 9246 uint8_t const cbAlign = RT_MIN(cbOperand, 16); 9247 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf); 9248 PRTUINT256U puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf]; 9249 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] 9250 || paTests[iTest].fInvalidEncoding ? X86_XCPT_UD 9251 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 9252 : fSseInstr ? paConfigs[iCfg].bXcptSse 9253 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 9254 uint64_t const fGprValMask = paTests[iTest].cBitsGprValMask == 64 ? UINT64_MAX 9255 : RT_BIT_64(paTests[iTest].cBitsGprValMask) - 1; 9256 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 9257 unsigned cRecompRuns = 0; 9258 unsigned iVal; 9259 9260 /* If testing unaligned memory accesses (or #PFs), skip register-only tests. This 9261 allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 9262 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf)) 9263 continue; 9264 9265 /* #AC is only raised in ring-3.: */ 9266 if (bXcptExpect == X86_XCPT_AC) 9246 9267 { 9247 uint16_t cErrors; 9248 uint16_t uSavedFtw = 0xff; 9249 RTUINT256U uMemOpExpect; 9250 9251 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 9252 9253 /* 9254 * Set up the context and some expectations. 9255 */ 9256 if (fGprDst) 9268 if (bRing != 3) 9269 bXcptExpect = X86_XCPT_DB; 9270 else if (fAvxInstr) 9271 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 9272 } 9273 9274 if (fPf && bXcptExpect == X86_XCPT_DB) 9275 bXcptExpect = X86_XCPT_PF; 9276 9277 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 9278 9279 /* 9280 * Iterate the test values and do the actual testing. 9281 */ 9282 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 9283 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 9257 9284 { 9258 /* dest - gpr/mem */ 9259 if (paTests[iTest].iGprReg == UINT8_MAX) 9285 uint16_t cErrors; 9286 uint16_t uSavedFtw = 0xff; 9287 RTUINT256U uMemOpExpect; 9288 9289 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 9290 9291 /* 9292 * Set up the context and some expectations. 9293 */ 9294 if (fGprDst) 9260 9295 { 9261 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9262 Bs3MemSet(puMemOp, 0xcc, cbMemOp); 9263 if (bXcptExpect != X86_XCPT_DB) 9264 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 9265 else 9296 /* dest - gpr/mem */ 9297 if (paTests[iTest].iGprReg == UINT8_MAX) 9266 9298 { 9267 Bs3MemSet(&uMemOpExpect, 0xaa, sizeof(uMemOpExpect)); 9268 switch (paTests[iTest].cbGpr) 9299 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9300 Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp); 9301 if (bXcptExpect != X86_XCPT_DB) 9302 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 9303 else 9269 9304 { 9270 case 1: uMemOpExpect.au8[0] = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break; 9271 case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break; 9272 case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break; 9273 case 8: uMemOpExpect.au64[0] = (paValues[iVal].uGpr & fGprValMask); break; 9274 default: BS3_ASSERT(0); 9305 Bs3MemSet(&uMemOpExpect, 0xaa, sizeof(uMemOpExpect)); 9306 switch (paTests[iTest].cbGpr) 9307 { 9308 case 1: uMemOpExpect.au8[0] = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break; 9309 case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break; 9310 case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break; 9311 case 8: uMemOpExpect.au64[0] = (paValues[iVal].uGpr & fGprValMask); break; 9312 default: BS3_ASSERT(0); 9313 } 9275 9314 } 9276 9315 } 9316 else 9317 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, UINT64_C(0xcccccccccccccccc), 9318 BS3_MODE_IS_64BIT_CODE(bMode) ? 8 : 4); /* we only restore 63:32 when bMode==LM64 */ 9319 9320 /* source - media/mem */ 9321 if (paTests[iTest].iMediaReg == UINT8_MAX) 9322 { 9323 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9324 BS3_ASSERT(paTests[iTest].iGprReg != UINT8_MAX); 9325 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uMedia, cbMemOp); 9326 uMemOpExpect = paValues[iVal].uMedia; 9327 } 9328 else if (fMmxInstr) 9329 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaReg, paValues[iVal].uMedia.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 9330 else if (fSseInstr) 9331 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia.DQWords.dqw0); 9332 else 9333 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia, 32); 9277 9334 } 9278 9335 else 9279 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, UINT64_C(0xcccccccccccccccc),9280 BS3_MODE_IS_64BIT_CODE(bMode) ? 8 : 4); /* we only restore 63:32 when bMode==LM64 */9281 9282 /* source - media/mem */9283 if (paTests[iTest].iMediaReg == UINT8_MAX)9284 9336 { 9285 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9286 BS3_ASSERT(paTests[iTest].iGprReg != UINT8_MAX); 9287 Bs3MemCpy(puMemOp, &paValues[iVal].uMedia, cbMemOp); 9288 uMemOpExpect = paValues[iVal].uMedia; 9337 /* dest - media */ 9338 if (paTests[iTest].iMediaReg == UINT8_MAX) 9339 { 9340 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9341 Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp); 9342 if (bXcptExpect == X86_XCPT_DB) 9343 uMemOpExpect = paValues[iVal].uMedia; 9344 else 9345 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 9346 } 9347 9348 /* source - gpr/mem */ 9349 if (paTests[iTest].iGprReg == UINT8_MAX) 9350 { 9351 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9352 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 9353 if (bXcptExpect == X86_XCPT_DB) 9354 switch (paTests[iTest].cbGpr) 9355 { 9356 case 1: uMemOpExpect.au8[0] = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break; 9357 case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break; 9358 case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break; 9359 case 8: uMemOpExpect.au64[0] = (paValues[iVal].uGpr & fGprValMask); break; 9360 default: BS3_ASSERT(0); 9361 } 9362 Bs3MemCpy(puMemOpAlias, &uMemOpExpect, cbMemOp); 9363 } 9364 else 9365 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, paTests[iTest].cbGpr); 9289 9366 } 9290 else if (fMmxInstr) 9291 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaReg, paValues[iVal].uMedia.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 9292 else if (fSseInstr) 9293 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia.DQWords.dqw0); 9294 else 9295 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia, 32); 9367 9368 /* Memory pointer. */ 9369 if (paTests[iTest].enmRm >= RM_MEM) 9370 { 9371 BS3_ASSERT(paTests[iTest].iGprReg == UINT8_MAX || paTests[iTest].iMediaReg == UINT8_MAX); 9372 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 9373 } 9374 9375 /* 9376 * Execute. 9377 */ 9378 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 9379 9380 /* 9381 * Check the result: 9382 */ 9383 cErrors = Bs3TestSubErrorCount(); 9384 9385 if (fMmxInstr && bXcptExpect == X86_XCPT_DB) 9386 { 9387 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 9388 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); 9389 } 9390 if (!fGprDst && bXcptExpect == X86_XCPT_DB && paTests[iTest].iMediaReg != UINT8_MAX) 9391 { 9392 if (fMmxInstr) 9393 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaReg, paValues[iVal].uMedia.QWords.qw0, BS3EXTCTXTOPMM_SET); 9394 else if (fSseInstr) 9395 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia.DQWords.dqw0); 9396 else 9397 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia, 32); 9398 } 9399 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 9400 9401 if (TrapFrame.bXcpt != bXcptExpect) 9402 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 9403 9404 if (fGprDst && bXcptExpect == X86_XCPT_DB && paTests[iTest].iGprReg != UINT8_MAX) 9405 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, 9406 paTests[iTest].cbGpr >= 4 ? 8 : paTests[iTest].cbGpr); 9407 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 9408 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 9409 { 9410 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 9411 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 9412 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 9413 } 9414 if (bXcptExpect == X86_XCPT_PF) 9415 Ctx.cr2.u = (uintptr_t)puMemOp; 9416 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 9417 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 9418 pszMode, idTestStep); 9419 Ctx.cr2.u = 0; 9420 9421 if ( paTests[iTest].enmRm >= RM_MEM 9422 && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0) 9423 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias); 9424 9425 if (cErrors != Bs3TestSubErrorCount()) 9426 { 9427 if (paConfigs[iCfg].fAligned) 9428 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 9429 bRing, iCfg, iTest, iVal, bXcptExpect); 9430 else 9431 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 9432 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 9433 Bs3TestPrintf("\n"); 9434 } 9435 9436 if (uSavedFtw != 0xff) 9437 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 9296 9438 } 9297 else 9298 { 9299 /* dest - media */ 9300 if (paTests[iTest].iMediaReg == UINT8_MAX) 9301 { 9302 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9303 Bs3MemSet(puMemOp, 0xcc, cbMemOp); 9304 if (bXcptExpect == X86_XCPT_DB) 9305 uMemOpExpect = paValues[iVal].uMedia; 9306 else 9307 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 9308 } 9309 9310 /* source - gpr/mem */ 9311 if (paTests[iTest].iGprReg == UINT8_MAX) 9312 { 9313 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9314 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 9315 if (bXcptExpect == X86_XCPT_DB) 9316 switch (paTests[iTest].cbGpr) 9317 { 9318 case 1: uMemOpExpect.au8[0] = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break; 9319 case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break; 9320 case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break; 9321 case 8: uMemOpExpect.au64[0] = (paValues[iVal].uGpr & fGprValMask); break; 9322 default: BS3_ASSERT(0); 9323 } 9324 Bs3MemCpy(puMemOp, &uMemOpExpect, cbMemOp); 9325 } 9326 else 9327 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, paTests[iTest].cbGpr); 9328 } 9329 9330 /* Memory pointer. */ 9331 if (paTests[iTest].enmRm >= RM_MEM) 9332 { 9333 BS3_ASSERT(paTests[iTest].iGprReg == UINT8_MAX || paTests[iTest].iMediaReg == UINT8_MAX); 9334 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 9335 } 9336 9337 /* 9338 * Execute. 9339 */ 9340 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 9341 9342 /* 9343 * Check the result: 9344 */ 9345 cErrors = Bs3TestSubErrorCount(); 9346 9347 if (fMmxInstr && bXcptExpect == X86_XCPT_DB) 9348 { 9349 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 9350 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); 9351 } 9352 if (!fGprDst && bXcptExpect == X86_XCPT_DB && paTests[iTest].iMediaReg != UINT8_MAX) 9353 { 9354 if (fMmxInstr) 9355 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaReg, paValues[iVal].uMedia.QWords.qw0, BS3EXTCTXTOPMM_SET); 9356 else if (fSseInstr) 9357 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia.DQWords.dqw0); 9358 else 9359 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaReg, &paValues[iVal].uMedia, 32); 9360 } 9361 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 9362 9363 if (TrapFrame.bXcpt != bXcptExpect) 9364 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 9365 9366 if (fGprDst && bXcptExpect == X86_XCPT_DB && paTests[iTest].iGprReg != UINT8_MAX) 9367 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, 9368 paTests[iTest].cbGpr >= 4 ? 8 : paTests[iTest].cbGpr); 9369 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 9370 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 9371 { 9372 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 9373 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 9374 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 9375 } 9376 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 9377 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 9378 pszMode, idTestStep); 9379 9380 if ( paTests[iTest].enmRm >= RM_MEM 9381 && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0) 9382 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp); 9383 9384 if (cErrors != Bs3TestSubErrorCount()) 9385 { 9386 if (paConfigs[iCfg].fAligned) 9387 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 9388 bRing, iCfg, iTest, iVal, bXcptExpect); 9389 else 9390 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 9391 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 9392 Bs3TestPrintf("\n"); 9393 } 9394 9395 if (uSavedFtw != 0xff) 9396 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 9397 } 9439 } 9440 9441 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 9398 9442 } 9399 9400 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 9401 } 9443 } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode)); 9402 9444 9403 9445 /* … … 9906 9948 for (;;) 9907 9949 { 9908 unsigned iCfg;9909 for (iCfg = 0; iCfg < cConfigs; iCfg++)9950 unsigned fPf = 0; 9951 do 9910 9952 { 9911 unsigned iTest; 9912 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 9913 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 9914 continue; /* unsupported config */ 9915 9916 /* 9917 * Iterate the tests. 9918 */ 9919 for (iTest = 0; iTest < cTests; iTest++) 9953 unsigned iCfg; 9954 for (iCfg = 0; iCfg < cConfigs; iCfg++) 9920 9955 { 9921 BS3CPUINSTR3_TEST3_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 9922 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 9923 unsigned const cValues = paTests[iTest].cValues; 9924 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 9925 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 9926 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 9927 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 9928 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 9929 uint8_t const cbMemOp = cbOperand; 9930 uint8_t const cbAlign = RT_MIN(cbOperand, !cbMaxAlign ? 16 : cbMaxAlign); 9931 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]); 9932 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 9933 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 9934 : fSseInstr ? paConfigs[iCfg].bXcptSse 9935 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 9936 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 9937 unsigned cRecompRuns = 0; 9938 unsigned iVal; 9939 9940 /* If testing unaligned memory accesses, skip register-only tests. This allows 9941 setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 9942 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck)) 9943 continue; 9944 9945 /* #AC is only raised in ring-3.: */ 9946 if (bXcptExpect == X86_XCPT_AC) 9956 unsigned iTest; 9957 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 9958 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 9959 continue; /* unsupported config */ 9960 9961 /* 9962 * Iterate the tests. 9963 */ 9964 for (iTest = 0; iTest < cTests; iTest++) 9947 9965 { 9948 if (bRing != 3) 9949 bXcptExpect = X86_XCPT_DB; 9950 else if (fAvxInstr) 9951 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 9966 BS3CPUINSTR3_TEST3_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 9967 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 9968 unsigned const cValues = paTests[iTest].cValues; 9969 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 9970 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 9971 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 9972 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 9973 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 9974 uint8_t const cbMemOp = cbOperand; 9975 uint8_t const cbAlign = RT_MIN(cbOperand, !cbMaxAlign ? 16 : cbMaxAlign); 9976 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf); 9977 PRTUINT256U puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf]; 9978 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 9979 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 9980 : fSseInstr ? paConfigs[iCfg].bXcptSse 9981 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 9982 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 9983 unsigned cRecompRuns = 0; 9984 unsigned iVal; 9985 9986 /* If testing unaligned memory accesses (or #PF), skip register-only tests. This 9987 allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 9988 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf)) 9989 continue; 9990 9991 /* #AC is only raised in ring-3.: */ 9992 if (bXcptExpect == X86_XCPT_AC) 9993 { 9994 if (bRing != 3) 9995 bXcptExpect = X86_XCPT_DB; 9996 else if (fAvxInstr) 9997 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 9998 } 9999 10000 if (fPf && bXcptExpect == X86_XCPT_DB) 10001 bXcptExpect = X86_XCPT_PF; 10002 10003 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 10004 10005 /* 10006 * Iterate the test values and do the actual testing. 10007 */ 10008 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 10009 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 10010 { 10011 uint16_t cErrors; 10012 uint16_t uSavedFtw = 0xff; 10013 RTUINT256U uMemOpExpect; 10014 10015 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 10016 10017 /* 10018 * Set up the context and some expectations. 10019 */ 10020 /* dest */ 10021 if (paTests[iTest].iRegDst == UINT8_MAX) 10022 { 10023 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 10024 Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp); 10025 if (bXcptExpect == X86_XCPT_DB) 10026 uMemOpExpect = paValues[iVal].uDstOut; 10027 else 10028 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 10029 } 10030 else if (fMmxInstr) 10031 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 10032 10033 /* source */ 10034 if (paTests[iTest].iRegSrc == UINT8_MAX) 10035 { 10036 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 10037 BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX); 10038 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc, cbMemOp); 10039 uMemOpExpect = paValues[iVal].uSrc; 10040 } 10041 else if (fMmxInstr) 10042 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc, paValues[iVal].uSrc.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 10043 else if (fSseInstr) 10044 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc, &paValues[iVal].uSrc.DQWords.dqw0); 10045 else 10046 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc, &paValues[iVal].uSrc, 32); 10047 10048 /* Memory pointer. */ 10049 if (paTests[iTest].enmRm >= RM_MEM) 10050 { 10051 BS3_ASSERT( paTests[iTest].iRegDst == UINT8_MAX 10052 || paTests[iTest].iRegSrc == UINT8_MAX); 10053 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 10054 } 10055 10056 /* 10057 * Execute. 10058 */ 10059 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 10060 10061 /* 10062 * Check the result: 10063 */ 10064 cErrors = Bs3TestSubErrorCount(); 10065 10066 if (bXcptExpect == X86_XCPT_DB && fMmxInstr) 10067 { 10068 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 10069 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); 10070 } 10071 if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX) 10072 { 10073 if (fMmxInstr) 10074 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET); 10075 else if (fSseInstr) 10076 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0); 10077 else 10078 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand); 10079 } 10080 10081 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 10082 10083 if (TrapFrame.bXcpt != bXcptExpect) 10084 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 10085 10086 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 10087 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 10088 { 10089 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 10090 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 10091 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 10092 } 10093 if (bXcptExpect == X86_XCPT_PF) 10094 Ctx.cr2.u = (uintptr_t)puMemOp; 10095 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 10096 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 10097 pszMode, idTestStep); 10098 Ctx.cr2.u = 0; 10099 10100 if ( paTests[iTest].enmRm >= RM_MEM 10101 && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0) 10102 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias); 10103 10104 if (cErrors != Bs3TestSubErrorCount()) 10105 { 10106 if (paConfigs[iCfg].fAligned) 10107 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 10108 bRing, iCfg, iTest, iVal, bXcptExpect); 10109 else 10110 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 10111 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 10112 Bs3TestPrintf("\n"); 10113 } 10114 10115 if (uSavedFtw != 0xff) 10116 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 10117 } 9952 10118 } 9953 10119 9954 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 9955 9956 /* 9957 * Iterate the test values and do the actual testing. 9958 */ 9959 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 9960 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 9961 { 9962 uint16_t cErrors; 9963 uint16_t uSavedFtw = 0xff; 9964 RTUINT256U uMemOpExpect; 9965 9966 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 9967 9968 /* 9969 * Set up the context and some expectations. 9970 */ 9971 /* dest */ 9972 if (paTests[iTest].iRegDst == UINT8_MAX) 9973 { 9974 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9975 Bs3MemSet(puMemOp, 0xcc, cbMemOp); 9976 if (bXcptExpect == X86_XCPT_DB) 9977 uMemOpExpect = paValues[iVal].uDstOut; 9978 else 9979 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 9980 } 9981 else if (fMmxInstr) 9982 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 9983 9984 /* source */ 9985 if (paTests[iTest].iRegSrc == UINT8_MAX) 9986 { 9987 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 9988 BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX); 9989 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc, cbMemOp); 9990 uMemOpExpect = paValues[iVal].uSrc; 9991 } 9992 else if (fMmxInstr) 9993 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc, paValues[iVal].uSrc.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 9994 else if (fSseInstr) 9995 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc, &paValues[iVal].uSrc.DQWords.dqw0); 9996 else 9997 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc, &paValues[iVal].uSrc, 32); 9998 9999 /* Memory pointer. */ 10000 if (paTests[iTest].enmRm >= RM_MEM) 10001 { 10002 BS3_ASSERT( paTests[iTest].iRegDst == UINT8_MAX 10003 || paTests[iTest].iRegSrc == UINT8_MAX); 10004 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 10005 } 10006 10007 /* 10008 * Execute. 10009 */ 10010 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 10011 10012 /* 10013 * Check the result: 10014 */ 10015 cErrors = Bs3TestSubErrorCount(); 10016 10017 if (bXcptExpect == X86_XCPT_DB && fMmxInstr) 10018 { 10019 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 10020 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); 10021 } 10022 if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX) 10023 { 10024 if (fMmxInstr) 10025 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET); 10026 else if (fSseInstr) 10027 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0); 10028 else 10029 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand); 10030 } 10031 10032 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 10033 10034 if (TrapFrame.bXcpt != bXcptExpect) 10035 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 10036 10037 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 10038 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 10039 { 10040 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 10041 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 10042 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 10043 } 10044 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 10045 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 10046 pszMode, idTestStep); 10047 10048 if ( paTests[iTest].enmRm >= RM_MEM 10049 && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0) 10050 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp); 10051 10052 if (cErrors != Bs3TestSubErrorCount()) 10053 { 10054 if (paConfigs[iCfg].fAligned) 10055 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 10056 bRing, iCfg, iTest, iVal, bXcptExpect); 10057 else 10058 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 10059 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 10060 Bs3TestPrintf("\n"); 10061 } 10062 10063 if (uSavedFtw != 0xff) 10064 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 10065 } 10120 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 10066 10121 } 10067 10068 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 10069 } 10122 } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode)); 10070 10123 10071 10124 /* … … 12113 12166 for (;;) 12114 12167 { 12115 unsigned iCfg;12116 for (iCfg = 0; iCfg < cConfigs; iCfg++)12168 unsigned fPf = 0; 12169 do 12117 12170 { 12118 unsigned iTest; 12119 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 12120 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 12121 continue; /* unsupported config */ 12122 12123 /* 12124 * Iterate the tests. 12125 */ 12126 for (iTest = 0; iTest < cTests; iTest++) 12171 unsigned iCfg; 12172 for (iCfg = 0; iCfg < cConfigs; iCfg++) 12127 12173 { 12128 BS3CPUINSTR3_TEST4_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 12129 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 12130 unsigned const cValues = paTests[iTest].cValues; 12131 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 12132 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 12133 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 12134 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 12135 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 12136 uint8_t const cbMemOp = cbOperand; 12137 uint8_t const cbAlign = RT_MIN(cbOperand, 16); 12138 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]); 12139 uint8_t const idxEflOut = cbOperand == 32 ? 2 : cbOperand == 16 ? 1 : 0; 12140 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 12141 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 12142 : fSseInstr ? paConfigs[iCfg].bXcptSse 12143 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 12144 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 12145 unsigned cRecompRuns = 0; 12146 unsigned iVal; 12147 12148 /* If testing unaligned memory accesses, skip register-only tests. This allows 12149 setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 12150 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck)) 12151 continue; 12152 12153 /* #AC is only raised in ring-3.: */ 12154 if (bXcptExpect == X86_XCPT_AC) 12174 unsigned iTest; 12175 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 12176 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 12177 continue; /* unsupported config */ 12178 12179 /* 12180 * Iterate the tests. 12181 */ 12182 for (iTest = 0; iTest < cTests; iTest++) 12155 12183 { 12156 if (bRing != 3) 12157 bXcptExpect = X86_XCPT_DB; 12158 else if (fAvxInstr) 12159 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 12184 BS3CPUINSTR3_TEST4_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 12185 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 12186 unsigned const cValues = paTests[iTest].cValues; 12187 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 12188 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 12189 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 12190 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 12191 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 12192 uint8_t const cbMemOp = cbOperand; 12193 uint8_t const cbAlign = RT_MIN(cbOperand, 16); 12194 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf); 12195 PRTUINT256U puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf]; 12196 uint8_t const idxEflOut = cbOperand == 32 ? 2 : cbOperand == 16 ? 1 : 0; 12197 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 12198 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 12199 : fSseInstr ? paConfigs[iCfg].bXcptSse 12200 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 12201 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 12202 unsigned cRecompRuns = 0; 12203 unsigned iVal; 12204 12205 /* If testing unaligned memory accesses (or #PF), skip register-only tests. This 12206 allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 12207 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf)) 12208 continue; 12209 12210 /* #AC is only raised in ring-3.: */ 12211 if (bXcptExpect == X86_XCPT_AC) 12212 { 12213 if (bRing != 3) 12214 bXcptExpect = X86_XCPT_DB; 12215 else if (fAvxInstr) 12216 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 12217 } 12218 12219 if (fPf && bXcptExpect == X86_XCPT_DB) 12220 bXcptExpect = X86_XCPT_PF; 12221 12222 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 12223 12224 /* 12225 * Iterate the test values and do the actual testing. 12226 */ 12227 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues * 2) 12228 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 12229 { 12230 unsigned iEflVariation; 12231 uint32_t const fSavedEfl = Ctx.rflags.u32; 12232 for (iEflVariation = 0; iEflVariation < 2; iEflVariation++) 12233 { 12234 uint16_t cErrors; 12235 uint16_t uSavedFtw = 0xff; 12236 RTUINT256U uMemOpExpect; 12237 12238 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, iEflVariation)) continue; 12239 12240 /* 12241 * Set up the context and some expectations. 12242 */ 12243 /* eflags */ 12244 if (iEflVariation) 12245 Ctx.rflags.u32 = fSavedEfl | X86_EFL_STATUS_BITS; 12246 else 12247 Ctx.rflags.u32 = fSavedEfl & ~X86_EFL_STATUS_BITS; 12248 12249 /* source1 */ 12250 if (paTests[iTest].iRegSrc1 == UINT8_MAX) 12251 { 12252 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12253 BS3_ASSERT(paTests[iTest].iRegSrc2 != UINT8_MAX); 12254 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc1, cbMemOp); 12255 uMemOpExpect = paValues[iVal].uSrc1; 12256 } 12257 else if (fMmxInstr) 12258 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12259 else if (fSseInstr) 12260 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0); 12261 else 12262 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32); 12263 12264 /* source2 */ 12265 if (paTests[iTest].iRegSrc2 == UINT8_MAX) 12266 { 12267 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12268 BS3_ASSERT(paTests[iTest].iRegSrc1 != UINT8_MAX); 12269 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc2, cbMemOp); 12270 uMemOpExpect = paValues[iVal].uSrc2; 12271 } 12272 else if (fMmxInstr) 12273 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12274 else if (fSseInstr) 12275 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0); 12276 else 12277 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32); 12278 12279 /* Memory pointer. */ 12280 if (paTests[iTest].enmRm >= RM_MEM) 12281 { 12282 BS3_ASSERT( paTests[iTest].iRegSrc1 == UINT8_MAX 12283 || paTests[iTest].iRegSrc2 == UINT8_MAX); 12284 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 12285 } 12286 12287 /* 12288 * Execute. 12289 */ 12290 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 12291 12292 /* 12293 * Check the result: 12294 */ 12295 cErrors = Bs3TestSubErrorCount(); 12296 12297 if (bXcptExpect == X86_XCPT_DB && fMmxInstr) 12298 { 12299 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 12300 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); 12301 } 12302 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 12303 12304 if (TrapFrame.bXcpt != bXcptExpect) 12305 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 12306 12307 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 12308 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 12309 { 12310 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 12311 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 12312 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 12313 } 12314 if (bXcptExpect == X86_XCPT_DB) 12315 Ctx.rflags.u32 = (Ctx.rflags.u32 & ~fEflCheck) | paValues[iVal].afEflOut[idxEflOut]; 12316 if (bXcptExpect == X86_XCPT_PF) 12317 Ctx.cr2.u = (uintptr_t)puMemOp; 12318 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 12319 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 12320 pszMode, idTestStep); 12321 Ctx.cr2.u = 0; 12322 12323 if ( paTests[iTest].enmRm >= RM_MEM 12324 && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0) 12325 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias); 12326 12327 if (cErrors != Bs3TestSubErrorCount()) 12328 { 12329 if (paConfigs[iCfg].fAligned) 12330 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u/efl#%u failed (bXcptExpect=%#x)", 12331 bRing, iCfg, iTest, iVal, iEflVariation, bXcptExpect); 12332 else 12333 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u/efl#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 12334 bRing, iCfg, iTest, iVal, iEflVariation, bXcptExpect, 12335 puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 12336 Bs3TestPrintf("\n"); 12337 } 12338 12339 if (uSavedFtw != 0xff) 12340 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 12341 } 12342 Ctx.rflags.u32 = fSavedEfl; 12343 } 12160 12344 } 12161 12345 12162 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 12163 12164 /* 12165 * Iterate the test values and do the actual testing. 12166 */ 12167 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues * 2) 12168 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 12169 { 12170 unsigned iEflVariation; 12171 uint32_t const fSavedEfl = Ctx.rflags.u32; 12172 for (iEflVariation = 0; iEflVariation < 2; iEflVariation++) 12173 { 12174 uint16_t cErrors; 12175 uint16_t uSavedFtw = 0xff; 12176 RTUINT256U uMemOpExpect; 12177 12178 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, iEflVariation)) continue; 12179 12180 /* 12181 * Set up the context and some expectations. 12182 */ 12183 /* eflags */ 12184 if (iEflVariation) 12185 Ctx.rflags.u32 = fSavedEfl | X86_EFL_STATUS_BITS; 12186 else 12187 Ctx.rflags.u32 = fSavedEfl & ~X86_EFL_STATUS_BITS; 12188 12189 /* source1 */ 12190 if (paTests[iTest].iRegSrc1 == UINT8_MAX) 12191 { 12192 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12193 BS3_ASSERT(paTests[iTest].iRegSrc2 != UINT8_MAX); 12194 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc1, cbMemOp); 12195 uMemOpExpect = paValues[iVal].uSrc1; 12196 } 12197 else if (fMmxInstr) 12198 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12199 else if (fSseInstr) 12200 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0); 12201 else 12202 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32); 12203 12204 /* source2 */ 12205 if (paTests[iTest].iRegSrc2 == UINT8_MAX) 12206 { 12207 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12208 BS3_ASSERT(paTests[iTest].iRegSrc1 != UINT8_MAX); 12209 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc2, cbMemOp); 12210 uMemOpExpect = paValues[iVal].uSrc2; 12211 } 12212 else if (fMmxInstr) 12213 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12214 else if (fSseInstr) 12215 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0); 12216 else 12217 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32); 12218 12219 /* Memory pointer. */ 12220 if (paTests[iTest].enmRm >= RM_MEM) 12221 { 12222 BS3_ASSERT( paTests[iTest].iRegSrc1 == UINT8_MAX 12223 || paTests[iTest].iRegSrc2 == UINT8_MAX); 12224 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 12225 } 12226 12227 /* 12228 * Execute. 12229 */ 12230 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 12231 12232 /* 12233 * Check the result: 12234 */ 12235 cErrors = Bs3TestSubErrorCount(); 12236 12237 if (bXcptExpect == X86_XCPT_DB && fMmxInstr) 12238 { 12239 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 12240 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); 12241 } 12242 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 12243 12244 if (TrapFrame.bXcpt != bXcptExpect) 12245 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 12246 12247 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 12248 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 12249 { 12250 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 12251 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 12252 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 12253 } 12254 if (bXcptExpect == X86_XCPT_DB) 12255 Ctx.rflags.u32 = (Ctx.rflags.u32 & ~fEflCheck) | paValues[iVal].afEflOut[idxEflOut]; 12256 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 12257 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 12258 pszMode, idTestStep); 12259 12260 if ( paTests[iTest].enmRm >= RM_MEM 12261 && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0) 12262 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp); 12263 12264 if (cErrors != Bs3TestSubErrorCount()) 12265 { 12266 if (paConfigs[iCfg].fAligned) 12267 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u/efl#%u failed (bXcptExpect=%#x)", 12268 bRing, iCfg, iTest, iVal, iEflVariation, bXcptExpect); 12269 else 12270 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u/efl#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 12271 bRing, iCfg, iTest, iVal, iEflVariation, bXcptExpect, 12272 puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 12273 Bs3TestPrintf("\n"); 12274 } 12275 12276 if (uSavedFtw != 0xff) 12277 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 12278 } 12279 Ctx.rflags.u32 = fSavedEfl; 12280 } 12346 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 12281 12347 } 12282 12283 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 12284 } 12348 } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode)); 12285 12349 12286 12350 /* … … 12443 12507 for (;;) 12444 12508 { 12445 unsigned iCfg;12446 for (iCfg = 0; iCfg < cConfigs; iCfg++)12509 unsigned fPf = 0; 12510 do 12447 12511 { 12448 unsigned iTest; 12449 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 12450 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 12451 continue; /* unsupported config */ 12452 12453 /* 12454 * Iterate the tests. 12455 */ 12456 for (iTest = 0; iTest < cTests; iTest++) 12512 unsigned iCfg; 12513 for (iCfg = 0; iCfg < cConfigs; iCfg++) 12457 12514 { 12458 BS3CPUINSTR3_TEST5_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 12459 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 12460 unsigned const cValues = paTests[iTest].cValues; 12461 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 12462 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 12463 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 12464 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 12465 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 12466 uint8_t const cbMemOp = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm); 12467 uint8_t const cbAlign = cbMemOp; 12468 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]); 12469 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 12470 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 12471 : fSseInstr ? paConfigs[iCfg].bXcptSse 12472 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 12473 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 12474 unsigned cRecompRuns = 0; 12475 unsigned iVal; 12476 12477 /* If testing unaligned memory accesses, skip register-only tests. This allows 12478 setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 12479 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck)) 12480 continue; 12481 12482 /* #AC is only raised in ring-3.: */ 12483 if (bXcptExpect == X86_XCPT_AC) 12515 unsigned iTest; 12516 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 12517 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 12518 continue; /* unsupported config */ 12519 12520 /* 12521 * Iterate the tests. 12522 */ 12523 for (iTest = 0; iTest < cTests; iTest++) 12484 12524 { 12485 if (bRing != 3) 12486 bXcptExpect = X86_XCPT_DB; 12487 else if (fAvxInstr) 12488 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 12525 BS3CPUINSTR3_TEST5_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 12526 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 12527 unsigned const cValues = paTests[iTest].cValues; 12528 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 12529 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 12530 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 12531 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 12532 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 12533 uint8_t const cbMemOp = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm); 12534 uint8_t const cbAlign = cbMemOp; 12535 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf); 12536 PRTUINT256U puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf]; 12537 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 12538 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 12539 : fSseInstr ? paConfigs[iCfg].bXcptSse 12540 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 12541 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 12542 unsigned cRecompRuns = 0; 12543 unsigned iVal; 12544 12545 /* If testing unaligned memory accesses (or #PF), skip register-only tests. This 12546 allows setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 12547 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf)) 12548 continue; 12549 12550 /* #AC is only raised in ring-3: */ 12551 if (bXcptExpect == X86_XCPT_AC) 12552 { 12553 if (bRing != 3) 12554 bXcptExpect = X86_XCPT_DB; 12555 else if (fAvxInstr) 12556 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 12557 } 12558 12559 if (fPf && bXcptExpect == X86_XCPT_DB) 12560 bXcptExpect = X86_XCPT_PF; 12561 12562 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 12563 12564 /* 12565 * Iterate the test values and do the actual testing. 12566 */ 12567 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 12568 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 12569 { 12570 uint16_t cErrors; 12571 uint16_t uSavedFtw = 0xff; 12572 RTUINT256U uMemOpExpect; 12573 12574 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 12575 12576 /* 12577 * Set up the context and some expectations. 12578 */ 12579 /* dest */ 12580 if (paTests[iTest].iRegDst == UINT8_MAX) 12581 { 12582 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12583 Bs3MemSet(puMemOpAlias, 0xcc, cbMemOp); 12584 if (bXcptExpect == X86_XCPT_DB) 12585 uMemOpExpect = paValues[iVal].uDstOut; 12586 else 12587 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 12588 } 12589 else if (fMmxInstr) 12590 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12591 12592 /* source #1 (/ destination for MMX and SSE) */ 12593 if (paTests[iTest].iRegSrc1 == UINT8_MAX) 12594 { 12595 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12596 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc1, cbMemOp); 12597 if (paTests[iTest].iRegDst == UINT8_MAX) 12598 BS3_ASSERT(fSseInstr); 12599 else 12600 uMemOpExpect = paValues[iVal].uSrc1; 12601 } 12602 else if (fMmxInstr) 12603 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12604 else if (fSseInstr) 12605 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0); 12606 else 12607 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32); 12608 12609 /* source #2 */ 12610 if (paTests[iTest].iRegSrc2 == UINT8_MAX) 12611 { 12612 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12613 BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX); 12614 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc2, cbMemOp); 12615 uMemOpExpect = paValues[iVal].uSrc2; 12616 } 12617 else if (fMmxInstr) 12618 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12619 else if (fSseInstr) 12620 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0); 12621 else 12622 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32); 12623 12624 /* source #3 */ 12625 if (paTests[iTest].iRegSrc3 == UINT8_MAX) 12626 { 12627 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12628 BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX); 12629 Bs3MemCpy(puMemOpAlias, &paValues[iVal].uSrc3, cbMemOp); 12630 uMemOpExpect = paValues[iVal].uSrc3; 12631 } 12632 else if (fMmxInstr) 12633 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc3, paValues[iVal].uSrc3.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12634 else if (fSseInstr) 12635 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc3, &paValues[iVal].uSrc3.DQWords.dqw0); 12636 else 12637 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc3, &paValues[iVal].uSrc3, 32); 12638 12639 /* Memory pointer. */ 12640 if (paTests[iTest].enmRm >= RM_MEM) 12641 { 12642 BS3_ASSERT( paTests[iTest].iRegDst == UINT8_MAX 12643 || paTests[iTest].iRegSrc1 == UINT8_MAX 12644 || paTests[iTest].iRegSrc2 == UINT8_MAX 12645 || paTests[iTest].iRegSrc3 == UINT8_MAX); 12646 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 12647 } 12648 12649 /* 12650 * Execute. 12651 */ 12652 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 12653 12654 /* 12655 * Check the result: 12656 */ 12657 cErrors = Bs3TestSubErrorCount(); 12658 12659 if (fMmxInstr && bXcptExpect == X86_XCPT_DB) 12660 { 12661 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 12662 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); /* Observed on 10980xe after pxor mm1, mm2. */ 12663 } 12664 if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX) 12665 { 12666 if (fMmxInstr) 12667 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET); 12668 else if (fSseInstr) 12669 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0); 12670 else 12671 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand); 12672 } 12673 #if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */ 12674 if ( pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE 12675 && pExtCtx->Ctx.x.Hdr.bmXState == 0x7 12676 && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3) 12677 pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7; 12678 #endif 12679 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 12680 12681 if (TrapFrame.bXcpt != bXcptExpect) 12682 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 12683 12684 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 12685 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 12686 { 12687 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 12688 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 12689 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 12690 } 12691 if (bXcptExpect == X86_XCPT_PF) 12692 Ctx.cr2.u = (uintptr_t)puMemOp; 12693 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 12694 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 12695 pszMode, idTestStep); 12696 Ctx.cr2.u = 0; 12697 12698 if ( paTests[iTest].enmRm >= RM_MEM 12699 && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0) 12700 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias); 12701 12702 if (cErrors != Bs3TestSubErrorCount()) 12703 { 12704 if (paConfigs[iCfg].fAligned) 12705 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 12706 bRing, iCfg, iTest, iVal, bXcptExpect); 12707 else 12708 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 12709 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 12710 Bs3TestPrintf("\n"); 12711 } 12712 12713 if (uSavedFtw != 0xff) 12714 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 12715 } 12489 12716 } 12490 12717 12491 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 12492 12493 /* 12494 * Iterate the test values and do the actual testing. 12495 */ 12496 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 12497 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 12498 { 12499 uint16_t cErrors; 12500 uint16_t uSavedFtw = 0xff; 12501 RTUINT256U uMemOpExpect; 12502 12503 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 12504 12505 /* 12506 * Set up the context and some expectations. 12507 */ 12508 /* dest */ 12509 if (paTests[iTest].iRegDst == UINT8_MAX) 12510 { 12511 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12512 Bs3MemSet(puMemOp, 0xcc, cbMemOp); 12513 if (bXcptExpect == X86_XCPT_DB) 12514 uMemOpExpect = paValues[iVal].uDstOut; 12515 else 12516 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 12517 } 12518 else if (fMmxInstr) 12519 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, ~paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12520 12521 /* source #1 (/ destination for MMX and SSE) */ 12522 if (paTests[iTest].iRegSrc1 == UINT8_MAX) 12523 { 12524 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12525 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc1, cbMemOp); 12526 if (paTests[iTest].iRegDst == UINT8_MAX) 12527 BS3_ASSERT(fSseInstr); 12528 else 12529 uMemOpExpect = paValues[iVal].uSrc1; 12530 } 12531 else if (fMmxInstr) 12532 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc1, paValues[iVal].uSrc1.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12533 else if (fSseInstr) 12534 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1.DQWords.dqw0); 12535 else 12536 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc1, &paValues[iVal].uSrc1, 32); 12537 12538 /* source #2 */ 12539 if (paTests[iTest].iRegSrc2 == UINT8_MAX) 12540 { 12541 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12542 BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX); 12543 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc2, cbMemOp); 12544 uMemOpExpect = paValues[iVal].uSrc2; 12545 } 12546 else if (fMmxInstr) 12547 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc2, paValues[iVal].uSrc2.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12548 else if (fSseInstr) 12549 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2.DQWords.dqw0); 12550 else 12551 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc2, &paValues[iVal].uSrc2, 32); 12552 12553 /* source #3 */ 12554 if (paTests[iTest].iRegSrc3 == UINT8_MAX) 12555 { 12556 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 12557 BS3_ASSERT(paTests[iTest].iRegDst != UINT8_MAX && paTests[iTest].iRegSrc1 != UINT8_MAX); 12558 Bs3MemCpy(puMemOp, &paValues[iVal].uSrc3, cbMemOp); 12559 uMemOpExpect = paValues[iVal].uSrc3; 12560 } 12561 else if (fMmxInstr) 12562 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegSrc3, paValues[iVal].uSrc3.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 12563 else if (fSseInstr) 12564 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegSrc3, &paValues[iVal].uSrc3.DQWords.dqw0); 12565 else 12566 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegSrc3, &paValues[iVal].uSrc3, 32); 12567 12568 /* Memory pointer. */ 12569 if (paTests[iTest].enmRm >= RM_MEM) 12570 { 12571 BS3_ASSERT( paTests[iTest].iRegDst == UINT8_MAX 12572 || paTests[iTest].iRegSrc1 == UINT8_MAX 12573 || paTests[iTest].iRegSrc2 == UINT8_MAX 12574 || paTests[iTest].iRegSrc3 == UINT8_MAX); 12575 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 12576 } 12577 12578 /* 12579 * Execute. 12580 */ 12581 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 12582 12583 /* 12584 * Check the result: 12585 */ 12586 cErrors = Bs3TestSubErrorCount(); 12587 12588 if (fMmxInstr && bXcptExpect == X86_XCPT_DB) 12589 { 12590 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 12591 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); /* Observed on 10980xe after pxor mm1, mm2. */ 12592 } 12593 if (bXcptExpect == X86_XCPT_DB && paTests[iTest].iRegDst != UINT8_MAX) 12594 { 12595 if (fMmxInstr) 12596 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iRegDst, paValues[iVal].uDstOut.QWords.qw0, BS3EXTCTXTOPMM_SET); 12597 else if (fSseInstr) 12598 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut.DQWords.dqw0); 12599 else 12600 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iRegDst, &paValues[iVal].uDstOut, cbOperand); 12601 } 12602 #if defined(DEBUG_aeichner) /** @todo Necessary kludge on a i7-1068NG7. */ 12603 if ( pExtCtx->enmMethod == BS3EXTCTXMETHOD_XSAVE 12604 && pExtCtx->Ctx.x.Hdr.bmXState == 0x7 12605 && pExtCtxOut->Ctx.x.Hdr.bmXState == 0x3) 12606 pExtCtxOut->Ctx.x.Hdr.bmXState = 0x7; 12607 #endif 12608 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 12609 12610 if (TrapFrame.bXcpt != bXcptExpect) 12611 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 12612 12613 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 12614 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 12615 { 12616 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 12617 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 12618 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 12619 } 12620 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 12621 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 12622 pszMode, idTestStep); 12623 12624 if ( paTests[iTest].enmRm >= RM_MEM 12625 && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0) 12626 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp); 12627 12628 if (cErrors != Bs3TestSubErrorCount()) 12629 { 12630 if (paConfigs[iCfg].fAligned) 12631 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 12632 bRing, iCfg, iTest, iVal, bXcptExpect); 12633 else 12634 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 12635 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 12636 Bs3TestPrintf("\n"); 12637 } 12638 12639 if (uSavedFtw != 0xff) 12640 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 12641 } 12718 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 12642 12719 } 12643 12644 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 12645 } 12720 } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode)); 12646 12721 12647 12722 /* … … 13008 13083 for (;;) 13009 13084 { 13010 unsigned iCfg;13011 for (iCfg = 0; iCfg < cConfigs; iCfg++)13085 unsigned fPf = 0; 13086 do 13012 13087 { 13013 unsigned iTest; 13014 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 13015 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 13016 continue; /* unsupported config */ 13017 13018 /* 13019 * Iterate the tests. 13020 */ 13021 for (iTest = 0; iTest < cTests; iTest++) 13088 unsigned iCfg; 13089 for (iCfg = 0; iCfg < cConfigs; iCfg++) 13022 13090 { 13023 BS3CPUINSTR3_TEST6_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 13024 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 13025 unsigned const cValues = paTests[iTest].cValues; 13026 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 13027 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 13028 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 13029 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 13030 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 13031 uint8_t const cbMemOp = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm); 13032 uint8_t const cbAlign = RT_MIN(cbOperand, 16); 13033 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg]); 13034 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 13035 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 13036 : fSseInstr ? paConfigs[iCfg].bXcptSse 13037 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 13038 uint64_t const fGprValMask = paTests[iTest].cBitsGprValMask == 64 ? UINT64_MAX 13039 : RT_BIT_64(paTests[iTest].cBitsGprValMask) - 1; 13040 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 13041 unsigned cRecompRuns = 0; 13042 unsigned iVal; 13043 13044 /* If testing unaligned memory accesses, skip register-only tests. This allows 13045 setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 13046 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck)) 13047 continue; 13048 13049 /* #AC is only raised in ring-3.: */ 13050 if (bXcptExpect == X86_XCPT_AC) 13091 unsigned iTest; 13092 BS3CPUINSTR3_CONFIG_SAVED_T SavedCfg; 13093 if (!bs3CpuInstr3ConfigReconfigure(&SavedCfg, &Ctx, pExtCtx, &paConfigs[iCfg], bMode)) 13094 continue; /* unsupported config */ 13095 13096 /* 13097 * Iterate the tests. 13098 */ 13099 for (iTest = 0; iTest < cTests; iTest++) 13051 13100 { 13052 if (bRing != 3) 13053 bXcptExpect = X86_XCPT_DB; 13054 else if (fAvxInstr) 13055 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 13101 BS3CPUINSTR3_TEST6_VALUES_T const BS3_FAR *paValues = paTests[iTest].paValues; 13102 uint8_t const cbInstr = ((uint8_t const BS3_FAR *)(uintptr_t)paTests[iTest].pfnWorker)[-1]; 13103 unsigned const cValues = paTests[iTest].cValues; 13104 bool const fMmxInstr = paTests[iTest].enmType < T_SSE; 13105 bool const fSseInstr = paTests[iTest].enmType >= T_SSE && paTests[iTest].enmType < T_AVX_128; 13106 bool const fAvxInstr = paTests[iTest].enmType >= T_AVX_128; 13107 uint8_t const cbOperand = paTests[iTest].enmType < T_128BITS ? 64/8 13108 : paTests[iTest].enmType < T_256BITS ? 128/8 : 256/8; 13109 uint8_t const cbMemOp = bs3CpuInstr3MemOpSize(cbOperand, paTests[iTest].enmRm); 13110 uint8_t const cbAlign = RT_MIN(cbOperand, 16); 13111 PRTUINT256U puMemOp = bs3CpuInstr3BufForOperand(pbBuf, cbBuf, cbMemOp, cbAlign, &paConfigs[iCfg], fPf); 13112 PRTUINT256U puMemOpAlias = (PRTUINT256U)&g_pbBufAlias[(uintptr_t)puMemOp - (uintptr_t)pbBuf]; 13113 uint8_t bXcptExpect = !g_afTypeSupports[paTests[iTest].enmType] ? X86_XCPT_UD 13114 : fMmxInstr ? paConfigs[iCfg].bXcptMmx 13115 : fSseInstr ? paConfigs[iCfg].bXcptSse 13116 : BS3_MODE_IS_RM_OR_V86(bMode) ? X86_XCPT_UD : paConfigs[iCfg].bXcptAvx; 13117 uint64_t const fGprValMask = paTests[iTest].cBitsGprValMask == 64 ? UINT64_MAX 13118 : RT_BIT_64(paTests[iTest].cBitsGprValMask) - 1; 13119 uint16_t idTestStep = bRing * 10000 + iCfg * 100 + iTest * 10; 13120 unsigned cRecompRuns = 0; 13121 unsigned iVal; 13122 13123 /* If testing unaligned memory accesses, skip register-only tests. This allows 13124 setting bXcptMmx, bXcptSse and bXcptAvx to reflect the misaligned exceptions. */ 13125 if (paTests[iTest].enmRm == RM_REG && (!paConfigs[iCfg].fAligned || paConfigs[iCfg].fAlignCheck || fPf)) 13126 continue; 13127 13128 /* #AC is only raised in ring-3.: */ 13129 if (bXcptExpect == X86_XCPT_AC) 13130 { 13131 if (bRing != 3) 13132 bXcptExpect = X86_XCPT_DB; 13133 else if (fAvxInstr) 13134 bXcptExpect = paTests[iTest].bAvxMisalignXcpt; /* they generally don't raise #AC */ 13135 } 13136 13137 if (fPf && bXcptExpect == X86_XCPT_DB) 13138 bXcptExpect = X86_XCPT_PF; 13139 13140 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 13141 13142 /* 13143 * Iterate the test values and do the actual testing. 13144 */ 13145 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 13146 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 13147 { 13148 uint16_t cErrors; 13149 uint16_t uSavedFtw = 0xff; 13150 RTUINT256U uMemOpExpect; 13151 13152 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 13153 13154 /* 13155 * Set up the context and some expectations. 13156 */ 13157 /* source - media */ 13158 BS3_ASSERT(paTests[iTest].iMediaRegSrc != UINT8_MAX); 13159 if (fMmxInstr) 13160 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaRegSrc, paValues[iVal].uMediaSrc.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 13161 else if (fSseInstr) 13162 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaRegSrc, &paValues[iVal].uMediaSrc.DQWords.dqw0); 13163 else 13164 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaRegSrc, &paValues[iVal].uMediaSrc, 32); 13165 13166 /* source - gpr/mem */ 13167 if (paTests[iTest].iGprReg == UINT8_MAX) 13168 { 13169 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 13170 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 13171 if (bXcptExpect == X86_XCPT_DB) 13172 switch (paTests[iTest].cbGpr) 13173 { 13174 case 1: uMemOpExpect.au8[0] = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break; 13175 case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break; 13176 case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break; 13177 case 8: uMemOpExpect.au64[0] = (paValues[iVal].uGpr & fGprValMask); break; 13178 default: BS3_ASSERT(0); 13179 } 13180 Bs3MemCpy(puMemOpAlias, &uMemOpExpect, cbMemOp); 13181 } 13182 else 13183 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, paTests[iTest].cbGpr); 13184 13185 /* Memory pointer. */ 13186 if (paTests[iTest].enmRm >= RM_MEM) 13187 { 13188 BS3_ASSERT(paTests[iTest].iGprReg == UINT8_MAX || paTests[iTest].iMediaRegSrc == UINT8_MAX); 13189 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 13190 } 13191 13192 /* 13193 * Execute. 13194 */ 13195 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 13196 13197 /* 13198 * Check the result: 13199 */ 13200 cErrors = Bs3TestSubErrorCount(); 13201 13202 if (fMmxInstr && bXcptExpect == X86_XCPT_DB) 13203 { 13204 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 13205 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); 13206 } 13207 13208 if (bXcptExpect == X86_XCPT_DB) 13209 { 13210 if (fMmxInstr) 13211 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaRegDst, paValues[iVal].uMediaDst.QWords.qw0, BS3EXTCTXTOPMM_SET); 13212 else if (fSseInstr) 13213 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaRegDst, &paValues[iVal].uMediaDst.DQWords.dqw0); 13214 else 13215 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaRegDst, &paValues[iVal].uMediaDst, 32); 13216 } 13217 13218 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 13219 13220 if (TrapFrame.bXcpt != bXcptExpect) 13221 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 13222 13223 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 13224 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 13225 { 13226 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 13227 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 13228 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 13229 } 13230 if (bXcptExpect == X86_XCPT_PF) 13231 Ctx.cr2.u = (uintptr_t)puMemOp; 13232 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 13233 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 13234 pszMode, idTestStep); 13235 Ctx.cr2.u = 0; 13236 13237 if ( paTests[iTest].enmRm >= RM_MEM 13238 && Bs3MemCmp(puMemOpAlias, &uMemOpExpect, cbMemOp) != 0) 13239 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOpAlias); 13240 13241 if (cErrors != Bs3TestSubErrorCount()) 13242 { 13243 if (paConfigs[iCfg].fAligned) 13244 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 13245 bRing, iCfg, iTest, iVal, bXcptExpect); 13246 else 13247 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 13248 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 13249 Bs3TestPrintf("\n"); 13250 } 13251 13252 if (uSavedFtw != 0xff) 13253 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 13254 } 13056 13255 } 13057 13256 13058 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, paTests[iTest].pfnWorker); 13059 13060 /* 13061 * Iterate the test values and do the actual testing. 13062 */ 13063 while (cRecompRuns < BS3_THRESHOLD_NATIVE_RECOMPILER + cValues) 13064 for (iVal = 0; iVal < cValues; iVal++, idTestStep++, cRecompRuns++) 13065 { 13066 uint16_t cErrors; 13067 uint16_t uSavedFtw = 0xff; 13068 RTUINT256U uMemOpExpect; 13069 13070 if (BS3_SKIPIT(bRing, iCfg, iTest, iVal, 0)) continue; 13071 13072 /* 13073 * Set up the context and some expectations. 13074 */ 13075 /* source - media */ 13076 BS3_ASSERT(paTests[iTest].iMediaRegSrc != UINT8_MAX); 13077 if (fMmxInstr) 13078 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaRegSrc, paValues[iVal].uMediaSrc.QWords.qw0, BS3EXTCTXTOPMM_ZERO); 13079 else if (fSseInstr) 13080 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaRegSrc, &paValues[iVal].uMediaSrc.DQWords.dqw0); 13081 else 13082 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaRegSrc, &paValues[iVal].uMediaSrc, 32); 13083 13084 /* source - gpr/mem */ 13085 if (paTests[iTest].iGprReg == UINT8_MAX) 13086 { 13087 BS3_ASSERT(paTests[iTest].enmRm >= RM_MEM); 13088 Bs3MemSet(&uMemOpExpect, 0xcc, sizeof(uMemOpExpect)); 13089 if (bXcptExpect == X86_XCPT_DB) 13090 switch (paTests[iTest].cbGpr) 13091 { 13092 case 1: uMemOpExpect.au8[0] = (uint8_t) (paValues[iVal].uGpr & fGprValMask); break; 13093 case 2: uMemOpExpect.au16[0] = (uint16_t)(paValues[iVal].uGpr & fGprValMask); break; 13094 case 4: uMemOpExpect.au32[0] = (uint32_t)(paValues[iVal].uGpr & fGprValMask); break; 13095 case 8: uMemOpExpect.au64[0] = (paValues[iVal].uGpr & fGprValMask); break; 13096 default: BS3_ASSERT(0); 13097 } 13098 Bs3MemCpy(puMemOp, &uMemOpExpect, cbMemOp); 13099 } 13100 else 13101 Bs3RegCtxSetGpr(&Ctx, paTests[iTest].iGprReg, paValues[iVal].uGpr & fGprValMask, paTests[iTest].cbGpr); 13102 13103 /* Memory pointer. */ 13104 if (paTests[iTest].enmRm >= RM_MEM) 13105 { 13106 BS3_ASSERT(paTests[iTest].iGprReg == UINT8_MAX || paTests[iTest].iMediaRegSrc == UINT8_MAX); 13107 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, &Ctx.fs, puMemOp); 13108 } 13109 13110 /* 13111 * Execute. 13112 */ 13113 Bs3TrapSetJmpAndRestoreWithExtCtxAndRm(&Ctx, pExtCtx, &TrapFrame, pExtCtxOut); 13114 13115 /* 13116 * Check the result: 13117 */ 13118 cErrors = Bs3TestSubErrorCount(); 13119 13120 if (fMmxInstr && bXcptExpect == X86_XCPT_DB) 13121 { 13122 uSavedFtw = Bs3ExtCtxGetAbridgedFtw(pExtCtx); 13123 Bs3ExtCtxSetAbridgedFtw(pExtCtx, 0xff); 13124 } 13125 13126 if (bXcptExpect == X86_XCPT_DB) 13127 { 13128 if (fMmxInstr) 13129 Bs3ExtCtxSetMm(pExtCtx, paTests[iTest].iMediaRegDst, paValues[iVal].uMediaDst.QWords.qw0, BS3EXTCTXTOPMM_SET); 13130 else if (fSseInstr) 13131 Bs3ExtCtxSetXmm(pExtCtx, paTests[iTest].iMediaRegDst, &paValues[iVal].uMediaDst.DQWords.dqw0); 13132 else 13133 Bs3ExtCtxSetYmm(pExtCtx, paTests[iTest].iMediaRegDst, &paValues[iVal].uMediaDst, 32); 13134 } 13135 13136 Bs3TestCheckExtCtx(pExtCtxOut, pExtCtx, 0 /*fFlags*/, pszMode, idTestStep); 13137 13138 if (TrapFrame.bXcpt != bXcptExpect) 13139 Bs3TestFailedF("Expected bXcpt = %#x, got %#x", bXcptExpect, TrapFrame.bXcpt); 13140 13141 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on the 10980XE. WEIRD! */ 13142 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 13143 { 13144 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 13145 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 13146 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 13147 } 13148 Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &Ctx, bXcptExpect == X86_XCPT_DB ? cbInstr + 1 : 0, 0, 13149 bXcptExpect == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, 13150 pszMode, idTestStep); 13151 13152 if ( paTests[iTest].enmRm >= RM_MEM 13153 && Bs3MemCmp(puMemOp, &uMemOpExpect, cbMemOp) != 0) 13154 Bs3TestFailedF("Expected uMemOp %.*Rhxs, got %.*Rhxs", cbMemOp, &uMemOpExpect, cbMemOp, puMemOp); 13155 13156 if (cErrors != Bs3TestSubErrorCount()) 13157 { 13158 if (paConfigs[iCfg].fAligned) 13159 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x)", 13160 bRing, iCfg, iTest, iVal, bXcptExpect); 13161 else 13162 Bs3TestFailedF("ring-%d/cfg#%u/test#%u/value#%u failed (bXcptExpect=%#x, puMemOp=%p, EFLAGS=%#RX32, CR0=%#RX32)", 13163 bRing, iCfg, iTest, iVal, bXcptExpect, puMemOp, TrapFrame.Ctx.rflags.u32, TrapFrame.Ctx.cr0); 13164 Bs3TestPrintf("\n"); 13165 } 13166 13167 if (uSavedFtw != 0xff) 13168 Bs3ExtCtxSetAbridgedFtw(pExtCtx, uSavedFtw); 13169 } 13257 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 13170 13258 } 13171 13172 bs3CpuInstr3ConfigRestore(&SavedCfg, &Ctx, pExtCtx); 13173 } 13259 } while (fPf++ == 0 && BS3_MODE_IS_PAGED(bMode)); 13174 13260 13175 13261 /* … … 13532 13618 bs3CpuInstr3_vpbroadcastb_vpbroadcastw_vpbroadcastd_vpbroadcastq_vbroadcasti128, 0 }, 13533 13619 #endif 13534 #if defined 13620 #if defined(ALL_TESTS) 13535 13621 { "vinserti128/vinsertf128", bs3CpuInstr3_vinserti128_vinsertf128, 0 }, 13536 13622 #endif 13537 #if defined 13623 #if defined(ALL_TESTS) 13538 13624 { "[v]psubsb/[v]psubsw", bs3CpuInstr3_v_psubsb_psubsw, 0 }, 13539 13625 { "[v]psubusb/[v]psubusw", bs3CpuInstr3_v_psubusb_psubusw, 0 }, … … 13541 13627 { "[v]paddsb/[v]paddsw", bs3CpuInstr3_v_paddsb_paddsw, 0 }, 13542 13628 #endif 13543 #if defined 13629 #if defined(ALL_TESTS) 13544 13630 { "[v]psllw/[v]pslld/[v]psllq", bs3CpuInstr3_v_psllw_pslld_psllq, 0 }, 13545 13631 { "[v]psraw/[v]psrad", bs3CpuInstr3_v_psraw_psrad, 0 }, 13546 13632 { "[v]psrlw/[v]psrld/[v]psrlq", bs3CpuInstr3_v_psrlw_psrld_psrlq, 0 }, 13547 13633 #endif 13548 #if defined 13634 #if defined(ALL_TESTS) 13549 13635 { "vpsllvd/vpsllvq", bs3CpuInstr3_vpsllvd_vpsllvq, 0 }, 13550 13636 { "vpsravd", bs3CpuInstr3_vpsravd, 0 }, 13551 13637 { "vpsrlvd/vpsrlvq", bs3CpuInstr3_vpsrlvd_vpsrlvq, 0 }, 13552 13638 #endif 13553 #if defined 13639 #if defined(ALL_TESTS) 13554 13640 { "vperm2i128/vperm2f128", bs3CpuInstr3_vperm2i128_vperm2f128, 0 }, 13555 13641 #endif 13556 #if defined 13642 #if defined(ALL_TESTS) 13557 13643 { "vpermilps", bs3CpuInstr3_vpermilps, 0 }, 13558 13644 { "vpermilpd", bs3CpuInstr3_vpermilpd, 0 }, 13559 13645 #endif 13560 #if defined 13646 #if defined(ALL_TESTS) 13561 13647 { "[v]pmaddwd", bs3CpuInstr3_v_pmaddwd, 0 }, 13562 13648 #endif … … 13612 13698 if (g_pbBuf) 13613 13699 { 13614 /* 13615 * Do the tests. 13616 */ 13617 Bs3TestDoModesByOne_pe32(g_aTests, RT_ELEMENTS(g_aTests), BS3TESTMODEBYONEENTRY_F_REAL_MODE_READY); 13700 g_pbBufAliasAlloc = (uint8_t BS3_FAR *)Bs3MemAlloc(BS3MEMKIND_TILED, g_cbBuf); 13701 if (g_pbBufAliasAlloc) 13702 { 13703 /* 13704 * Do the tests. 13705 */ 13706 Bs3TestDoModesByOne_pe32(g_aTests, RT_ELEMENTS(g_aTests), BS3TESTMODEBYONEENTRY_F_REAL_MODE_READY); 13618 13707 #ifdef BS3_SKIPIT_DO_SKIP 13619 bs3CpuInstr3_ShowTallies();13708 bs3CpuInstr3_ShowTallies(); 13620 13709 #endif 13710 } 13711 else 13712 Bs3TestFailed("Failed to allocate 16K alias buffer (tiled addressable)"); 13621 13713 } 13622 13714 else 13623 Bs3TestFailed("Failed to allocate 16K buffer ");13715 Bs3TestFailed("Failed to allocate 16K buffer (real mode addressable)"); 13624 13716 13625 13717 Bs3TestTerm();
Note:
See TracChangeset
for help on using the changeset viewer.