Changeset 96742 in vbox for trunk/src/VBox
- Timestamp:
- Sep 14, 2022 6:33:48 PM (2 years ago)
- Location:
- trunk/src/VBox/VMM/testcase
- Files:
-
- 4 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/testcase/Makefile.kmk
r96732 r96742 288 288 tstIEMAImplDataSseBinary-cvtss2si_i32_r32.bin \ 289 289 tstIEMAImplDataSseBinary-cvttss2si_i64_r32.bin \ 290 tstIEMAImplDataSseBinary-cvtss2si_i64_r32.bin 290 tstIEMAImplDataSseBinary-cvtss2si_i64_r32.bin \ 291 tstIEMAImplDataSseBinary-cvtsi2ss_r32_i32.bin \ 292 tstIEMAImplDataSseBinary-cvtsi2ss_r32_i64.bin \ 293 tstIEMAImplDataSseBinary-cvtsi2sd_r64_i32.bin \ 294 tstIEMAImplDataSseBinary-cvtsi2sd_r64_i64.bin 291 295 292 296 tstIEMAImpl_TEMPLATE = VBOXR3TSTEXE -
trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp
r96734 r96742 266 266 267 267 268 #if 0269 268 static int64_t RandI64Src(uint32_t iTest) 270 269 { … … 272 271 return (int64_t)RandU64(); 273 272 } 274 #endif275 273 276 274 … … 5919 5917 5920 5918 5919 /* 5920 * SSE operations converting single signed double-word integers to double-precision floating point values (probably only cvtsi2sd). 5921 */ 5922 TYPEDEF_SUBTEST_TYPE(SSE_BINARY_R64_I32_T, SSE_BINARY_R64_I32_TEST_T, PFNIEMAIMPLSSEF2R64I32); 5923 5924 static const SSE_BINARY_R64_I32_T g_aSseBinaryR64I32[] = 5925 { 5926 ENTRY_BIN(cvtsi2sd_r64_i32) 5927 }; 5928 5929 #ifdef TSTIEMAIMPL_WITH_GENERATOR 5930 static RTEXITCODE SseBinaryR64I32Generate(const char *pszDataFileFmt, uint32_t cTests) 5931 { 5932 cTests = RT_MAX(192, cTests); /* there are 144 standard input variations */ 5933 5934 static int32_t const s_aSpecials[] = 5935 { 5936 INT32_MIN, 5937 INT32_MAX, 5938 /** @todo More specials. */ 5939 }; 5940 5941 X86FXSTATE State; 5942 RT_ZERO(State); 5943 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aSseBinaryR64I32); iFn++) 5944 { 5945 PFNIEMAIMPLSSEF2R64I32 const pfn = g_aSseBinaryR64I32[iFn].pfnNative ? g_aSseBinaryR64I32[iFn].pfnNative : g_aSseBinaryR64I32[iFn].pfn; 5946 5947 PRTSTREAM pStrmOut = NULL; 5948 int rc = RTStrmOpenF("wb", &pStrmOut, pszDataFileFmt, g_aSseBinaryR64I32[iFn].pszName); 5949 if (RT_FAILURE(rc)) 5950 { 5951 RTMsgError("Failed to open data file for %s for writing: %Rrc", g_aSseBinaryR64I32[iFn].pszName, rc); 5952 return RTEXITCODE_FAILURE; 5953 } 5954 5955 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 5956 { 5957 SSE_BINARY_R64_I32_TEST_T TestData; RT_ZERO(TestData); 5958 5959 TestData.i32ValIn = iTest < cTests ? RandI32Src2(iTest) : s_aSpecials[iTest - cTests]; 5960 5961 uint32_t const fMxcsr = RandMxcsr() & X86_MXCSR_XCPT_FLAGS; 5962 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) 5963 for (uint8_t iDaz = 0; iDaz < 2; iDaz++) 5964 for (uint8_t iFz = 0; iFz < 2; iFz++) 5965 { 5966 State.MXCSR = (fMxcsr & ~X86_MXCSR_RC_MASK) 5967 | (iRounding << X86_MXCSR_RC_SHIFT) 5968 | (iDaz ? X86_MXCSR_DAZ : 0) 5969 | (iFz ? X86_MXCSR_FZ : 0) 5970 | X86_MXCSR_XCPT_MASK; 5971 uint32_t fMxcsrM; RTFLOAT64U r64OutM; 5972 pfn(&State, &fMxcsrM, &r64OutM, &TestData.i32ValIn); 5973 TestData.fMxcsrIn = State.MXCSR; 5974 TestData.fMxcsrOut = fMxcsrM; 5975 TestData.r64ValOut = r64OutM; 5976 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 5977 5978 State.MXCSR = State.MXCSR & ~X86_MXCSR_XCPT_MASK; 5979 uint32_t fMxcsrU; RTFLOAT64U r64OutU; 5980 pfn(&State, &fMxcsrU, &r64OutU, &TestData.i32ValIn); 5981 TestData.fMxcsrIn = State.MXCSR; 5982 TestData.fMxcsrOut = fMxcsrU; 5983 TestData.r64ValOut = r64OutU; 5984 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 5985 5986 uint16_t fXcpt = (fMxcsrM | fMxcsrU) & X86_MXCSR_XCPT_FLAGS; 5987 if (fXcpt) 5988 { 5989 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | fXcpt; 5990 uint32_t fMxcsr1; RTFLOAT64U r64Out1; 5991 pfn(&State, &fMxcsr1, &r64Out1, &TestData.i32ValIn); 5992 TestData.fMxcsrIn = State.MXCSR; 5993 TestData.fMxcsrOut = fMxcsr1; 5994 TestData.r64ValOut = r64Out1; 5995 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 5996 5997 if (((fMxcsr1 & X86_MXCSR_XCPT_FLAGS) & fXcpt) != (fMxcsr1 & X86_MXCSR_XCPT_FLAGS)) 5998 { 5999 fXcpt |= fMxcsr1 & X86_MXCSR_XCPT_FLAGS; 6000 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | (fXcpt << X86_MXCSR_XCPT_MASK_SHIFT); 6001 uint32_t fMxcsr2; RTFLOAT64U r64Out2; 6002 pfn(&State, &fMxcsr2, &r64Out2, &TestData.i32ValIn); 6003 TestData.fMxcsrIn = State.MXCSR; 6004 TestData.fMxcsrOut = fMxcsr2; 6005 TestData.r64ValOut = r64Out2; 6006 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6007 } 6008 if (!RT_IS_POWER_OF_TWO(fXcpt)) 6009 for (uint16_t fUnmasked = 1; fUnmasked <= X86_MXCSR_PE; fUnmasked <<= 1) 6010 if (fUnmasked & fXcpt) 6011 { 6012 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | ((fXcpt & ~fUnmasked) << X86_MXCSR_XCPT_MASK_SHIFT); 6013 uint32_t fMxcsr3; RTFLOAT64U r64Out3; 6014 pfn(&State, &fMxcsr3, &r64Out3, &TestData.i32ValIn); 6015 TestData.fMxcsrIn = State.MXCSR; 6016 TestData.fMxcsrOut = fMxcsr3; 6017 TestData.r64ValOut = r64Out3; 6018 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6019 } 6020 } 6021 } 6022 } 6023 rc = RTStrmClose(pStrmOut); 6024 if (RT_FAILURE(rc)) 6025 { 6026 RTMsgError("Failed to close data file for %s: %Rrc", g_aSseBinaryR64I32[iFn].pszName, rc); 6027 return RTEXITCODE_FAILURE; 6028 } 6029 } 6030 6031 return RTEXITCODE_SUCCESS; 6032 } 6033 #endif 6034 6035 6036 static void SseBinaryR64I32Test(void) 6037 { 6038 X86FXSTATE State; 6039 RT_ZERO(State); 6040 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aSseBinaryR64I32); iFn++) 6041 { 6042 if (!SubTestAndCheckIfEnabled(g_aSseBinaryR64I32[iFn].pszName)) 6043 continue; 6044 6045 uint32_t const cTests = *g_aSseBinaryR64I32[iFn].pcTests; 6046 SSE_BINARY_R64_I32_TEST_T const * const paTests = g_aSseBinaryR64I32[iFn].paTests; 6047 PFNIEMAIMPLSSEF2R64I32 pfn = g_aSseBinaryR64I32[iFn].pfn; 6048 uint32_t const cVars = COUNT_VARIATIONS(g_aSseBinaryR64I32[iFn]); 6049 if (!cTests) RTTestSkipped(g_hTest, "no tests"); 6050 for (uint32_t iVar = 0; iVar < cVars; iVar++) 6051 { 6052 for (uint32_t iTest = 0; iTest < cTests / sizeof(SSE_BINARY_R64_I32_TEST_T); iTest++) 6053 { 6054 uint32_t fMxcsr = 0; 6055 RTFLOAT64U r64Dst; RT_ZERO(r64Dst); 6056 6057 State.MXCSR = paTests[iTest].fMxcsrIn; 6058 pfn(&State, &fMxcsr, &r64Dst, &paTests[iTest].i32ValIn); 6059 if ( fMxcsr != paTests[iTest].fMxcsrOut 6060 || !RTFLOAT64U_ARE_IDENTICAL(&r64Dst, &paTests[iTest].r64ValOut)) 6061 RTTestFailed(g_hTest, "#%04u%s: mxcsr=%#08x in1=%RI32\n" 6062 "%s -> mxcsr=%#08x %s\n" 6063 "%s expected %#08x %s%s%s (%s)\n", 6064 iTest, iVar ? "/n" : "", paTests[iTest].fMxcsrIn, 6065 &paTests[iTest].i32ValIn, 6066 iVar ? " " : "", fMxcsr, FormatR64(&r64Dst), 6067 iVar ? " " : "", paTests[iTest].fMxcsrOut, FormatR64(&paTests[iTest].r64ValOut), 6068 MxcsrDiff(fMxcsr, paTests[iTest].fMxcsrOut), 6069 !RTFLOAT64U_ARE_IDENTICAL(&r64Dst, &paTests[iTest].r64ValOut) 6070 ? " - val" : "", 6071 FormatMxcsr(paTests[iTest].fMxcsrIn) ); 6072 } 6073 } 6074 } 6075 } 6076 6077 6078 /* 6079 * SSE operations converting single signed quad-word integers to double-precision floating point values (probably only cvtsi2sd). 6080 */ 6081 TYPEDEF_SUBTEST_TYPE(SSE_BINARY_R64_I64_T, SSE_BINARY_R64_I64_TEST_T, PFNIEMAIMPLSSEF2R64I64); 6082 6083 static const SSE_BINARY_R64_I64_T g_aSseBinaryR64I64[] = 6084 { 6085 ENTRY_BIN(cvtsi2sd_r64_i64), 6086 }; 6087 6088 #ifdef TSTIEMAIMPL_WITH_GENERATOR 6089 static RTEXITCODE SseBinaryR64I64Generate(const char *pszDataFileFmt, uint32_t cTests) 6090 { 6091 cTests = RT_MAX(192, cTests); /* there are 144 standard input variations */ 6092 6093 static int64_t const s_aSpecials[] = 6094 { 6095 INT64_MIN, 6096 INT64_MAX 6097 /** @todo More specials. */ 6098 }; 6099 6100 X86FXSTATE State; 6101 RT_ZERO(State); 6102 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aSseBinaryR64I64); iFn++) 6103 { 6104 PFNIEMAIMPLSSEF2R64I64 const pfn = g_aSseBinaryR64I64[iFn].pfnNative ? g_aSseBinaryR64I64[iFn].pfnNative : g_aSseBinaryR64I64[iFn].pfn; 6105 6106 PRTSTREAM pStrmOut = NULL; 6107 int rc = RTStrmOpenF("wb", &pStrmOut, pszDataFileFmt, g_aSseBinaryR64I64[iFn].pszName); 6108 if (RT_FAILURE(rc)) 6109 { 6110 RTMsgError("Failed to open data file for %s for writing: %Rrc", g_aSseBinaryR64I64[iFn].pszName, rc); 6111 return RTEXITCODE_FAILURE; 6112 } 6113 6114 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 6115 { 6116 SSE_BINARY_R64_I64_TEST_T TestData; RT_ZERO(TestData); 6117 6118 TestData.i64ValIn = iTest < cTests ? RandI64Src(iTest) : s_aSpecials[iTest - cTests]; 6119 6120 uint32_t const fMxcsr = RandMxcsr() & X86_MXCSR_XCPT_FLAGS; 6121 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) 6122 for (uint8_t iDaz = 0; iDaz < 2; iDaz++) 6123 for (uint8_t iFz = 0; iFz < 2; iFz++) 6124 { 6125 State.MXCSR = (fMxcsr & ~X86_MXCSR_RC_MASK) 6126 | (iRounding << X86_MXCSR_RC_SHIFT) 6127 | (iDaz ? X86_MXCSR_DAZ : 0) 6128 | (iFz ? X86_MXCSR_FZ : 0) 6129 | X86_MXCSR_XCPT_MASK; 6130 uint32_t fMxcsrM; RTFLOAT64U r64OutM; 6131 pfn(&State, &fMxcsrM, &r64OutM, &TestData.i64ValIn); 6132 TestData.fMxcsrIn = State.MXCSR; 6133 TestData.fMxcsrOut = fMxcsrM; 6134 TestData.r64ValOut = r64OutM; 6135 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6136 6137 State.MXCSR = State.MXCSR & ~X86_MXCSR_XCPT_MASK; 6138 uint32_t fMxcsrU; RTFLOAT64U r64OutU; 6139 pfn(&State, &fMxcsrU, &r64OutU, &TestData.i64ValIn); 6140 TestData.fMxcsrIn = State.MXCSR; 6141 TestData.fMxcsrOut = fMxcsrU; 6142 TestData.r64ValOut = r64OutU; 6143 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6144 6145 uint16_t fXcpt = (fMxcsrM | fMxcsrU) & X86_MXCSR_XCPT_FLAGS; 6146 if (fXcpt) 6147 { 6148 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | fXcpt; 6149 uint32_t fMxcsr1; RTFLOAT64U r64Out1; 6150 pfn(&State, &fMxcsr1, &r64Out1, &TestData.i64ValIn); 6151 TestData.fMxcsrIn = State.MXCSR; 6152 TestData.fMxcsrOut = fMxcsr1; 6153 TestData.r64ValOut = r64Out1; 6154 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6155 6156 if (((fMxcsr1 & X86_MXCSR_XCPT_FLAGS) & fXcpt) != (fMxcsr1 & X86_MXCSR_XCPT_FLAGS)) 6157 { 6158 fXcpt |= fMxcsr1 & X86_MXCSR_XCPT_FLAGS; 6159 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | (fXcpt << X86_MXCSR_XCPT_MASK_SHIFT); 6160 uint32_t fMxcsr2; RTFLOAT64U r64Out2; 6161 pfn(&State, &fMxcsr2, &r64Out2, &TestData.i64ValIn); 6162 TestData.fMxcsrIn = State.MXCSR; 6163 TestData.fMxcsrOut = fMxcsr2; 6164 TestData.r64ValOut = r64Out2; 6165 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6166 } 6167 if (!RT_IS_POWER_OF_TWO(fXcpt)) 6168 for (uint16_t fUnmasked = 1; fUnmasked <= X86_MXCSR_PE; fUnmasked <<= 1) 6169 if (fUnmasked & fXcpt) 6170 { 6171 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | ((fXcpt & ~fUnmasked) << X86_MXCSR_XCPT_MASK_SHIFT); 6172 uint32_t fMxcsr3; RTFLOAT64U r64Out3; 6173 pfn(&State, &fMxcsr3, &r64Out3, &TestData.i64ValIn); 6174 TestData.fMxcsrIn = State.MXCSR; 6175 TestData.fMxcsrOut = fMxcsr3; 6176 TestData.r64ValOut = r64Out3; 6177 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6178 } 6179 } 6180 } 6181 } 6182 rc = RTStrmClose(pStrmOut); 6183 if (RT_FAILURE(rc)) 6184 { 6185 RTMsgError("Failed to close data file for %s: %Rrc", g_aSseBinaryR64I64[iFn].pszName, rc); 6186 return RTEXITCODE_FAILURE; 6187 } 6188 } 6189 6190 return RTEXITCODE_SUCCESS; 6191 } 6192 #endif 6193 6194 6195 static void SseBinaryR64I64Test(void) 6196 { 6197 X86FXSTATE State; 6198 RT_ZERO(State); 6199 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aSseBinaryR64I64); iFn++) 6200 { 6201 if (!SubTestAndCheckIfEnabled(g_aSseBinaryR64I64[iFn].pszName)) 6202 continue; 6203 6204 uint32_t const cTests = *g_aSseBinaryR64I64[iFn].pcTests; 6205 SSE_BINARY_R64_I64_TEST_T const * const paTests = g_aSseBinaryR64I64[iFn].paTests; 6206 PFNIEMAIMPLSSEF2R64I64 pfn = g_aSseBinaryR64I64[iFn].pfn; 6207 uint32_t const cVars = COUNT_VARIATIONS(g_aSseBinaryR64I64[iFn]); 6208 if (!cTests) RTTestSkipped(g_hTest, "no tests"); 6209 for (uint32_t iVar = 0; iVar < cVars; iVar++) 6210 { 6211 for (uint32_t iTest = 0; iTest < cTests / sizeof(SSE_BINARY_R64_I64_TEST_T); iTest++) 6212 { 6213 uint32_t fMxcsr = 0; 6214 RTFLOAT64U r64Dst; RT_ZERO(r64Dst); 6215 6216 State.MXCSR = paTests[iTest].fMxcsrIn; 6217 pfn(&State, &fMxcsr, &r64Dst, &paTests[iTest].i64ValIn); 6218 if ( fMxcsr != paTests[iTest].fMxcsrOut 6219 || !RTFLOAT64U_ARE_IDENTICAL(&r64Dst, &paTests[iTest].r64ValOut)) 6220 RTTestFailed(g_hTest, "#%04u%s: mxcsr=%#08x in1=%RI64\n" 6221 "%s -> mxcsr=%#08x %s\n" 6222 "%s expected %#08x %s%s%s (%s)\n", 6223 iTest, iVar ? "/n" : "", paTests[iTest].fMxcsrIn, 6224 &paTests[iTest].i64ValIn, 6225 iVar ? " " : "", fMxcsr, FormatR64(&r64Dst), 6226 iVar ? " " : "", paTests[iTest].fMxcsrOut, FormatR64(&paTests[iTest].r64ValOut), 6227 MxcsrDiff(fMxcsr, paTests[iTest].fMxcsrOut), 6228 !RTFLOAT64U_ARE_IDENTICAL(&r64Dst, &paTests[iTest].r64ValOut) 6229 ? " - val" : "", 6230 FormatMxcsr(paTests[iTest].fMxcsrIn) ); 6231 } 6232 } 6233 } 6234 } 6235 6236 6237 /* 6238 * SSE operations converting single signed double-word integers to single-precision floating point values (probably only cvtsi2ss). 6239 */ 6240 TYPEDEF_SUBTEST_TYPE(SSE_BINARY_R32_I32_T, SSE_BINARY_R32_I32_TEST_T, PFNIEMAIMPLSSEF2R32I32); 6241 6242 static const SSE_BINARY_R32_I32_T g_aSseBinaryR32I32[] = 6243 { 6244 ENTRY_BIN(cvtsi2ss_r32_i32), 6245 }; 6246 6247 #ifdef TSTIEMAIMPL_WITH_GENERATOR 6248 static RTEXITCODE SseBinaryR32I32Generate(const char *pszDataFileFmt, uint32_t cTests) 6249 { 6250 cTests = RT_MAX(192, cTests); /* there are 144 standard input variations */ 6251 6252 static int32_t const s_aSpecials[] = 6253 { 6254 INT32_MIN, 6255 INT32_MAX, 6256 /** @todo More specials. */ 6257 }; 6258 6259 X86FXSTATE State; 6260 RT_ZERO(State); 6261 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aSseBinaryR32I32); iFn++) 6262 { 6263 PFNIEMAIMPLSSEF2R32I32 const pfn = g_aSseBinaryR32I32[iFn].pfnNative ? g_aSseBinaryR32I32[iFn].pfnNative : g_aSseBinaryR32I32[iFn].pfn; 6264 6265 PRTSTREAM pStrmOut = NULL; 6266 int rc = RTStrmOpenF("wb", &pStrmOut, pszDataFileFmt, g_aSseBinaryR32I32[iFn].pszName); 6267 if (RT_FAILURE(rc)) 6268 { 6269 RTMsgError("Failed to open data file for %s for writing: %Rrc", g_aSseBinaryR32I32[iFn].pszName, rc); 6270 return RTEXITCODE_FAILURE; 6271 } 6272 6273 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 6274 { 6275 SSE_BINARY_R32_I32_TEST_T TestData; RT_ZERO(TestData); 6276 6277 TestData.i32ValIn = iTest < cTests ? RandI32Src2(iTest) : s_aSpecials[iTest - cTests]; 6278 6279 uint32_t const fMxcsr = RandMxcsr() & X86_MXCSR_XCPT_FLAGS; 6280 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) 6281 for (uint8_t iDaz = 0; iDaz < 2; iDaz++) 6282 for (uint8_t iFz = 0; iFz < 2; iFz++) 6283 { 6284 State.MXCSR = (fMxcsr & ~X86_MXCSR_RC_MASK) 6285 | (iRounding << X86_MXCSR_RC_SHIFT) 6286 | (iDaz ? X86_MXCSR_DAZ : 0) 6287 | (iFz ? X86_MXCSR_FZ : 0) 6288 | X86_MXCSR_XCPT_MASK; 6289 uint32_t fMxcsrM; RTFLOAT32U r32OutM; 6290 pfn(&State, &fMxcsrM, &r32OutM, &TestData.i32ValIn); 6291 TestData.fMxcsrIn = State.MXCSR; 6292 TestData.fMxcsrOut = fMxcsrM; 6293 TestData.r32ValOut = r32OutM; 6294 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6295 6296 State.MXCSR = State.MXCSR & ~X86_MXCSR_XCPT_MASK; 6297 uint32_t fMxcsrU; RTFLOAT32U r32OutU; 6298 pfn(&State, &fMxcsrU, &r32OutU, &TestData.i32ValIn); 6299 TestData.fMxcsrIn = State.MXCSR; 6300 TestData.fMxcsrOut = fMxcsrU; 6301 TestData.r32ValOut = r32OutU; 6302 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6303 6304 uint16_t fXcpt = (fMxcsrM | fMxcsrU) & X86_MXCSR_XCPT_FLAGS; 6305 if (fXcpt) 6306 { 6307 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | fXcpt; 6308 uint32_t fMxcsr1; RTFLOAT32U r32Out1; 6309 pfn(&State, &fMxcsr1, &r32Out1, &TestData.i32ValIn); 6310 TestData.fMxcsrIn = State.MXCSR; 6311 TestData.fMxcsrOut = fMxcsr1; 6312 TestData.r32ValOut = r32Out1; 6313 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6314 6315 if (((fMxcsr1 & X86_MXCSR_XCPT_FLAGS) & fXcpt) != (fMxcsr1 & X86_MXCSR_XCPT_FLAGS)) 6316 { 6317 fXcpt |= fMxcsr1 & X86_MXCSR_XCPT_FLAGS; 6318 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | (fXcpt << X86_MXCSR_XCPT_MASK_SHIFT); 6319 uint32_t fMxcsr2; RTFLOAT32U r32Out2; 6320 pfn(&State, &fMxcsr2, &r32Out2, &TestData.i32ValIn); 6321 TestData.fMxcsrIn = State.MXCSR; 6322 TestData.fMxcsrOut = fMxcsr2; 6323 TestData.r32ValOut = r32Out2; 6324 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6325 } 6326 if (!RT_IS_POWER_OF_TWO(fXcpt)) 6327 for (uint16_t fUnmasked = 1; fUnmasked <= X86_MXCSR_PE; fUnmasked <<= 1) 6328 if (fUnmasked & fXcpt) 6329 { 6330 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | ((fXcpt & ~fUnmasked) << X86_MXCSR_XCPT_MASK_SHIFT); 6331 uint32_t fMxcsr3; RTFLOAT32U r32Out3; 6332 pfn(&State, &fMxcsr3, &r32Out3, &TestData.i32ValIn); 6333 TestData.fMxcsrIn = State.MXCSR; 6334 TestData.fMxcsrOut = fMxcsr3; 6335 TestData.r32ValOut = r32Out3; 6336 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6337 } 6338 } 6339 } 6340 } 6341 rc = RTStrmClose(pStrmOut); 6342 if (RT_FAILURE(rc)) 6343 { 6344 RTMsgError("Failed to close data file for %s: %Rrc", g_aSseBinaryR32I32[iFn].pszName, rc); 6345 return RTEXITCODE_FAILURE; 6346 } 6347 } 6348 6349 return RTEXITCODE_SUCCESS; 6350 } 6351 #endif 6352 6353 6354 static void SseBinaryR32I32Test(void) 6355 { 6356 X86FXSTATE State; 6357 RT_ZERO(State); 6358 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aSseBinaryR32I32); iFn++) 6359 { 6360 if (!SubTestAndCheckIfEnabled(g_aSseBinaryR32I32[iFn].pszName)) 6361 continue; 6362 6363 uint32_t const cTests = *g_aSseBinaryR32I32[iFn].pcTests; 6364 SSE_BINARY_R32_I32_TEST_T const * const paTests = g_aSseBinaryR32I32[iFn].paTests; 6365 PFNIEMAIMPLSSEF2R32I32 pfn = g_aSseBinaryR32I32[iFn].pfn; 6366 uint32_t const cVars = COUNT_VARIATIONS(g_aSseBinaryR32I32[iFn]); 6367 if (!cTests) RTTestSkipped(g_hTest, "no tests"); 6368 for (uint32_t iVar = 0; iVar < cVars; iVar++) 6369 { 6370 for (uint32_t iTest = 0; iTest < cTests / sizeof(SSE_BINARY_R32_I32_TEST_T); iTest++) 6371 { 6372 uint32_t fMxcsr = 0; 6373 RTFLOAT32U r32Dst; RT_ZERO(r32Dst); 6374 6375 State.MXCSR = paTests[iTest].fMxcsrIn; 6376 pfn(&State, &fMxcsr, &r32Dst, &paTests[iTest].i32ValIn); 6377 if ( fMxcsr != paTests[iTest].fMxcsrOut 6378 || !RTFLOAT32U_ARE_IDENTICAL(&r32Dst, &paTests[iTest].r32ValOut)) 6379 RTTestFailed(g_hTest, "#%04u%s: mxcsr=%#08x in1=%RI32\n" 6380 "%s -> mxcsr=%#08x %RI32\n" 6381 "%s expected %#08x %RI32%s%s (%s)\n", 6382 iTest, iVar ? "/n" : "", paTests[iTest].fMxcsrIn, 6383 &paTests[iTest].i32ValIn, 6384 iVar ? " " : "", fMxcsr, FormatR32(&r32Dst), 6385 iVar ? " " : "", paTests[iTest].fMxcsrOut, FormatR32(&paTests[iTest].r32ValOut), 6386 MxcsrDiff(fMxcsr, paTests[iTest].fMxcsrOut), 6387 !RTFLOAT32U_ARE_IDENTICAL(&r32Dst, &paTests[iTest].r32ValOut) 6388 ? " - val" : "", 6389 FormatMxcsr(paTests[iTest].fMxcsrIn) ); 6390 } 6391 } 6392 } 6393 } 6394 6395 6396 /* 6397 * SSE operations converting single signed quad-word integers to single-precision floating point values (probably only cvtsi2ss). 6398 */ 6399 TYPEDEF_SUBTEST_TYPE(SSE_BINARY_R32_I64_T, SSE_BINARY_R32_I64_TEST_T, PFNIEMAIMPLSSEF2R32I64); 6400 6401 static const SSE_BINARY_R32_I64_T g_aSseBinaryR32I64[] = 6402 { 6403 ENTRY_BIN(cvtsi2ss_r32_i64), 6404 }; 6405 6406 #ifdef TSTIEMAIMPL_WITH_GENERATOR 6407 static RTEXITCODE SseBinaryR32I64Generate(const char *pszDataFileFmt, uint32_t cTests) 6408 { 6409 cTests = RT_MAX(192, cTests); /* there are 144 standard input variations */ 6410 6411 static int64_t const s_aSpecials[] = 6412 { 6413 INT64_MIN, 6414 INT64_MAX 6415 /** @todo More specials. */ 6416 }; 6417 6418 X86FXSTATE State; 6419 RT_ZERO(State); 6420 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aSseBinaryR32I64); iFn++) 6421 { 6422 PFNIEMAIMPLSSEF2R32I64 const pfn = g_aSseBinaryR32I64[iFn].pfnNative ? g_aSseBinaryR32I64[iFn].pfnNative : g_aSseBinaryR32I64[iFn].pfn; 6423 6424 PRTSTREAM pStrmOut = NULL; 6425 int rc = RTStrmOpenF("wb", &pStrmOut, pszDataFileFmt, g_aSseBinaryR32I64[iFn].pszName); 6426 if (RT_FAILURE(rc)) 6427 { 6428 RTMsgError("Failed to open data file for %s for writing: %Rrc", g_aSseBinaryR32I64[iFn].pszName, rc); 6429 return RTEXITCODE_FAILURE; 6430 } 6431 6432 for (uint32_t iTest = 0; iTest < cTests + RT_ELEMENTS(s_aSpecials); iTest += 1) 6433 { 6434 SSE_BINARY_R32_I64_TEST_T TestData; RT_ZERO(TestData); 6435 6436 TestData.i64ValIn = iTest < cTests ? RandI64Src(iTest) : s_aSpecials[iTest - cTests]; 6437 6438 uint32_t const fMxcsr = RandMxcsr() & X86_MXCSR_XCPT_FLAGS; 6439 for (uint16_t iRounding = 0; iRounding < 4; iRounding++) 6440 for (uint8_t iDaz = 0; iDaz < 2; iDaz++) 6441 for (uint8_t iFz = 0; iFz < 2; iFz++) 6442 { 6443 State.MXCSR = (fMxcsr & ~X86_MXCSR_RC_MASK) 6444 | (iRounding << X86_MXCSR_RC_SHIFT) 6445 | (iDaz ? X86_MXCSR_DAZ : 0) 6446 | (iFz ? X86_MXCSR_FZ : 0) 6447 | X86_MXCSR_XCPT_MASK; 6448 uint32_t fMxcsrM; RTFLOAT32U r32OutM; 6449 pfn(&State, &fMxcsrM, &r32OutM, &TestData.i64ValIn); 6450 TestData.fMxcsrIn = State.MXCSR; 6451 TestData.fMxcsrOut = fMxcsrM; 6452 TestData.r32ValOut = r32OutM; 6453 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6454 6455 State.MXCSR = State.MXCSR & ~X86_MXCSR_XCPT_MASK; 6456 uint32_t fMxcsrU; RTFLOAT32U r32OutU; 6457 pfn(&State, &fMxcsrU, &r32OutU, &TestData.i64ValIn); 6458 TestData.fMxcsrIn = State.MXCSR; 6459 TestData.fMxcsrOut = fMxcsrU; 6460 TestData.r32ValOut = r32OutU; 6461 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6462 6463 uint16_t fXcpt = (fMxcsrM | fMxcsrU) & X86_MXCSR_XCPT_FLAGS; 6464 if (fXcpt) 6465 { 6466 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | fXcpt; 6467 uint32_t fMxcsr1; RTFLOAT32U r32Out1; 6468 pfn(&State, &fMxcsr1, &r32Out1, &TestData.i64ValIn); 6469 TestData.fMxcsrIn = State.MXCSR; 6470 TestData.fMxcsrOut = fMxcsr1; 6471 TestData.r32ValOut = r32Out1; 6472 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6473 6474 if (((fMxcsr1 & X86_MXCSR_XCPT_FLAGS) & fXcpt) != (fMxcsr1 & X86_MXCSR_XCPT_FLAGS)) 6475 { 6476 fXcpt |= fMxcsr1 & X86_MXCSR_XCPT_FLAGS; 6477 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | (fXcpt << X86_MXCSR_XCPT_MASK_SHIFT); 6478 uint32_t fMxcsr2; RTFLOAT32U r32Out2; 6479 pfn(&State, &fMxcsr2, &r32Out2, &TestData.i64ValIn); 6480 TestData.fMxcsrIn = State.MXCSR; 6481 TestData.fMxcsrOut = fMxcsr2; 6482 TestData.r32ValOut = r32Out2; 6483 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6484 } 6485 if (!RT_IS_POWER_OF_TWO(fXcpt)) 6486 for (uint16_t fUnmasked = 1; fUnmasked <= X86_MXCSR_PE; fUnmasked <<= 1) 6487 if (fUnmasked & fXcpt) 6488 { 6489 State.MXCSR = (State.MXCSR & ~X86_MXCSR_XCPT_MASK) | ((fXcpt & ~fUnmasked) << X86_MXCSR_XCPT_MASK_SHIFT); 6490 uint32_t fMxcsr3; RTFLOAT32U r32Out3; 6491 pfn(&State, &fMxcsr3, &r32Out3, &TestData.i64ValIn); 6492 TestData.fMxcsrIn = State.MXCSR; 6493 TestData.fMxcsrOut = fMxcsr3; 6494 TestData.r32ValOut = r32Out3; 6495 RTStrmWrite(pStrmOut, &TestData, sizeof(TestData)); 6496 } 6497 } 6498 } 6499 } 6500 rc = RTStrmClose(pStrmOut); 6501 if (RT_FAILURE(rc)) 6502 { 6503 RTMsgError("Failed to close data file for %s: %Rrc", g_aSseBinaryR32I64[iFn].pszName, rc); 6504 return RTEXITCODE_FAILURE; 6505 } 6506 } 6507 6508 return RTEXITCODE_SUCCESS; 6509 } 6510 #endif 6511 6512 6513 static void SseBinaryR32I64Test(void) 6514 { 6515 X86FXSTATE State; 6516 RT_ZERO(State); 6517 for (size_t iFn = 0; iFn < RT_ELEMENTS(g_aSseBinaryR32I64); iFn++) 6518 { 6519 if (!SubTestAndCheckIfEnabled(g_aSseBinaryR32I64[iFn].pszName)) 6520 continue; 6521 6522 uint32_t const cTests = *g_aSseBinaryR32I64[iFn].pcTests; 6523 SSE_BINARY_R32_I64_TEST_T const * const paTests = g_aSseBinaryR32I64[iFn].paTests; 6524 PFNIEMAIMPLSSEF2R32I64 pfn = g_aSseBinaryR32I64[iFn].pfn; 6525 uint32_t const cVars = COUNT_VARIATIONS(g_aSseBinaryR32I64[iFn]); 6526 if (!cTests) RTTestSkipped(g_hTest, "no tests"); 6527 for (uint32_t iVar = 0; iVar < cVars; iVar++) 6528 { 6529 for (uint32_t iTest = 0; iTest < cTests / sizeof(SSE_BINARY_R32_I64_TEST_T); iTest++) 6530 { 6531 uint32_t fMxcsr = 0; 6532 RTFLOAT32U r32Dst; RT_ZERO(r32Dst); 6533 6534 State.MXCSR = paTests[iTest].fMxcsrIn; 6535 pfn(&State, &fMxcsr, &r32Dst, &paTests[iTest].i64ValIn); 6536 if ( fMxcsr != paTests[iTest].fMxcsrOut 6537 || !RTFLOAT32U_ARE_IDENTICAL(&r32Dst, &paTests[iTest].r32ValOut)) 6538 RTTestFailed(g_hTest, "#%04u%s: mxcsr=%#08x in1=%RI64\n" 6539 "%s -> mxcsr=%#08x %RI32\n" 6540 "%s expected %#08x %RI32%s%s (%s)\n", 6541 iTest, iVar ? "/n" : "", paTests[iTest].fMxcsrIn, 6542 &paTests[iTest].i64ValIn, 6543 iVar ? " " : "", fMxcsr, FormatR32(&r32Dst), 6544 iVar ? " " : "", paTests[iTest].fMxcsrOut, FormatR32(&paTests[iTest].r32ValOut), 6545 MxcsrDiff(fMxcsr, paTests[iTest].fMxcsrOut), 6546 !RTFLOAT32U_ARE_IDENTICAL(&r32Dst, &paTests[iTest].r32ValOut) 6547 ? " - val" : "", 6548 FormatMxcsr(paTests[iTest].fMxcsrIn) ); 6549 } 6550 } 6551 } 6552 } 6553 6554 5921 6555 5922 6556 int main(int argc, char **argv) … … 6261 6895 if (rcExit == RTEXITCODE_SUCCESS) 6262 6896 rcExit = SseBinaryU128R64Generate(pszDataFileFmt, cTests); 6897 6263 6898 if (rcExit == RTEXITCODE_SUCCESS) 6264 6899 rcExit = SseBinaryI32R64Generate(pszDataFileFmt, cTests); … … 6269 6904 if (rcExit == RTEXITCODE_SUCCESS) 6270 6905 rcExit = SseBinaryI64R32Generate(pszDataFileFmt, cTests); 6906 6907 if (rcExit == RTEXITCODE_SUCCESS) 6908 rcExit = SseBinaryR64I32Generate(pszDataFileFmt, cTests); 6909 if (rcExit == RTEXITCODE_SUCCESS) 6910 rcExit = SseBinaryR64I64Generate(pszDataFileFmt, cTests); 6911 if (rcExit == RTEXITCODE_SUCCESS) 6912 rcExit = SseBinaryR32I32Generate(pszDataFileFmt, cTests); 6913 if (rcExit == RTEXITCODE_SUCCESS) 6914 rcExit = SseBinaryR32I64Generate(pszDataFileFmt, cTests); 6915 6271 6916 if (rcExit != RTEXITCODE_SUCCESS) 6272 6917 return rcExit; … … 6368 7013 SseBinaryU128R32Test(); 6369 7014 SseBinaryU128R64Test(); 7015 6370 7016 SseBinaryI32R64Test(); 6371 7017 SseBinaryI64R64Test(); 6372 7018 SseBinaryI32R32Test(); 6373 7019 SseBinaryI64R32Test(); 7020 7021 SseBinaryR64I32Test(); 7022 SseBinaryR64I64Test(); 7023 SseBinaryR32I32Test(); 7024 SseBinaryR32I64Test(); 6374 7025 } 6375 7026 } -
trunk/src/VBox/VMM/testcase/tstIEMAImpl.h
r96732 r96742 418 418 RTFLOAT32U r32ValIn; 419 419 } SSE_BINARY_I64_R32_TEST_T; 420 421 typedef struct SSE_BINARY_R32_I32_TEST_T 422 { 423 uint32_t fMxcsrIn; 424 uint32_t fMxcsrOut; 425 uint32_t u32Padding; 426 int32_t i32ValIn; 427 RTFLOAT32U r32ValOut; 428 } SSE_BINARY_R32_I32_TEST_T; 429 430 typedef struct SSE_BINARY_R32_I64_TEST_T 431 { 432 uint32_t fMxcsrIn; 433 uint32_t fMxcsrOut; 434 int64_t i64ValIn; 435 RTFLOAT32U r32ValOut; 436 } SSE_BINARY_R32_I64_TEST_T; 437 438 typedef struct SSE_BINARY_R64_I32_TEST_T 439 { 440 uint32_t fMxcsrIn; 441 uint32_t fMxcsrOut; 442 uint32_t u32Padding; 443 int32_t i32ValIn; 444 RTFLOAT64U r64ValOut; 445 } SSE_BINARY_R64_I32_TEST_T; 446 447 typedef struct SSE_BINARY_R64_I64_TEST_T 448 { 449 uint32_t fMxcsrIn; 450 uint32_t fMxcsrOut; 451 int64_t i64ValIn; 452 RTFLOAT64U r64ValOut; 453 } SSE_BINARY_R64_I64_TEST_T; 420 454 421 455 /** @} */ … … 849 883 TSTIEM_DECLARE_TEST_ARRAY_BIN(SseBinary, SSE_BINARY_I64_R32_TEST_T, cvtss2si_i64_r32 ); 850 884 885 TSTIEM_DECLARE_TEST_ARRAY_BIN(SseBinary, SSE_BINARY_R32_I32_TEST_T, cvtsi2ss_r32_i32 ); 886 TSTIEM_DECLARE_TEST_ARRAY_BIN(SseBinary, SSE_BINARY_R32_I64_TEST_T, cvtsi2ss_r32_i64 ); 887 888 TSTIEM_DECLARE_TEST_ARRAY_BIN(SseBinary, SSE_BINARY_R64_I32_TEST_T, cvtsi2sd_r64_i32 ); 889 TSTIEM_DECLARE_TEST_ARRAY_BIN(SseBinary, SSE_BINARY_R64_I64_TEST_T, cvtsi2sd_r64_i64 ); 890 851 891 RT_C_DECLS_END 852 892 -
trunk/src/VBox/VMM/testcase/tstIEMAImplDataSseBinary.S
r96732 r96742 113 113 IEM_TEST_DATA cvttss2si_i64_r32, "tstIEMAImplDataSseBinary-cvttss2si_i64_r32.bin" 114 114 IEM_TEST_DATA cvtss2si_i64_r32, "tstIEMAImplDataSseBinary-cvtss2si_i64_r32.bin" 115 116 IEM_TEST_DATA cvtsi2ss_r32_i32, "tstIEMAImplDataSseBinary-cvtsi2ss_r32_i32.bin" 117 IEM_TEST_DATA cvtsi2ss_r32_i64, "tstIEMAImplDataSseBinary-cvtsi2ss_r32_i64.bin" 118 119 IEM_TEST_DATA cvtsi2sd_r64_i32, "tstIEMAImplDataSseBinary-cvtsi2sd_r64_i32.bin" 120 IEM_TEST_DATA cvtsi2sd_r64_i64, "tstIEMAImplDataSseBinary-cvtsi2sd_r64_i64.bin" -
trunk/src/VBox/VMM/testcase/tstIEMAImplDataSseBinary.asm
r96732 r96742 111 111 IEM_TEST_DATA cvttss2si_i64_r32, "tstIEMAImplDataSseBinary-cvttss2si_i64_r32.bin" 112 112 IEM_TEST_DATA cvtss2si_i64_r32, "tstIEMAImplDataSseBinary-cvtss2si_i64_r32.bin" 113 114 IEM_TEST_DATA cvtsi2ss_r32_i32, "tstIEMAImplDataSseBinary-cvtsi2ss_r32_i32.bin" 115 IEM_TEST_DATA cvtsi2ss_r32_i64, "tstIEMAImplDataSseBinary-cvtsi2ss_r32_i64.bin" 116 117 IEM_TEST_DATA cvtsi2sd_r64_i32, "tstIEMAImplDataSseBinary-cvtsi2sd_r64_i32.bin" 118 IEM_TEST_DATA cvtsi2sd_r64_i64, "tstIEMAImplDataSseBinary-cvtsi2sd_r64_i64.bin"
Note:
See TracChangeset
for help on using the changeset viewer.