- Timestamp:
- Feb 22, 2022 9:09:02 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp
r93879 r93880 140 140 * Internal Functions * 141 141 *********************************************************************************************************************************/ 142 static uint32_t RandEFlags(void); 143 static uint8_t RandU8(void); 144 static uint16_t RandU16(void); 145 static uint32_t RandU32(void); 146 static uint64_t RandU64(void); 142 static uint32_t RandEFlags(void); 143 static uint8_t RandU8(void); 144 static uint16_t RandU16(void); 145 static uint32_t RandU32(void); 146 static uint64_t RandU64(void); 147 static RTUINT128U RandU128(void); 147 148 148 149 … … 745 746 static void XaddTest(void) 746 747 { 747 RTTestSub(g_hTest, "xadd");748 748 #define TEST_XADD(a_cBits, a_Type, a_Fmt) do { \ 749 749 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLXADDU ## a_cBits, (a_Type *, a_Type *, uint32_t *)); \ … … 763 763 for (size_t iFn = 0; iFn < RT_ELEMENTS(s_aFuncs); iFn++) \ 764 764 { \ 765 RTTestSub(g_hTest, s_aFuncs[iFn].pszName); \ 765 766 BINU ## a_cBits ## _TEST_T const * const paTests = s_aFuncs[iFn].paTests; \ 766 767 uint32_t const cTests = s_aFuncs[iFn].cTests; \ … … 794 795 static void CmpXchgTest(void) 795 796 { 796 RTTestSub(g_hTest, "cmpxchg");797 797 #define TEST_CMPXCHG(a_cBits, a_Type, a_Fmt) do {\ 798 798 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLCMPXCHGU ## a_cBits, (a_Type *, a_Type *, a_Type, uint32_t *)); \ … … 813 813 for (size_t iFn = 0; iFn < RT_ELEMENTS(s_aFuncs); iFn++) \ 814 814 { \ 815 RTTestSub(g_hTest, s_aFuncs[iFn].pszName); \ 815 816 BINU ## a_cBits ## _TEST_T const * const paTests = s_aFuncs[iFn].paTests; \ 816 817 uint32_t const cTests = s_aFuncs[iFn].cTests; \ … … 857 858 } 858 859 859 #if 0 860 static void CmpXchgTest(void) 861 { 862 RTTestSub(g_hTest, "cmpxchg"); 863 #define TEST_CMPXCHG(a_cBits, a_Type, a_Fmt) do {\ 864 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLCMPXCHGU ## a_cBits, (a_Type *, a_Type *, a_Type, uint32_t *)); \ 865 static struct \ 866 { \ 867 const char *pszName; \ 868 FNIEMAIMPLCMPXCHGU ## a_cBits *pfn; \ 869 } const s_aFuncs[] = \ 870 { \ 871 { "cmpxchg_u" # a_cBits, iemAImpl_cmpxchg_u ## a_cBits }, \ 872 { "cmpxchg_u" # a_cBits "_locked", iemAImpl_cmpxchg_u ## a_cBits ## _locked }, \ 873 }; \ 874 for (size_t iFn = 0; iFn < RT_ELEMENTS(s_aFuncs); iFn++) \ 875 { \ 876 for (uint32_t iTest = 0; iTest < 4; iTest += 2) \ 877 { \ 878 a_Type const uOldValue = RandU ## a_cBits(); \ 879 a_Type const uNewValue = RandU ## a_cBits(); \ 880 /* positive test. */ \ 881 *g_pu ## a_cBits = uOldValue; \ 882 a_Type uA = uOldValue; \ 883 uint32_t fEflIn = RandEFlags(); \ 884 uint32_t fEfl = fEflIn; \ 885 s_aFuncs[iFn].pfn(g_pu ## a_cBits, &uA, uNewValue, &fEfl); \ 886 if ( fEfl != (fEflIn | X86_EFL_ZF) \ 887 || *g_pu ## a_cBits != uNewValue \ 888 || uA != uOldValue) \ 889 RTTestFailed(g_hTest, "%s/#%u: efl=%#08x dst=" a_Fmt " cmp=" a_Fmt " new=" a_Fmt " -> efl=%#08x dst=" a_Fmt " old=" a_Fmt ", expected %#08x, " a_Fmt ", " a_Fmt "%s\n", \ 890 s_aFuncs[iFn].pszName, iTest, fEflIn, uOldValue, uOldValue, uNewValue, \ 891 fEfl, *g_pu ## a_cBits, uA, \ 892 (fEflIn | X86_EFL_ZF), uNewValue, uOldValue, EFlagsDiff(fEfl, fEflIn | X86_EFL_ZF)); \ 893 /* negative */ \ 894 a_Type const uExpect = ~uOldValue; \ 895 *g_pu ## a_cBits = uExpect; \ 896 uA = uOldValue; \ 897 fEfl = fEflIn = RandEFlags(); \ 898 s_aFuncs[iFn].pfn(g_pu ## a_cBits, &uA, uNewValue, &fEfl); \ 899 if ( fEfl != (fEflIn & ~X86_EFL_ZF) \ 900 || *g_pu ## a_cBits != uExpect \ 901 || uA != uExpect) \ 902 RTTestFailed(g_hTest, "%s/#%u: efl=%#08x dst=" a_Fmt " cmp=" a_Fmt " new=" a_Fmt " -> efl=%#08x dst=" a_Fmt " old=" a_Fmt ", expected %#08x, " a_Fmt ", " a_Fmt "%s\n", \ 903 s_aFuncs[iFn].pszName, iTest + 1, fEflIn, uExpect, uOldValue, uNewValue, \ 904 fEfl, *g_pu ## a_cBits, uA, \ 905 (fEflIn & ~X86_EFL_ZF), uExpect, uExpect, EFlagsDiff(fEfl, fEflIn & ~X86_EFL_ZF)); \ 906 } \ 907 } \ 908 } while(0) 909 TEST_CMPXCHG(8, uint8_t, "%#04RX8"); 910 #if 0 911 TEST_CMPXCHG(16, uint16_t, "%#06x"); 912 TEST_CMPXCHG(32, uint32_t, "%#010RX32"); 913 #if ARCH_BITS != 32 /* calling convension issue, skipping as it's an unsupported host */ 914 TEST_CMPXCHG(64, uint64_t, "%#010RX64"); 860 static void CmpXchg8bTest(void) 861 { 862 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLCMPXCHG8B,(uint64_t *, PRTUINT64U, PRTUINT64U, uint32_t *)); 863 static struct 864 { 865 const char *pszName; 866 FNIEMAIMPLCMPXCHG8B *pfn; 867 } const s_aFuncs[] = 868 { 869 { "cmpxchg8b", iemAImpl_cmpxchg8b }, 870 { "cmpxchg8b_locked", iemAImpl_cmpxchg8b_locked }, 871 }; 872 for (size_t iFn = 0; iFn < RT_ELEMENTS(s_aFuncs); iFn++) 873 { 874 RTTestSub(g_hTest, s_aFuncs[iFn].pszName); 875 for (uint32_t iTest = 0; iTest < 4; iTest += 2) 876 { 877 uint64_t const uOldValue = RandU64(); 878 uint64_t const uNewValue = RandU64(); 879 880 /* positive test. */ 881 RTUINT64U uA, uB; 882 uB.u = uNewValue; 883 uA.u = uOldValue; 884 *g_pu64 = uOldValue; 885 uint32_t fEflIn = RandEFlags(); 886 uint32_t fEfl = fEflIn; 887 s_aFuncs[iFn].pfn(g_pu64, &uA, &uB, &fEfl); 888 if ( fEfl != (fEflIn | X86_EFL_ZF) 889 || *g_pu64 != uNewValue 890 || uA.u != uOldValue) 891 RTTestFailed(g_hTest, "#%u: efl=%#08x dst=%#018RX64 cmp=%#018RX64 new=%#018RX64\n -> efl=%#08x dst=%#018RX64 old=%#018RX64,\n wanted %#08x, %#018RX64, %#018RX64%s\n", 892 iTest, fEflIn, uOldValue, uOldValue, uNewValue, 893 fEfl, *g_pu64, uA.u, 894 (fEflIn | X86_EFL_ZF), uNewValue, uOldValue, EFlagsDiff(fEfl, fEflIn | X86_EFL_ZF)); 895 RTTEST_CHECK(g_hTest, uB.u == uNewValue); 896 897 /* negative */ 898 uint64_t const uExpect = ~uOldValue; 899 *g_pu64 = uExpect; 900 uA.u = uOldValue; 901 uB.u = uNewValue; 902 fEfl = fEflIn = RandEFlags(); 903 s_aFuncs[iFn].pfn(g_pu64, &uA, &uB, &fEfl); 904 if ( fEfl != (fEflIn & ~X86_EFL_ZF) 905 || *g_pu64 != uExpect 906 || uA.u != uExpect) 907 RTTestFailed(g_hTest, "#%u: efl=%#08x dst=%#018RX64 cmp=%#018RX64 new=%#018RX64\n -> efl=%#08x dst=%#018RX64 old=%#018RX64,\n wanted %#08x, %#018RX64, %#018RX64%s\n", 908 iTest + 1, fEflIn, uExpect, uOldValue, uNewValue, 909 fEfl, *g_pu64, uA.u, 910 (fEflIn & ~X86_EFL_ZF), uExpect, uExpect, EFlagsDiff(fEfl, fEflIn & ~X86_EFL_ZF)); 911 RTTEST_CHECK(g_hTest, uB.u == uNewValue); 912 } 913 } 914 } 915 916 static void CmpXchg16bTest(void) 917 { 918 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLCMPXCHG16B,(PRTUINT128U, PRTUINT128U, PRTUINT128U, uint32_t *)); 919 static struct 920 { 921 const char *pszName; 922 FNIEMAIMPLCMPXCHG16B *pfn; 923 } const s_aFuncs[] = 924 { 925 { "cmpxchg16b", iemAImpl_cmpxchg16b }, 926 { "cmpxchg16b_locked", iemAImpl_cmpxchg16b_locked }, 927 #if !defined(RT_ARCH_ARM64) 928 { "cmpxchg16b_fallback", iemAImpl_cmpxchg16b_fallback }, 915 929 #endif 930 }; 931 for (size_t iFn = 0; iFn < RT_ELEMENTS(s_aFuncs); iFn++) 932 { 933 #if !defined(IEM_WITHOUT_ASSEMBLY) && defined(RT_ARCH_AMD64) 934 if (!(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16)) 935 continue; 916 936 #endif 917 } 918 #endif 937 RTTestSub(g_hTest, s_aFuncs[iFn].pszName); 938 for (uint32_t iTest = 0; iTest < 4; iTest += 2) 939 { 940 RTUINT128U const uOldValue = RandU128(); 941 RTUINT128U const uNewValue = RandU128(); 942 943 /* positive test. */ 944 RTUINT128U uA, uB; 945 uB = uNewValue; 946 uA = uOldValue; 947 *g_pu128 = uOldValue; 948 uint32_t fEflIn = RandEFlags(); 949 uint32_t fEfl = fEflIn; 950 s_aFuncs[iFn].pfn(g_pu128, &uA, &uB, &fEfl); 951 if ( fEfl != (fEflIn | X86_EFL_ZF) 952 || g_pu128->s.Lo != uNewValue.s.Lo 953 || g_pu128->s.Hi != uNewValue.s.Hi 954 || uA.s.Lo != uOldValue.s.Lo 955 || uA.s.Hi != uOldValue.s.Hi) 956 RTTestFailed(g_hTest, "#%u: efl=%#08x dst=%#018RX64'%016RX64 cmp=%#018RX64'%016RX64 new=%#018RX64'%016RX64\n" 957 " -> efl=%#08x dst=%#018RX64'%016RX64 old=%#018RX64'%016RX64,\n" 958 " wanted %#08x, %#018RX64'%016RX64, %#018RX64'%016RX64%s\n", 959 iTest, fEflIn, uOldValue.s.Hi, uOldValue.s.Lo, uOldValue.s.Hi, uOldValue.s.Lo, uNewValue.s.Hi, uNewValue.s.Lo, 960 fEfl, g_pu128->s.Hi, g_pu128->s.Lo, uA.s.Hi, uA.s.Lo, 961 (fEflIn | X86_EFL_ZF), uNewValue.s.Hi, uNewValue.s.Lo, uOldValue.s.Hi, uOldValue.s.Lo, 962 EFlagsDiff(fEfl, fEflIn | X86_EFL_ZF)); 963 RTTEST_CHECK(g_hTest, uB.s.Lo == uNewValue.s.Lo && uB.s.Hi == uNewValue.s.Hi); 964 965 /* negative */ 966 RTUINT128U const uExpect = RTUINT128_INIT(~uOldValue.s.Hi, ~uOldValue.s.Lo); 967 *g_pu128 = uExpect; 968 uA = uOldValue; 969 uB = uNewValue; 970 fEfl = fEflIn = RandEFlags(); 971 s_aFuncs[iFn].pfn(g_pu128, &uA, &uB, &fEfl); 972 if ( fEfl != (fEflIn & ~X86_EFL_ZF) 973 || g_pu128->s.Lo != uExpect.s.Lo 974 || g_pu128->s.Hi != uExpect.s.Hi 975 || uA.s.Lo != uExpect.s.Lo 976 || uA.s.Hi != uExpect.s.Hi) 977 RTTestFailed(g_hTest, "#%u: efl=%#08x dst=%#018RX64'%016RX64 cmp=%#018RX64'%016RX64 new=%#018RX64'%016RX64\n" 978 " -> efl=%#08x dst=%#018RX64'%016RX64 old=%#018RX64'%016RX64,\n" 979 " wanted %#08x, %#018RX64'%016RX64, %#018RX64'%016RX64%s\n", 980 iTest + 1, fEflIn, uExpect.s.Hi, uExpect.s.Lo, uOldValue.s.Hi, uOldValue.s.Lo, uNewValue.s.Hi, uNewValue.s.Lo, 981 fEfl, g_pu128->s.Hi, g_pu128->s.Lo, uA.s.Hi, uA.s.Lo, 982 (fEflIn & ~X86_EFL_ZF), uExpect.s.Hi, uExpect.s.Lo, uExpect.s.Hi, uExpect.s.Lo, 983 EFlagsDiff(fEfl, fEflIn & ~X86_EFL_ZF)); 984 RTTEST_CHECK(g_hTest, uB.s.Lo == uNewValue.s.Lo && uB.s.Hi == uNewValue.s.Hi); 985 } 986 } 987 } 919 988 920 989 … … 950 1019 { 951 1020 return RTRandU64(); 1021 } 1022 1023 1024 static RTUINT128U RandU128(void) 1025 { 1026 RTUINT128U Ret; 1027 Ret.s.Hi = RTRandU64(); 1028 Ret.s.Lo = RTRandU64(); 1029 return Ret; 952 1030 } 953 1031 … … 1002 1080 { 1003 1081 /* Allocate guarded memory for use in the tests. */ 1004 #define ALLOC_GUARDED_VAR(a_ uVar) do { \1005 rc = RTTestGuardedAlloc(g_hTest, sizeof( a_uVar), sizeof(a_uVar), false /*fHead*/, (void **)&a_uVar); \1006 if (RT_FAILURE(rc)) RTTestFailed(g_hTest, "Failed to allocate guarded mem: " #a_ uVar); \1082 #define ALLOC_GUARDED_VAR(a_puVar) do { \ 1083 rc = RTTestGuardedAlloc(g_hTest, sizeof(*a_puVar), sizeof(*a_puVar), false /*fHead*/, (void **)&a_puVar); \ 1084 if (RT_FAILURE(rc)) RTTestFailed(g_hTest, "Failed to allocate guarded mem: " #a_puVar); \ 1007 1085 } while (0) 1008 1086 ALLOC_GUARDED_VAR(g_pu8); … … 1026 1104 XaddTest(); 1027 1105 CmpXchgTest(); 1106 CmpXchg8bTest(); 1107 CmpXchg16bTest(); 1028 1108 } 1029 1109 return RTTestSummaryAndDestroy(g_hTest);
Note:
See TracChangeset
for help on using the changeset viewer.