diff --git a/docs/area-owners.md b/docs/area-owners.md index e1889072f9f736..7960fcaa9ef907 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -31,7 +31,7 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi | area-Diagnostics-mono | @tommcdon | @tommcdon @mdh1418 @thaystg | | | area-EnC-mono | @tommcdon | @mikelle-rogers @thaystg | Hot Reload on WebAssembly, Android, iOS, etc . @lambdageek to consult | | area-ExceptionHandling-coreclr | @mangod9 | @janvorli | | -| area-Extensions-Caching | @ericstj | @dotnet/area-extensions-caching | Consultants: @mgravell, @sebastienros | +| area-Extensions-Caching | @jeffhandley | @dotnet/area-extensions-caching | Consultants: @mgravell, @sebastienros | | area-Extensions-Configuration | @ericstj | @dotnet/area-extensions-configuration | Consultants: @eerhardt | | area-Extensions-DependencyInjection | @ericstj | @dotnet/area-extensions-dependencyinjection | Consultants: @halter73, @benjaminpetit | | area-Extensions-FileSystem | @jeffhandley | @dotnet/area-extensions-filesystem | | @@ -128,15 +128,15 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi | area-System.ServiceModel | @HongGit | @HongGit @mconnew | Repo: https://github.com/dotnet/WCF
Packages: | | area-System.ServiceModel.Syndication | @HongGit | @StephenMolloy @HongGit | | | area-System.ServiceProcess | @ericstj | @dotnet/area-system-serviceprocess | | -| area-System.Speech | @jeffhandley | @ericstj @jeffhandley | | -| area-System.Text.Encoding | @jeffhandley | @dotnet/area-system-text-encoding | | -| area-System.Text.Encodings.Web | @jeffhandley | @dotnet/area-system-text-encodings-web | | +| area-System.Speech | @ericstj | @dotnet/area-system-speech | | +| area-System.Text.Encoding | @ericstj | @dotnet/area-system-text-encoding | | +| area-System.Text.Encodings.Web | @ericstj | @dotnet/area-system-text-encodings-web | | | area-System.Text.Json | @jeffhandley | @dotnet/area-system-text-json | | | area-System.Text.RegularExpressions | @ericstj | @dotnet/area-system-text-regularexpressions | Consultants: @stephentoub | | area-System.Threading | @mangod9 | @kouvel | | -| area-System.Threading.Channels | @ericstj | @dotnet/area-system-threading-channels | Consultants: @stephentoub | +| area-System.Threading.Channels | @jeffhandley | @dotnet/area-system-threading-channels | Consultants: @stephentoub | | area-System.Threading.RateLimiting | @rafikiassumani-msft | @BrennanConroy @halter73 | | -| area-System.Threading.Tasks | @ericstj | @dotnet/area-system-threading-tasks | Consultants: @stephentoub | +| area-System.Threading.Tasks | @jeffhandley | @dotnet/area-system-threading-tasks | Consultants: @stephentoub | | area-System.Transactions | @sammonort | @roji | | | area-System.Xml | @jeffhandley | @dotnet/area-system-xml | | | area-TieredCompilation-coreclr | @mangod9 | @kouvel | | diff --git a/eng/Subsets.props b/eng/Subsets.props index 502fd50fbc25c5..4ff3be6bccf268 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -89,7 +89,7 @@ CoreCLR - CoreCLR + CoreCLR Mono Mono $(PrimaryRuntimeFlavor) diff --git a/eng/testing/BrowserVersions.props b/eng/testing/BrowserVersions.props index 561cdb08a28a20..674577d8559fc2 100644 --- a/eng/testing/BrowserVersions.props +++ b/eng/testing/BrowserVersions.props @@ -1,13 +1,13 @@ - 131.0.6778.85 - 1368529 - https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/1368532 - 13.1.201 - 131.0.6778.33 - 1368529 - https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1368547 - 13.1.201 + 132.0.6834.83 + 1381561 + https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/1381561 + 13.2.152 + 132.0.6834.84 + 1381561 + https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1381570 + 13.2.152 125.0.1 0.34.0 125.0.1 diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 288891b0daab44..12f0ed85e03c66 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -5258,30 +5258,6 @@ static GCInfo::WriteBarrierForm GetWriteBarrierForm(Compiler* comp, ValueNum vn) return GetWriteBarrierForm(comp, funcApp.m_args[0]); } } - if (funcApp.m_func == VNF_InitVal) - { - unsigned lclNum = vnStore->CoercedConstantValue(funcApp.m_args[0]); - assert(lclNum != BAD_VAR_NUM); - CORINFO_CLASS_HANDLE srcCls = NO_CLASS_HANDLE; - - if (comp->compMethodHasRetVal() && (lclNum == comp->info.compRetBuffArg)) - { - // See if the address is in current method's return buffer - // while the return type is a byref-like type. - srcCls = comp->info.compMethodInfo->args.retTypeClass; - } - else if (lclNum == comp->info.compThisArg) - { - // Same for implicit "this" parameter - assert(!comp->info.compIsStatic); - srcCls = comp->info.compClassHnd; - } - - if ((srcCls != NO_CLASS_HANDLE) && comp->eeIsByrefLike(srcCls)) - { - return GCInfo::WriteBarrierForm::WBF_NoBarrier; - } - } } return GCInfo::WriteBarrierForm::WBF_BarrierUnknown; } diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index e465cd68058ef4..79964ca1289842 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -650,6 +650,7 @@ class CodeGen final : public CodeGenInterface #if defined(TARGET_AMD64) void genAmd64EmitterUnitTestsSse2(); void genAmd64EmitterUnitTestsApx(); + void genAmd64EmitterUnitTestsAvx10v2(); #endif #endif // defined(DEBUG) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 50b947bc5bce14..9c215b0ec69918 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2675,6 +2675,12 @@ void CodeGen::genCodeForBinary(GenTreeOp* tree) break; } + case GT_AND_NOT: + { + ins = INS_bics; + break; + } + default: { noway_assert(!"Unexpected BinaryOp with GTF_SET_FLAGS set"); diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index dec27882bb2285..d535dfb1454570 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -1832,15 +1832,26 @@ void CodeGen::genGenerateMachineCode() #if defined(TARGET_X86) if (compiler->canUseEvexEncoding()) { - if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v1)) + if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v2)) + { + if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v2_V512)) + { + printf("X86 with AVX10.2/512"); + } + else + { + printf("X86 with AVX10.2/256"); + } + } + else if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v1)) { if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v1_V512)) { - printf("X86 with AVX10/512"); + printf("X86 with AVX10.1/512"); } else { - printf("X86 with AVX10/256"); + printf("X86 with AVX10.1/256"); } } else @@ -1860,15 +1871,26 @@ void CodeGen::genGenerateMachineCode() #elif defined(TARGET_AMD64) if (compiler->canUseEvexEncoding()) { - if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v1)) + if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v2)) + { + if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v2_V512)) + { + printf("X64 with AVX10.2/512"); + } + else + { + printf("X64 with AVX10.2/256"); + } + } + else if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v1)) { if (compiler->compOpportunisticallyDependsOn(InstructionSet_AVX10v1_V512)) { - printf("X64 with AVX10/512"); + printf("X64 with AVX10.1/512"); } else { - printf("X64 with AVX10/256"); + printf("X64 with AVX10.1/256"); } } else diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 53257afb010b74..945f468d86fa81 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -2712,6 +2712,10 @@ void CodeGen::genEmitterUnitTests() { genAmd64EmitterUnitTestsApx(); } + if (unitTestSectionAll || (strstr(unitTestSection, "avx10v2") != nullptr)) + { + genAmd64EmitterUnitTestsAvx10v2(); + } #elif defined(TARGET_ARM64) if (unitTestSectionAll || (strstr(unitTestSection, "general") != nullptr)) diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 750b2d9818ba73..4f9b2c4f0184b2 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -9239,6 +9239,159 @@ void CodeGen::genAmd64EmitterUnitTestsApx() theEmitter->emitIns_S(INS_not, EA_2BYTE, 0, 0); } +void CodeGen::genAmd64EmitterUnitTestsAvx10v2() +{ + // All the Avx10.2 instructions are evex and evex only has one size. + // Also, there is no specialized handling for XMM0 vs XMM9 vs XMM16 + + emitter* theEmitter = GetEmitter(); + + genDefineTempLabel(genCreateTempLabel()); + + // This test suite needs AVX10.2 enabled. + if (!theEmitter->emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2)) + { + return; + } + + // packed conversion instructions + theEmitter->emitIns_R_R(INS_vcvttps2dqs, EA_16BYTE, REG_XMM0, REG_XMM1); // xmm + theEmitter->emitIns_R_R(INS_vcvttps2dqs, EA_16BYTE, REG_XMM9, REG_XMM10); // xmm + theEmitter->emitIns_R_R(INS_vcvttps2dqs, EA_16BYTE, REG_XMM15, REG_XMM16); // xmm + theEmitter->emitIns_R_R(INS_vcvttps2dqs, EA_32BYTE, REG_XMM0, REG_XMM1); // ymm + theEmitter->emitIns_R_R(INS_vcvttps2dqs, EA_64BYTE, REG_XMM0, REG_XMM1); // zmm + + theEmitter->emitIns_R_R(INS_vcvttps2udqs, EA_16BYTE, REG_XMM0, REG_XMM1); // xmm + theEmitter->emitIns_R_R(INS_vcvttps2udqs, EA_16BYTE, REG_XMM9, REG_XMM10); // xmm + theEmitter->emitIns_R_R(INS_vcvttps2udqs, EA_16BYTE, REG_XMM15, REG_XMM16); // xmm + theEmitter->emitIns_R_R(INS_vcvttps2udqs, EA_32BYTE, REG_XMM0, REG_XMM1); // ymm + theEmitter->emitIns_R_R(INS_vcvttps2udqs, EA_64BYTE, REG_XMM0, REG_XMM1); // zmm + + theEmitter->emitIns_R_R(INS_vcvttpd2qqs, EA_16BYTE, REG_XMM0, REG_XMM1); // xmm + theEmitter->emitIns_R_R(INS_vcvttpd2qqs, EA_16BYTE, REG_XMM9, REG_XMM10); // xmm + theEmitter->emitIns_R_R(INS_vcvttpd2qqs, EA_16BYTE, REG_XMM15, REG_XMM16); // xmm + theEmitter->emitIns_R_R(INS_vcvttpd2qqs, EA_32BYTE, REG_XMM0, REG_XMM1); // ymm + theEmitter->emitIns_R_R(INS_vcvttpd2qqs, EA_64BYTE, REG_XMM0, REG_XMM1); // zmm + + theEmitter->emitIns_R_R(INS_vcvttpd2uqqs, EA_16BYTE, REG_XMM0, REG_XMM1); // xmm + theEmitter->emitIns_R_R(INS_vcvttpd2uqqs, EA_16BYTE, REG_XMM9, REG_XMM10); // xmm + theEmitter->emitIns_R_R(INS_vcvttpd2uqqs, EA_16BYTE, REG_XMM15, REG_XMM16); // xmm + theEmitter->emitIns_R_R(INS_vcvttpd2uqqs, EA_32BYTE, REG_XMM0, REG_XMM1); // ymm + theEmitter->emitIns_R_R(INS_vcvttpd2uqqs, EA_64BYTE, REG_XMM0, REG_XMM1); // zmm + + // scalar conversion instructions + theEmitter->emitIns_R_R(INS_vcvttsd2sis32, EA_4BYTE, REG_EAX, REG_XMM0); + theEmitter->emitIns_R_R(INS_vcvttsd2sis64, EA_8BYTE, REG_RAX, REG_XMM0); + theEmitter->emitIns_R_R(INS_vcvttsd2usis32, EA_4BYTE, REG_EAX, REG_XMM0); + theEmitter->emitIns_R_R(INS_vcvttsd2usis64, EA_8BYTE, REG_RAX, REG_XMM0); + theEmitter->emitIns_R_R(INS_vcvttss2sis32, EA_4BYTE, REG_EAX, REG_XMM0); + theEmitter->emitIns_R_R(INS_vcvttss2sis64, EA_8BYTE, REG_RAX, REG_XMM0); + theEmitter->emitIns_R_R(INS_vcvttss2usis32, EA_4BYTE, REG_EAX, REG_XMM0); + theEmitter->emitIns_R_R(INS_vcvttss2usis64, EA_8BYTE, REG_RAX, REG_XMM0); + + // minmax instruction + theEmitter->emitIns_R_R_R_I(INS_vminmaxss, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2, 0); + theEmitter->emitIns_R_R_R_I(INS_vminmaxss, EA_16BYTE, REG_XMM8, REG_XMM9, REG_XMM10, 0); + theEmitter->emitIns_R_R_R_I(INS_vminmaxss, EA_16BYTE, REG_XMM14, REG_XMM15, REG_XMM16, 0); + + theEmitter->emitIns_R_R_R_I(INS_vminmaxsd, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2, 0); + theEmitter->emitIns_R_R_R_I(INS_vminmaxsd, EA_16BYTE, REG_XMM9, REG_XMM10, REG_XMM11, 0); + theEmitter->emitIns_R_R_R_I(INS_vminmaxsd, EA_16BYTE, REG_XMM16, REG_XMM17, REG_XMM18, 0); + + theEmitter->emitIns_R_R_R_I(INS_vminmaxps, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2, 0); + theEmitter->emitIns_R_R_R_I(INS_vminmaxpd, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2, 0); + theEmitter->emitIns_R_R_R_I(INS_vminmaxps, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2, 0); + theEmitter->emitIns_R_R_R_I(INS_vminmaxpd, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2, 0); + + // VCVT[,T]PS2I[,U]BS + theEmitter->emitIns_R_R(INS_vcvtps2ibs, EA_16BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvtps2ibs, EA_32BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvtps2ibs, EA_32BYTE, REG_XMM0, REG_XMM1, INS_OPTS_EVEX_er_ru); + theEmitter->emitIns_R_R(INS_vcvtps2ibs, EA_64BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvtps2ibs, EA_64BYTE, REG_XMM0, REG_XMM1, INS_OPTS_EVEX_er_ru); + + theEmitter->emitIns_R_R(INS_vcvtps2iubs, EA_16BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvtps2iubs, EA_32BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvtps2iubs, EA_32BYTE, REG_XMM0, REG_XMM1, INS_OPTS_EVEX_er_rz); + theEmitter->emitIns_R_R(INS_vcvtps2iubs, EA_64BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvtps2iubs, EA_64BYTE, REG_XMM0, REG_XMM1, INS_OPTS_EVEX_er_rz); + + theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_16BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_32BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_32BYTE, REG_XMM0, REG_XMM1, INS_OPTS_EVEX_eb_er_rd); + theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_64BYTE, REG_XMM0, REG_XMM1); + + theEmitter->emitIns_R_R(INS_vcvttps2iubs, EA_16BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvttps2iubs, EA_32BYTE, REG_XMM0, REG_XMM1); + theEmitter->emitIns_R_R(INS_vcvttps2iubs, EA_32BYTE, REG_XMM0, REG_XMM1, INS_OPTS_EVEX_er_ru); + theEmitter->emitIns_R_R(INS_vcvttps2iubs, EA_64BYTE, REG_XMM0, REG_XMM1); + + // VPDPW[SU,US,UU]D[,S] + theEmitter->emitIns_R_R_R(INS_vpdpwsud, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwsud, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwsud, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwsuds, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwsuds, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwsuds, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + + theEmitter->emitIns_R_R_R(INS_vpdpwusd, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwusd, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwusd, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwusds, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwusds, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwusds, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + + theEmitter->emitIns_R_R_R(INS_vpdpwuud, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwuud, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwuud, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwuuds, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwuuds, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpwuuds, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + + // VPDPB[SU,UU,SS]D[,S] + theEmitter->emitIns_R_R_R(INS_vpdpbssd, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbssd, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbssd, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbssds, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbssds, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbssds, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + + theEmitter->emitIns_R_R_R(INS_vpdpbsud, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbsud, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbsud, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbsuds, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbsuds, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbsuds, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + + theEmitter->emitIns_R_R_R(INS_vpdpbuud, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbuud, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbuud, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbuuds, EA_16BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbuuds, EA_32BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + theEmitter->emitIns_R_R_R(INS_vpdpbuuds, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2); + + // VMPSADBW + theEmitter->emitIns_R_R_R_I(INS_vmpsadbw, EA_64BYTE, REG_XMM0, REG_XMM1, REG_XMM2, 0); // zmm + + // VCOMXSD + theEmitter->emitIns_R_R(INS_vcomxsd, EA_16BYTE, REG_XMM0, REG_XMM1); + + // VCOMXSS + theEmitter->emitIns_R_R(INS_vcomxss, EA_16BYTE, REG_XMM0, REG_XMM1); + + // VUCOMXSD + theEmitter->emitIns_R_R(INS_vucomxsd, EA_16BYTE, REG_XMM0, REG_XMM1); + + // VUCOMXSS + theEmitter->emitIns_R_R(INS_vucomxss, EA_16BYTE, REG_XMM0, REG_XMM1); + + // VMOVD + theEmitter->emitIns_R_R(INS_vmovd, EA_16BYTE, REG_XMM0, REG_XMM1); + + // VMOVW + theEmitter->emitIns_R_R(INS_vmovw, EA_16BYTE, REG_XMM0, REG_XMM1); +} + #endif // defined(DEBUG) && defined(TARGET_AMD64) #ifdef PROFILING_SUPPORTED diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 185c7c323c6adb..33dda8c734ca1b 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -4571,7 +4571,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl // Note: the importer is sensitive to block weights, so this has // to happen before importation. // - activePhaseChecks |= PhaseChecks::CHECK_PROFILE; + activePhaseChecks |= PhaseChecks::CHECK_PROFILE | PhaseChecks::CHECK_PROFILE_FLAGS; DoPhase(this, PHASE_INCPROFILE, &Compiler::fgIncorporateProfileData); activePhaseChecks |= PhaseChecks::CHECK_FG_INIT_BLOCK; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 956e05e9b71f00..5190c70c060b3a 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1542,8 +1542,9 @@ enum class PhaseChecks : unsigned int CHECK_LOOPS = 1 << 4, // loop integrity/canonicalization CHECK_LIKELIHOODS = 1 << 5, // profile data likelihood integrity CHECK_PROFILE = 1 << 6, // profile data full integrity - CHECK_LINKED_LOCALS = 1 << 7, // check linked list of locals - CHECK_FG_INIT_BLOCK = 1 << 8, // flow graph has an init block + CHECK_PROFILE_FLAGS = 1 << 7, // blocks with profile-derived weights have BBF_PROF_WEIGHT flag set + CHECK_LINKED_LOCALS = 1 << 8, // check linked list of locals + CHECK_FG_INIT_BLOCK = 1 << 9, // flow graph has an init block }; inline constexpr PhaseChecks operator ~(PhaseChecks a) @@ -1608,8 +1609,9 @@ enum class ProfileChecks : unsigned int CHECK_HASLIKELIHOOD = 1 << 0, // check all FlowEdges for hasLikelihood CHECK_LIKELIHOODSUM = 1 << 1, // check block succesor likelihoods sum to 1 CHECK_LIKELY = 1 << 2, // fully check likelihood based weights - RAISE_ASSERT = 1 << 3, // assert on check failure - CHECK_ALL_BLOCKS = 1 << 4, // check blocks even if bbHasProfileWeight is false + CHECK_FLAGS = 1 << 3, // check blocks with profile-derived weights have BBF_PROF_WEIGHT flag set + RAISE_ASSERT = 1 << 4, // assert on check failure + CHECK_ALL_BLOCKS = 1 << 5, // check blocks even if bbHasProfileWeight is false }; inline constexpr ProfileChecks operator ~(ProfileChecks a) @@ -2866,6 +2868,7 @@ class Compiler bool bbInCatchHandlerILRange(BasicBlock* blk); bool bbInFilterILRange(BasicBlock* blk); + bool bbInCatchHandlerBBRange(BasicBlock* blk); bool bbInFilterBBRange(BasicBlock* blk); bool bbInTryRegions(unsigned regionIndex, BasicBlock* blk); bool bbInExnFlowRegions(unsigned regionIndex, BasicBlock* blk); @@ -5223,15 +5226,13 @@ class Compiler void impMarkInlineCandidate(GenTree* call, CORINFO_CONTEXT_HANDLE exactContextHnd, bool exactContextNeedsRuntimeLookup, - CORINFO_CALL_INFO* callInfo, - IL_OFFSET ilOffset); + CORINFO_CALL_INFO* callInfo); void impMarkInlineCandidateHelper(GenTreeCall* call, uint8_t candidateIndex, CORINFO_CONTEXT_HANDLE exactContextHnd, bool exactContextNeedsRuntimeLookup, CORINFO_CALL_INFO* callInfo, - IL_OFFSET ilOffset, InlineResult* inlineResult); bool impTailCallRetTypeCompatible(bool allowWidening, diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index dc0f977b608622..02461633f3c547 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1607,36 +1607,36 @@ class emitter bool idIsBound() const { - assert(!IsAvx512OrPriorInstruction(_idIns)); + assert(!IsSimdInstruction(_idIns)); return _idBound != 0; } void idSetIsBound() { - assert(!IsAvx512OrPriorInstruction(_idIns)); + assert(!IsSimdInstruction(_idIns)); _idBound = 1; } #ifndef TARGET_ARMARCH bool idIsCallRegPtr() const { - assert(!IsAvx512OrPriorInstruction(_idIns)); + assert(!IsSimdInstruction(_idIns)); return _idCallRegPtr != 0; } void idSetIsCallRegPtr() { - assert(!IsAvx512OrPriorInstruction(_idIns)); + assert(!IsSimdInstruction(_idIns)); _idCallRegPtr = 1; } #endif // !TARGET_ARMARCH bool idIsTlsGD() const { - assert(!IsAvx512OrPriorInstruction(_idIns)); + assert(!IsSimdInstruction(_idIns)); return _idTlsGD != 0; } void idSetTlsGD() { - assert(!IsAvx512OrPriorInstruction(_idIns)); + assert(!IsSimdInstruction(_idIns)); _idTlsGD = 1; } @@ -1645,12 +1645,12 @@ class emitter // code, it is not necessary to generate GC info for a call so labeled. bool idIsNoGC() const { - assert(!IsAvx512OrPriorInstruction(_idIns)); + assert(!IsSimdInstruction(_idIns)); return _idNoGC != 0; } void idSetIsNoGC(bool val) { - assert(!IsAvx512OrPriorInstruction(_idIns)); + assert(!IsSimdInstruction(_idIns)); _idNoGC = val; } @@ -1703,7 +1703,7 @@ class emitter unsigned idGetEvexAaaContext() const { - assert(IsAvx512OrPriorInstruction(_idIns)); + assert(IsSimdInstruction(_idIns)); return _idEvexAaaContext; } @@ -1719,7 +1719,7 @@ class emitter bool idIsEvexZContextSet() const { - assert(IsAvx512OrPriorInstruction(_idIns)); + assert(IsSimdInstruction(_idIns)); return _idEvexZContext != 0; } diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 77f8787a3e2457..ddec8af5e753f5 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -1417,7 +1417,9 @@ bool emitter::TakesRex2Prefix(const instrDesc* id) const // - R, X, B, W - bits to express corresponding REX prefixes.Additionally, X combines with B to expand r/m to 32 SIMD // registers // - R' - combines with R to expand reg to 32 SIMD registers -// - mm - lower 2 bits of m-mmmmm (5-bit) in corresponding VEX prefix +// - mmm - Encodes the map number to which the instruction belongs to +// mm - lower 2 bits of m-mmmmm (5-bit) in corresponding VEX prefix (For AVX10.1 and below) +// mmm - map number to which the instruction belongs to (For AVX10.2 and above) // - vvvv (4-bits) - register specifier in 1's complement form; must be 1111 if unused // - pp (2-bits) - opcode extension providing equivalent functionality of a SIMD size prefix // these prefixes are treated mandatory when used with escape opcode 0Fh for @@ -1433,6 +1435,11 @@ bool emitter::TakesRex2Prefix(const instrDesc* id) const // - V'- bit to extend vvvv // - aaa - specifies mask register // Rest - reserved for future use and usage of them will uresult in Undefined instruction exception. +// - u - Bit to indicate YMM Embedded rounding. +// Set to 1 for isas Avx10.1 and below +// Needs to be set to 0 for AVX10.2 and above to indicate YMM embedded rounding +// - B' - reserved as of now +// set to 0 for future compatibility. // #define DEFAULT_BYTE_EVEX_PREFIX 0x62F07C0800000000ULL @@ -1441,6 +1448,7 @@ bool emitter::TakesRex2Prefix(const instrDesc* id) const #define LBIT_IN_BYTE_EVEX_PREFIX 0x0000002000000000ULL #define LPRIMEBIT_IN_BYTE_EVEX_PREFIX 0x0000004000000000ULL #define ZBIT_IN_BYTE_EVEX_PREFIX 0x0000008000000000ULL +#define uBIT_IN_BYTE_EVEX_PREFIX 0x0000040000000000ULL //------------------------------------------------------------------------ // AddEvexPrefix: Add default EVEX prefix with only LL' bits set. @@ -1482,7 +1490,13 @@ emitter::code_t emitter::AddEvexPrefix(const instrDesc* id, code_t code, emitAtt if (!id->idHasMem()) { - // embedded rounding case. + // ymm embedded rounding case. + if (attr == EA_32BYTE) + { + assert(emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2)); + code &= ~(uBIT_IN_BYTE_EVEX_PREFIX); + } + unsigned roundingMode = id->idGetEvexbContext(); if (roundingMode == 1) { @@ -1740,7 +1754,7 @@ bool emitter::TakesRexWPrefix(const instrDesc* id) const } } - assert(!IsAvx512OrPriorInstruction(ins)); + assert(!IsSimdInstruction(ins)); #ifdef TARGET_AMD64 // movsx should always sign extend out to 8 bytes just because we don't track @@ -2220,8 +2234,14 @@ emitter::code_t emitter::emitExtractEvexPrefix(instruction ins, code_t& code) co // check for a prefix in the 11 position BYTE sizePrefix = (code >> 16) & 0xFF; - if ((sizePrefix != 0) && isPrefix(sizePrefix)) + if (sizePrefix == 0) + { + // no simd prefix for EVEX2 - AVX10.2 and above + assert(emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2)); + } + else if (isPrefix(sizePrefix)) { + // EVEX1 - EVEX encoding before Avx10.2 // 'pp' bits in byte 1 of EVEX prefix allows us to encode SIMD size prefixes as two bits // // 00 - None (0F - packed float) @@ -2256,37 +2276,49 @@ emitter::code_t emitter::emitExtractEvexPrefix(instruction ins, code_t& code) co unreached(); } } + } + else + { + unreached(); + } + // Now the byte in the 22 position should be either of the below: + // 1. An escape byte 0F (For isa before AVX10.2) + // 2. A map number from 0 to 7 (For AVX10.2 and above) + leadingBytes = check; + assert(leadingBytes == 0x0F || (emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2) && + leadingBytes >= 0x00 && leadingBytes <= 0x07)); - // Now the byte in the 22 position must be an escape byte 0F - leadingBytes = check; - assert(leadingBytes == 0x0F); - - // Get rid of both sizePrefix and escape byte - code &= 0x0000FFFFLL; + // Get rid of both sizePrefix and escape byte + code &= 0x0000FFFFLL; - // Check the byte in the 33 position to see if it is 3A or 38. - // In such a case escape bytes must be 0x0F3A or 0x0F38 - check = code & 0xFF; + // Check the byte in the 33 position to see if it is 3A or 38. + // In such a case escape bytes must be 0x0F3A or 0x0F38 + check = code & 0xFF; - if ((check == 0x3A) || (check == 0x38)) - { - leadingBytes = (leadingBytes << 8) | check; - code &= 0x0000FF00LL; - } + if ((check == 0x3A) || (check == 0x38)) + { + leadingBytes = (leadingBytes << 8) | check; + code &= 0x0000FF00LL; } } else { - // 2-byte opcode with the bytes ordered as 0x0011RM22 - // the byte in position 11 must be an escape byte. + // 2-byte opcode with the bytes ordered as 0x0011RM22. There are 2 posibilities here: + // 1. the byte in position 11 must be an escape byte. + // 2. the byte in position 11 must be a map number from 0 to 7. leadingBytes = (code >> 16) & 0xFF; - assert(leadingBytes == 0x0F || leadingBytes == 0x00); + assert(leadingBytes == 0x0F || (emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2) && + leadingBytes >= 0x00 && leadingBytes <= 0x07)); code &= 0xFFFF; } - // If there is an escape byte it must be 0x0F or 0x0F3A or 0x0F38 - // mm bits in byte 0 of EVEX prefix allows us to encode these - // implied leading bytes. They are identical to low two bits of VEX.mmmmm + // Encode the escape byte in the evex prefix using either of the below: + // 1. If there is an escape byte it must be 0x0F or 0x0F3A or 0x0F38 + // mm bits in byte 0 of EVEX prefix allows us to encode these + // implied leading bytes. They are identical to low two bits of VEX.mmmmm + // 2. If there is no escape byte but a map number from 0 to 7, + // EVEX.mmm bits in byte 0 of EVEX prefix allows us to encode these + // map numbers switch (leadingBytes) { @@ -2314,6 +2346,19 @@ emitter::code_t emitter::emitExtractEvexPrefix(instruction ins, code_t& code) co break; } + case 0x05: + { + assert(emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2)); + evexPrefix |= (0x05 << 16); + break; + } + + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x06: + case 0x07: default: { assert(!"encountered unknown leading bytes"); @@ -3066,7 +3111,7 @@ bool emitter::emitInsCanOnlyWriteSSE2OrAVXReg(instrDesc* id) { instruction ins = id->idIns(); - if (!IsAvx512OrPriorInstruction(ins)) + if (!IsSimdInstruction(ins)) { return false; } @@ -3511,7 +3556,7 @@ bool emitter::EncodedBySSE38orSSE3A(instruction ins) const size_t insCode = 0; - if (!IsAvx512OrPriorInstruction(ins)) + if (!IsSimdInstruction(ins)) { return false; } @@ -4081,7 +4126,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeRR(instrDesc* id, code_t code, int val } else { - assert(!IsAvx512OrPriorInstruction(ins)); + assert(!IsSimdInstruction(ins)); } return valSize + emitInsSizeRR(id, code); @@ -4130,7 +4175,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeRR(instrDesc* id) if ((code & 0xFF00) != 0) { - sz += IsAvx512OrPriorInstruction(ins) ? emitInsSize(id, code, includeRexPrefixSize) : 5; + sz += IsSimdInstruction(ins) ? emitInsSize(id, code, includeRexPrefixSize) : 5; } else { @@ -4698,7 +4743,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, code_t code, int val } else { - assert(!IsAvx512OrPriorInstruction(ins)); + assert(!IsSimdInstruction(ins)); } return valSize + emitInsSizeAM(id, code); @@ -4757,7 +4802,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeCV(instrDesc* id, code_t code, int val } else { - assert(!IsAvx512OrPriorInstruction(ins)); + assert(!IsSimdInstruction(ins)); } return valSize + emitInsSizeCV(id, code); @@ -6058,7 +6103,7 @@ void emitter::emitIns_R_I(instruction ins, emitAttr size = EA_SIZE(attr); // Allow emitting SSE2/AVX SIMD instructions of R_I form that can specify EA_16BYTE or EA_32BYTE - assert(size <= EA_PTRSIZE || IsAvx512OrPriorInstruction(ins)); + assert(size <= EA_PTRSIZE || IsSimdInstruction(ins)); noway_assert(emitVerifyEncodable(ins, size, reg)); @@ -6126,7 +6171,7 @@ void emitter::emitIns_R_I(instruction ins, if (valInByte) { - if (IsAvx512OrPriorInstruction(ins)) + if (IsSimdInstruction(ins)) { sz = 1; isSimdInsAndValInByte = true; @@ -6142,7 +6187,7 @@ void emitter::emitIns_R_I(instruction ins, } else { - assert(!IsAvx512OrPriorInstruction(ins)); + assert(!IsSimdInstruction(ins)); if (reg == REG_EAX && !instrIs3opImul(ins)) { @@ -7079,7 +7124,7 @@ void emitter::emitIns_AR(instruction ins, emitAttr attr, regNumber base, int off void emitter::emitIns_AR_R_R( instruction ins, emitAttr attr, regNumber op2Reg, regNumber op3Reg, regNumber base, int offs, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); instrDesc* id = emitNewInstrAmd(attr, offs); @@ -7126,7 +7171,7 @@ void emitter::emitIns_R_A_I( instruction ins, emitAttr attr, regNumber reg1, GenTreeIndir* indir, int ival, insOpts instOptions) { noway_assert(emitVerifyEncodable(ins, EA_SIZE(attr), reg1)); - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); ssize_t offs = indir->Offset(); instrDesc* id = emitNewInstrAmdCns(attr, offs, ival); @@ -7172,7 +7217,7 @@ void emitter::emitIns_R_C_I(instruction ins, } noway_assert(emitVerifyEncodable(ins, EA_SIZE(attr), reg1)); - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); instrDesc* id = emitNewInstrCnsDsp(attr, ival, offs); @@ -7206,7 +7251,7 @@ void emitter::emitIns_R_S_I( instruction ins, emitAttr attr, regNumber reg1, int varx, int offs, int ival, insOpts instOptions) { noway_assert(emitVerifyEncodable(ins, EA_SIZE(attr), reg1)); - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); instrDesc* id = emitNewInstrCns(attr, ival); @@ -7243,7 +7288,7 @@ void emitter::emitIns_R_S_I( void emitter::emitIns_R_R_A( instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, GenTreeIndir* indir, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); ssize_t offs = indir->Offset(); @@ -7267,7 +7312,7 @@ void emitter::emitIns_R_R_A( void emitter::emitIns_R_R_AR(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber base, int offs) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); instrDesc* id = emitNewInstrAmd(attr, offs); @@ -7363,7 +7408,7 @@ void emitter::emitIns_R_R_C(instruction ins, int offs, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); // Static always need relocs @@ -7398,7 +7443,7 @@ void emitter::emitIns_R_R_C(instruction ins, void emitter::emitIns_R_R_R( instruction ins, emitAttr attr, regNumber targetReg, regNumber reg1, regNumber reg2, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins) || IsKInstruction(ins)); instrDesc* id = emitNewInstr(attr); @@ -7426,7 +7471,7 @@ void emitter::emitIns_R_R_R( void emitter::emitIns_R_R_S( instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, int varx, int offs, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); instrDesc* id = emitNewInstr(attr); @@ -7460,7 +7505,7 @@ void emitter::emitIns_R_R_A_I(instruction ins, insFormat fmt, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); ssize_t offs = indir->Offset(); @@ -7485,7 +7530,7 @@ void emitter::emitIns_R_R_A_I(instruction ins, void emitter::emitIns_R_R_AR_I( instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber base, int offs, int ival) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); instrDesc* id = emitNewInstrAmdCns(attr, offs, ival); @@ -7514,7 +7559,7 @@ void emitter::emitIns_R_R_C_I(instruction ins, int ival, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); // Static always need relocs @@ -7557,7 +7602,7 @@ void emitter::emitIns_R_R_C_I(instruction ins, void emitter::emitIns_R_R_R_I( instruction ins, emitAttr attr, regNumber targetReg, regNumber reg1, regNumber reg2, int ival, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); instrDesc* id = emitNewInstrCns(attr, ival); @@ -7580,7 +7625,7 @@ void emitter::emitIns_R_R_R_I( void emitter::emitIns_R_R_S_I( instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, int varx, int offs, int ival, insOpts instOptions) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(IsThreeOperandAVXInstruction(ins)); instrDesc* id = emitNewInstrCns(attr, ival); @@ -8285,7 +8330,7 @@ void emitter::emitIns_AR_R(instruction ins, emitAttr attr, regNumber reg, regNum void emitter::emitIns_C_R_I( instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fldHnd, int offs, regNumber reg, int ival) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(reg != REG_NA); // Static always need relocs @@ -8322,7 +8367,7 @@ void emitter::emitIns_C_R_I( // void emitter::emitIns_S_R_I(instruction ins, emitAttr attr, int varNum, int offs, regNumber reg, int ival) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(reg != REG_NA); instrDesc* id = emitNewInstrAmdCns(attr, 0, ival); @@ -8355,7 +8400,7 @@ void emitter::emitIns_S_R_I(instruction ins, emitAttr attr, int varNum, int offs // void emitter::emitIns_A_R_I(instruction ins, emitAttr attr, GenTreeIndir* indir, regNumber reg, int imm) { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); assert(reg != REG_NA); instrDesc* id = emitNewInstrAmdCns(attr, indir->Offset(), imm); @@ -13289,7 +13334,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // SSE/AVX do not need to modify opcode if ((signed char)cval == cval && addc->cnsReloc == false && ins != INS_mov && ins != INS_test) { - if (id->idInsFmt() != IF_ARW_SHF && !IsAvx512OrPriorInstruction(ins)) + if (id->idInsFmt() != IF_ARW_SHF && !IsSimdInstruction(ins)) { code |= 2; } @@ -13672,7 +13717,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) #else dst += emitOutputLong(dst, dsp); #endif - if (!IsAvx512OrPriorInstruction(ins) && id->idIsTlsGD()) + if (!IsSimdInstruction(ins) && id->idIsTlsGD()) { addlDelta = -4; emitRecordRelocationWithAddlDelta((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_TLSGD, @@ -14236,7 +14281,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) if ((signed char)cval == cval && addc->cnsReloc == false && ins != INS_mov && ins != INS_test) { if ((id->idInsFmt() != IF_SRW_SHF) && (id->idInsFmt() != IF_RRW_SRD_CNS) && - (id->idInsFmt() != IF_RWR_RRD_SRD_CNS) && !IsAvx512OrPriorInstruction(ins)) + (id->idInsFmt() != IF_RWR_RRD_SRD_CNS) && !IsSimdInstruction(ins)) { code |= 2; } @@ -14736,7 +14781,7 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) if ((signed char)cval == cval && addc->cnsReloc == false && ins != INS_mov && ins != INS_test) { // SSE/AVX do not need to modify opcode - if (id->idInsFmt() != IF_MRW_SHF && !IsAvx512OrPriorInstruction(ins)) + if (id->idInsFmt() != IF_MRW_SHF && !IsSimdInstruction(ins)) { code |= 2; } @@ -15451,7 +15496,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) assert(!id->idHasReg3()); - if (IsAvx512OrPriorInstruction(ins)) + if (IsSimdInstruction(ins)) { assert((ins != INS_movd) || (isFloatReg(reg1) != isFloatReg(reg2))); @@ -15980,7 +16025,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id) noway_assert(emitVerifyEncodable(ins, size, reg)); - if (IsAvx512OrPriorInstruction(ins)) + if (IsSimdInstruction(ins)) { // Handle SSE2 instructions of the form "opcode reg, immed8" @@ -17763,7 +17808,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_RWR_ARD_CNS: case IF_RRW_ARD_CNS: { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); emitGetInsAmdCns(id, &cnsVal); if (hasCodeMI(ins)) @@ -17801,7 +17846,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_AWR_RRD_CNS: case IF_ARW_RRD_CNS: { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); emitGetInsAmdCns(id, &cnsVal); dst = emitOutputAM(dst, id, insCodeMR(ins), &cnsVal); sz = emitSizeOfInsDsc_AMD(id); @@ -17848,7 +17893,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_RWR_RRD_ARD_CNS: case IF_RWR_RRD_ARD_RRD: { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); code = insCodeRM(ins); emitGetInsAmdCns(id, &cnsVal); @@ -17994,7 +18039,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_SWR_RRD_CNS: case IF_SRW_RRD_CNS: { - assert(IsAvx512OrPriorInstruction(ins) || (ins == INS_shld) || (ins == INS_shrd)); + assert(IsSimdInstruction(ins) || (ins == INS_shld) || (ins == INS_shrd)); emitGetInsAmdCns(id, &cnsVal); dst = emitOutputSV(dst, id, insCodeMR(ins), &cnsVal); sz = emitSizeOfInsDsc_CNS(id); @@ -18005,7 +18050,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_RWR_SRD_CNS: case IF_RRW_SRD_CNS: { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); emitGetInsCns(id, &cnsVal); if (hasCodeMI(ins)) @@ -18234,7 +18279,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_RWR_MRD_CNS: case IF_RRW_MRD_CNS: { - assert(IsAvx512OrPriorInstruction(ins)); + assert(IsSimdInstruction(ins)); emitGetInsDcmCns(id, &cnsVal); if (hasCodeMI(ins)) @@ -19478,6 +19523,8 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_vmovdqu8: case INS_vmovdqu16: case INS_vmovdqu64: + case INS_vmovd: + case INS_vmovw: case INS_movaps: case INS_movups: case INS_movapd: @@ -19619,6 +19666,10 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_vrangeps: case INS_vrangesd: case INS_vrangess: + case INS_vminmaxsd: + case INS_vminmaxss: + case INS_vminmaxpd: + case INS_vminmaxps: case INS_vreducepd: case INS_vreduceps: case INS_vreducesd: @@ -19633,6 +19684,17 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins break; } + // TODO-XArch-AVX10.2: handle perf for AVX10.2 instructions + case INS_vcomxsd: + case INS_vcomxss: + case INS_vucomxsd: + case INS_vucomxss: + { + result.insThroughput = PERFSCORE_THROUGHPUT_2X; + result.insLatency += PERFSCORE_LATENCY_4C; + break; + } + case INS_vpermi2b: case INS_vpermt2b: { @@ -19808,8 +19870,24 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_vcvtusi2ss32: case INS_vcvtusi2ss64: case INS_vcvttsd2usi32: + case INS_vcvttsd2usis32: case INS_vcvttsd2usi64: + case INS_vcvttsd2usis64: case INS_vcvttss2usi32: + case INS_vcvttss2usis32: + case INS_vcvttsd2sis32: + case INS_vcvttsd2sis64: + case INS_vcvttss2sis32: + case INS_vcvttss2sis64: + case INS_vcvttss2usis64: + case INS_vcvttps2dqs: + case INS_vcvttps2udqs: + case INS_vcvttpd2qqs: + case INS_vcvttpd2uqqs: + case INS_vcvttps2ibs: + case INS_vcvttps2iubs: + case INS_vcvtps2ibs: + case INS_vcvtps2iubs: result.insThroughput = PERFSCORE_THROUGHPUT_1C; result.insLatency += PERFSCORE_LATENCY_7C; break; @@ -20246,6 +20324,7 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins } case INS_mpsadbw: + case INS_vmpsadbw: result.insThroughput = PERFSCORE_THROUGHPUT_2C; result.insLatency += PERFSCORE_LATENCY_4C; break; @@ -20259,9 +20338,21 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_pmaddwd: case INS_pmaddubsw: case INS_vpdpbusd: - case INS_vpdpwssd: case INS_vpdpbusds: + case INS_vpdpbssd: + case INS_vpdpbssds: + case INS_vpdpbsud: + case INS_vpdpbsuds: + case INS_vpdpbuud: + case INS_vpdpbuuds: case INS_vpdpwssds: + case INS_vpdpwssd: + case INS_vpdpwsud: + case INS_vpdpwsuds: + case INS_vpdpwusd: + case INS_vpdpwusds: + case INS_vpdpwuud: + case INS_vpdpwuuds: case INS_gf2p8affineinvqb: case INS_gf2p8affineqb: case INS_gf2p8mulb: diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index ee75f8b13cd774..1761d79f8eca7f 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -1323,7 +1323,8 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* inlineRe // (This could happen for example for a BBJ_THROW block fall through a BBJ_RETURN block which // causes the BBJ_RETURN block not to be imported at all.) // Fail the inlining attempt - if ((inlineCandidateInfo->fncRetType != TYP_VOID) && (inlineCandidateInfo->retExpr->gtSubstExpr == nullptr)) + if ((inlineCandidateInfo->methInfo.args.retType != CORINFO_TYPE_VOID) && + (inlineCandidateInfo->retExpr->gtSubstExpr == nullptr)) { #ifdef DEBUG if (verbose) @@ -1514,7 +1515,7 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo) noway_assert(!block->hasTryIndex()); noway_assert(!block->hasHndIndex()); block->copyEHRegion(iciBlock); - block->CopyFlags(iciBlock, BBF_BACKWARD_JUMP); + block->CopyFlags(iciBlock, BBF_BACKWARD_JUMP | BBF_PROF_WEIGHT); // Update block nums appropriately // diff --git a/src/coreclr/jit/fgprofile.cpp b/src/coreclr/jit/fgprofile.cpp index 9cf332bf16c995..2a21e61f0d3a09 100644 --- a/src/coreclr/jit/fgprofile.cpp +++ b/src/coreclr/jit/fgprofile.cpp @@ -4571,6 +4571,12 @@ void Compiler::fgDebugCheckProfile(PhaseChecks checks) else if (hasFlag(checks, PhaseChecks::CHECK_PROFILE)) { ProfileChecks profileChecks = ProfileChecks::CHECK_LIKELY | ProfileChecks::RAISE_ASSERT; + + if (hasFlag(checks, PhaseChecks::CHECK_PROFILE_FLAGS)) + { + profileChecks |= ProfileChecks::CHECK_FLAGS; + } + fgDebugCheckProfileWeights(profileChecks); } else if (hasFlag(checks, PhaseChecks::CHECK_LIKELIHOODS)) @@ -4611,6 +4617,7 @@ bool Compiler::fgDebugCheckProfileWeights(ProfileChecks checks) const bool verifyLikelyWeights = hasFlag(checks, ProfileChecks::CHECK_LIKELY); const bool verifyHasLikelihood = hasFlag(checks, ProfileChecks::CHECK_HASLIKELIHOOD); const bool verifyLikelihoodSum = hasFlag(checks, ProfileChecks::CHECK_LIKELIHOODSUM); + const bool checkProfileFlag = hasFlag(checks, ProfileChecks::CHECK_FLAGS) && fgIsUsingProfileWeights(); const bool assertOnFailure = hasFlag(checks, ProfileChecks::RAISE_ASSERT) && fgPgoConsistent; const bool checkAllBlocks = hasFlag(checks, ProfileChecks::CHECK_ALL_BLOCKS); @@ -4633,6 +4640,7 @@ bool Compiler::fgDebugCheckProfileWeights(ProfileChecks checks) unsigned problemBlocks = 0; unsigned unprofiledBlocks = 0; unsigned profiledBlocks = 0; + unsigned unflaggedBlocks = 0; bool entryProfiled = false; bool exitProfiled = false; bool hasTry = false; @@ -4643,10 +4651,20 @@ bool Compiler::fgDebugCheckProfileWeights(ProfileChecks checks) // for (BasicBlock* const block : Blocks()) { - if (!block->hasProfileWeight() && !checkAllBlocks) + if (!block->hasProfileWeight()) { - unprofiledBlocks++; - continue; + if (checkProfileFlag && (block->bbPreds != nullptr)) + { + // Block has flow into it that isn't marked as profile-derived. + // + unflaggedBlocks++; + } + + if (!checkAllBlocks) + { + unprofiledBlocks++; + continue; + } } // There is some profile data to check. @@ -4831,6 +4849,12 @@ bool Compiler::fgDebugCheckProfileWeights(ProfileChecks checks) } } + if (unflaggedBlocks > 0) + { + JITDUMP("%d blocks are missing BBF_PROF_WEIGHT flag.\n", unflaggedBlocks); + assert(!"Missing BBF_PROF_WEIGHT flag"); + } + return (problemBlocks == 0); } diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 94293bdf4e6217..06854fa563b59c 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -20020,7 +20020,7 @@ bool GenTree::SupportsSettingZeroFlag() } #endif #elif defined(TARGET_ARM64) - if (OperIs(GT_AND)) + if (OperIs(GT_AND, GT_AND_NOT)) { return true; } @@ -27789,6 +27789,21 @@ bool GenTreeHWIntrinsic::OperIsEmbRoundingEnabled() const case NI_AVX10v1_MultiplyScalar: case NI_AVX10v1_SubtractScalar: case NI_AVX10v1_SqrtScalar: + case NI_AVX10v2_Add: + case NI_AVX10v2_ConvertToVector128Int32: + case NI_AVX10v2_ConvertToVector128Single: + case NI_AVX10v2_ConvertToVector128UInt32: + case NI_AVX10v2_ConvertToVector256Double: + case NI_AVX10v2_ConvertToVector256Int32: + case NI_AVX10v2_ConvertToVector256Int64: + case NI_AVX10v2_ConvertToVector256Single: + case NI_AVX10v2_ConvertToVector256UInt32: + case NI_AVX10v2_ConvertToVector256UInt64: + case NI_AVX10v2_Divide: + case NI_AVX10v2_Multiply: + case NI_AVX10v2_Scale: + case NI_AVX10v2_Sqrt: + case NI_AVX10v2_Subtract: { return true; } @@ -27857,6 +27872,10 @@ bool GenTreeHWIntrinsic::OperIsEmbRoundingEnabled() const case NI_AVX10v1_V512_ConvertToVector512Double: case NI_AVX10v1_V512_ConvertToVector512Int64: case NI_AVX10v1_V512_ConvertToVector512UInt64: + case NI_AVX10v2_ConvertToSByteWithSaturationAndZeroExtendToInt32: + case NI_AVX10v2_ConvertToByteWithSaturationAndZeroExtendToInt32: + case NI_AVX10v2_V512_ConvertToSByteWithSaturationAndZeroExtendToInt32: + case NI_AVX10v2_V512_ConvertToByteWithSaturationAndZeroExtendToInt32: { return numArgs == 2; } @@ -28232,6 +28251,7 @@ genTreeOps GenTreeHWIntrinsic::GetOperForHWIntrinsicId(NamedIntrinsic id, var_ty case NI_AVX_Add: case NI_AVX2_Add: case NI_AVX512F_Add: + case NI_AVX10v2_Add: case NI_AVX512BW_Add: #elif defined(TARGET_ARM64) case NI_AdvSimd_Add: @@ -28268,6 +28288,7 @@ genTreeOps GenTreeHWIntrinsic::GetOperForHWIntrinsicId(NamedIntrinsic id, var_ty case NI_SSE2_Divide: case NI_AVX_Divide: case NI_AVX512F_Divide: + case NI_AVX10v2_Divide: #elif defined(TARGET_ARM64) case NI_AdvSimd_Arm64_Divide: #endif @@ -28320,6 +28341,7 @@ genTreeOps GenTreeHWIntrinsic::GetOperForHWIntrinsicId(NamedIntrinsic id, var_ty #if defined(TARGET_XARCH) case NI_SSE2_Multiply: case NI_AVX512F_Multiply: + case NI_AVX10v2_Multiply: { if (varTypeIsFloating(simdBaseType)) { @@ -28485,6 +28507,7 @@ genTreeOps GenTreeHWIntrinsic::GetOperForHWIntrinsicId(NamedIntrinsic id, var_ty case NI_AVX2_Subtract: case NI_AVX512F_Subtract: case NI_AVX512BW_Subtract: + case NI_AVX10v2_Subtract: #elif defined(TARGET_ARM64) case NI_AdvSimd_Subtract: case NI_AdvSimd_Arm64_Subtract: diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 553888bb996aa6..a00d57962d757b 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -807,8 +807,8 @@ static const HWIntrinsicIsaRange hwintrinsicIsaRangeArray[] = { { NI_Illegal, NI_Illegal }, // VectorT256 { NI_Illegal, NI_Illegal }, // VectorT512 { NI_Illegal, NI_Illegal }, // APX - { NI_Illegal, NI_Illegal }, // AVX10v2 - { NI_Illegal, NI_Illegal }, // AVX10v2_V512 + { FIRST_NI_AVX10v2, LAST_NI_AVX10v2 }, // AVX10v2 + { FIRST_NI_AVX10v2_V512, LAST_NI_AVX10v2_V512 }, // AVX10v2_V512 { FIRST_NI_GFNI, LAST_NI_GFNI }, { FIRST_NI_GFNI_V256, LAST_NI_GFNI_V256 }, { FIRST_NI_GFNI_V512, LAST_NI_GFNI_V512 }, diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index b76781500c56fa..8a629436d25947 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -1432,6 +1432,56 @@ HARDWARE_INTRINSIC(AVX10v1_X64, ConvertToUInt64, HARDWARE_INTRINSIC(AVX10v1_X64, ConvertToUInt64WithTruncation, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttss2usi64, INS_vcvttsd2usi64}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) #define LAST_NI_AVX10v1_X64 NI_AVX10v1_X64_ConvertToUInt64WithTruncation +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// AVX10v2 Intrinsics +#define FIRST_NI_AVX10v2 NI_AVX10v2_Add +HARDWARE_INTRINSIC(AVX10v2, Add, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_addps, INS_addpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative |HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToByteWithSaturationAndZeroExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2iubs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2iubs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToSByteWithSaturationAndZeroExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2ibs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2ibs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector128Int32, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtpd2dq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector128Single, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtqq2ps, INS_vcvtuqq2ps, INS_invalid, INS_cvtpd2ps}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector128UInt32, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtpd2udq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector256Double, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtqq2pd, INS_vcvtuqq2pd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector256Int32, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtps2dq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector256Int64, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2qq, INS_vcvtpd2qq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector256Single, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtdq2ps, INS_vcvtudq2ps, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector256UInt32, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2udq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVector256UInt64, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2uqq, INS_vcvtpd2uqq}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVectorInt32WithTruncationSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2dqs, INS_vcvttpd2dqs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVectorInt64WithTruncationSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2qqs, INS_vcvttpd2qqs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVectorUInt32WithTruncationSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2udqs, INS_vcvttpd2udqs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2, ConvertToVectorUInt64WithTruncationSaturation, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2uqqs, INS_vcvttpd2uqqs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2, Divide, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_divps, INS_divpd}, HW_Category_SimpleSIMD, HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, MinMax, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vminmaxps, INS_vminmaxpd}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2, MinMaxScalar, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vminmaxss, INS_vminmaxsd}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2, Multiply, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mulps, INS_mulpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative |HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, Scale, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vscalefps, INS_vscalefpd}, HW_Category_SimpleSIMD, HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, Sqrt, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqrtps, INS_sqrtpd}, HW_Category_SimpleSIMD, HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2, Subtract, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_subps, INS_subpd}, HW_Category_SimpleSIMD, HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +#define LAST_NI_AVX10v2 NI_AVX10v2_Subtract + +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// AVX10v2_V512 Intrinsics +#define FIRST_NI_AVX10v2_V512 NI_AVX10v2_V512_ConvertToByteWithSaturationAndZeroExtendToInt32 +HARDWARE_INTRINSIC(AVX10v2_V512, ConvertToByteWithSaturationAndZeroExtendToInt32, 64, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2iubs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2iubs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, ConvertToSByteWithSaturationAndZeroExtendToInt32, 64, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2ibs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible|HW_Flag_EmbRoundingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2ibs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, ConvertToVectorInt32WithTruncationSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2dqs, INS_vcvttpd2dqs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, ConvertToVectorInt64WithTruncationSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2qqs, INS_vcvttpd2qqs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, ConvertToVectorUInt32WithTruncationSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2udqs, INS_vcvttpd2udqs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, ConvertToVectorUInt64WithTruncationSaturation, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2uqqs, INS_vcvttpd2uqqs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, MinMax, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vminmaxps, INS_vminmaxpd}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbBroadcastCompatible|HW_Flag_EmbMaskingCompatible) +HARDWARE_INTRINSIC(AVX10v2_V512, MultipleSumAbsoluteDifferences, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_vmpsadbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_EmbMaskingCompatible) +#define LAST_NI_AVX10v2_V512 NI_AVX10v2_V512_MultipleSumAbsoluteDifferences // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index b8c8d43f787e0b..cc53c87ba7f712 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -50,6 +50,10 @@ static CORINFO_InstructionSet X64VersionOfIsa(CORINFO_InstructionSet isa) return InstructionSet_AVX10v1_X64; case InstructionSet_AVX10v1_V512: return InstructionSet_AVX10v1_V512_X64; + case InstructionSet_AVX10v2: + return InstructionSet_AVX10v2_X64; + case InstructionSet_AVX10v2_V512: + return InstructionSet_AVX10v2_V512_X64; case InstructionSet_AVXVNNI: return InstructionSet_AVXVNNI_X64; case InstructionSet_AES: @@ -139,6 +143,10 @@ static CORINFO_InstructionSet V512VersionOfIsa(CORINFO_InstructionSet isa) return InstructionSet_AVX10v1_V512; case InstructionSet_AVX10v1_X64: return InstructionSet_AVX10v1_V512_X64; + case InstructionSet_AVX10v2: + return InstructionSet_AVX10v2_V512; + case InstructionSet_AVX10v2_X64: + return InstructionSet_AVX10v2_V512_X64; case InstructionSet_GFNI: return InstructionSet_GFNI_V512; case InstructionSet_PCLMULQDQ: @@ -172,9 +180,16 @@ static CORINFO_InstructionSet lookupInstructionSet(const char* className) { return InstructionSet_AVX; } - else if (strcmp(className + 3, "10v1") == 0) + else if (strncmp(className + 3, "10v", 3) == 0) { - return InstructionSet_AVX10v1; + if (strcmp(className + 6, "1") == 0) + { + return InstructionSet_AVX10v1; + } + else if (strcmp(className + 6, "2") == 0) + { + return InstructionSet_AVX10v2; + } } else if (strcmp(className + 3, "2") == 0) { @@ -412,6 +427,9 @@ int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic id) case NI_AVX_CompareScalar: case NI_AVX512F_Compare: case NI_EVEX_CompareMask: + case NI_AVX10v2_MinMaxScalar: + case NI_AVX10v2_MinMax: + case NI_AVX10v2_V512_MinMax: { assert(!HWIntrinsicInfo::HasFullRangeImm(id)); return 31; // enum FloatComparisonMode has 32 values @@ -910,6 +928,10 @@ bool HWIntrinsicInfo::isFullyImplementedIsa(CORINFO_InstructionSet isa) case InstructionSet_AVX10v1_X64: case InstructionSet_AVX10v1_V512: case InstructionSet_AVX10v1_V512_X64: + case InstructionSet_AVX10v2: + case InstructionSet_AVX10v2_X64: + case InstructionSet_AVX10v2_V512: + case InstructionSet_AVX10v2_V512_X64: case InstructionSet_EVEX: case InstructionSet_GFNI: case InstructionSet_GFNI_X64: @@ -3341,7 +3363,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { // Emulate NI_AVX512DQ_VL_MultiplyLow with SSE41 for SIMD16 } - else + else if (simdSize != 64) { // Software fallback break; @@ -3399,7 +3421,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { // Emulate NI_AVX512DQ_VL_MultiplyLow with SSE41 for SIMD16 } - else + else if (simdSize != 64) { // Software fallback break; diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 5bd6e842daa119..0435ecf0b514e4 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9548,6 +9548,21 @@ void Compiler::impImportBlockCode(BasicBlock* block) { indirFlags |= GTF_IND_TGT_HEAP; } + else if ((lclTyp == TYP_STRUCT) && (fieldInfo.structType != NO_CLASS_HANDLE) && + eeIsByrefLike(fieldInfo.structType)) + { + // Field's type is a byref-like struct -> address is not on the heap. + indirFlags |= GTF_IND_TGT_NOT_HEAP; + } + else + { + // Field's owner is a byref-like struct -> address is not on the heap. + CORINFO_CLASS_HANDLE fldOwner = info.compCompHnd->getFieldClass(resolvedToken.hField); + if ((fldOwner != NO_CLASS_HANDLE) && eeIsByrefLike(fldOwner)) + { + indirFlags |= GTF_IND_TGT_NOT_HEAP; + } + } assert(varTypeIsI(op1)); op1 = (lclTyp == TYP_STRUCT) ? gtNewStoreBlkNode(layout, op1, op2, indirFlags)->AsIndir() @@ -10981,7 +10996,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) // Make sure the type matches the original call. var_types returnType = genActualType(op2->gtType); - var_types originalCallType = inlCandInfo->fncRetType; + var_types originalCallType = genActualType(JITtype2varType(inlCandInfo->methInfo.args.retType)); if ((returnType != originalCallType) && (originalCallType == TYP_STRUCT)) { originalCallType = impNormStructType(inlCandInfo->methInfo.args.retTypeClass); diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 6d737b4f59d10f..a90a23c405cc2d 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -1030,7 +1030,7 @@ var_types Compiler::impImportCall(OPCODE opcode, INDEBUG(call->AsCall()->gtRawILOffset = rawILOffset); // Is it an inline candidate? - impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, rawILOffset); + impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo); } // append the call node. @@ -1240,7 +1240,7 @@ var_types Compiler::impImportCall(OPCODE opcode, INDEBUG(call->AsCall()->gtRawILOffset = rawILOffset); // Is it an inline candidate? - impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, rawILOffset); + impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo); } // Extra checks for tail calls and tail recursion. @@ -7450,7 +7450,6 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call, // exactContextHnd -- context handle for inlining // exactContextNeedsRuntimeLookup -- true if context required runtime lookup // callInfo -- call info from VM -// ilOffset -- the actual IL offset of the instruction that produced this inline candidate // // Notes: // Mostly a wrapper for impMarkInlineCandidateHelper that also undoes @@ -7460,8 +7459,7 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call, void Compiler::impMarkInlineCandidate(GenTree* callNode, CORINFO_CONTEXT_HANDLE exactContextHnd, bool exactContextNeedsRuntimeLookup, - CORINFO_CALL_INFO* callInfo, - IL_OFFSET ilOffset) + CORINFO_CALL_INFO* callInfo) { if (!opts.OptEnabled(CLFLG_INLINING)) { @@ -7484,7 +7482,7 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode, // Do the actual evaluation impMarkInlineCandidateHelper(call, candidateId, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, - ilOffset, &inlineResult); + &inlineResult); // Ignore non-inlineable candidates // TODO: Consider keeping them to just devirtualize without inlining, at least for interface // calls on NativeAOT, but that requires more changes elsewhere too. @@ -7507,8 +7505,7 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode, const uint8_t candidatesCount = call->GetInlineCandidatesCount(); assert(candidatesCount <= 1); InlineResult inlineResult(this, call, nullptr, "impMarkInlineCandidate"); - impMarkInlineCandidateHelper(call, 0, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, ilOffset, - &inlineResult); + impMarkInlineCandidateHelper(call, 0, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo, &inlineResult); } // If this call is an inline candidate or is not a guarded devirtualization @@ -7541,7 +7538,6 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode, // exactContextHnd -- context handle for inlining // exactContextNeedsRuntimeLookup -- true if context required runtime lookup // callInfo -- call info from VM -// ilOffset -- IL offset of instruction creating the inline candidate // // Notes: // If callNode is an inline candidate, this method sets the flag @@ -7558,7 +7554,6 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, CORINFO_CONTEXT_HANDLE exactContextHnd, bool exactContextNeedsRuntimeLookup, CORINFO_CALL_INFO* callInfo, - IL_OFFSET ilOffset, InlineResult* inlineResult) { // Let the strategy know there's another call @@ -7696,21 +7691,20 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, if (!(methAttr & CORINFO_FLG_FORCEINLINE)) { /* Don't bother inline blocks that are in the filter region */ - if (bbInCatchHandlerILRange(compCurBB)) + if (bbInCatchHandlerBBRange(compCurBB)) { #ifdef DEBUG if (verbose) { printf("\nWill not inline blocks that are in the catch handler region\n"); } - #endif inlineResult->NoteFatal(InlineObservation::CALLSITE_IS_WITHIN_CATCH); return; } - if (bbInFilterILRange(compCurBB)) + if (bbInFilterBBRange(compCurBB)) { #ifdef DEBUG if (verbose) @@ -7767,7 +7761,6 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, // The new value should not be null. assert(inlineCandidateInfo != nullptr); inlineCandidateInfo->exactContextNeedsRuntimeLookup = exactContextNeedsRuntimeLookup; - inlineCandidateInfo->ilOffset = ilOffset; // If we're in an inlinee compiler, and have a return spill temp, and this inline candidate // is also a tail call candidate, it can use the same return spill temp. @@ -9201,12 +9194,11 @@ void Compiler::impCheckCanInline(GenTreeCall* call, CORINFO_CLASS_HANDLE clsHandle = compCompHnd->getMethodClass(ftn); unsigned const clsAttr = compCompHnd->getClassAttribs(clsHandle); +#ifdef DEBUG // Return type // - var_types const fncRetType = pParam->call->TypeGet(); - -#ifdef DEBUG - var_types fncRealRetType = JITtype2varType(methInfo.args.retType); + var_types const fncRetType = pParam->call->gtReturnType; + var_types const fncRealRetType = JITtype2varType(methInfo.args.retType); assert((genActualType(fncRealRetType) == genActualType(fncRetType)) || // VSW 288602 @@ -9250,7 +9242,6 @@ void Compiler::impCheckCanInline(GenTreeCall* call, pInfo->clsAttr = clsAttr; pInfo->methAttr = pParam->methAttr; pInfo->initClassResult = initClassResult; - pInfo->fncRetType = fncRetType; pInfo->exactContextNeedsRuntimeLookup = false; pInfo->inlinersContext = pParam->pThis->compInlineContext; diff --git a/src/coreclr/jit/inline.h b/src/coreclr/jit/inline.h index ce50b2cc93dba8..426e6575973d4c 100644 --- a/src/coreclr/jit/inline.h +++ b/src/coreclr/jit/inline.h @@ -622,10 +622,7 @@ struct InlineCandidateInfo : public HandleHistogramProfileCandidateInfo unsigned clsAttr; unsigned methAttr; - // actual IL offset of instruction that resulted in this inline candidate - IL_OFFSET ilOffset; CorInfoInitClassResult initClassResult; - var_types fncRetType; bool exactContextNeedsRuntimeLookup; InlineContext* inlinersContext; }; diff --git a/src/coreclr/jit/instr.h b/src/coreclr/jit/instr.h index 5ec40ea333973c..4f00ca62627966 100644 --- a/src/coreclr/jit/instr.h +++ b/src/coreclr/jit/instr.h @@ -85,7 +85,7 @@ enum instruction : uint32_t }; //------------------------------------------------------------------------ -// IsAvx512OrPriorInstruction: Is this an Avx512 or Avx or Sse or K (opmask) instruction. +// IsSimdInstruction: Is this an Avx512 or Avx or Sse or K (opmask) instruction. // Technically, K instructions would be considered under the VEX encoding umbrella, but due to // the instruction table encoding had to be pulled out with the rest of the `INST5` definitions. // @@ -95,10 +95,10 @@ enum instruction : uint32_t // Returns: // `true` if it is a sse or avx or avx512 instruction. // -inline bool IsAvx512OrPriorInstruction(instruction ins) +inline bool IsSimdInstruction(instruction ins) { #if defined(TARGET_XARCH) - return (ins >= INS_FIRST_SSE_INSTRUCTION) && (ins <= INS_LAST_AVX512_INSTRUCTION); + return (ins >= INS_FIRST_SSE_INSTRUCTION) && (ins <= INS_LAST_AVX10v2_INSTRUCTION); #else return false; #endif // TARGET_XARCH diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index 3c6285405a0747..24be0ef3527b6a 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -172,6 +172,10 @@ INSTMUL(imul_15, "imul", IUM_RD, BAD_CODE, 0x4400003868, #define PCKDBL(c) PACK3(0x66, 0x0f, c) #define PCKFLT(c) PACK2(0x0f, c) #define PCKMVB(c) PACK3(0x0F, 0x38, c) +#define PCKDBLMAP(m, c) PACK3(0x66, m, c) +#define PCKFLTMAP(m, c) PACK2(m, c) +#define SSEDBLMAP(m, c) PACK3(0xf2, m, c) +#define SSEFLTMAP(m, c) PACK3(0xf3, m, c) // These macros encode extra byte that is implicit in the macro. #define PACK4(byte1,byte2,byte3,byte4) (((byte1) << 16) | ((byte2) << 24) | (byte3) | ((byte4) << 8)) @@ -181,6 +185,7 @@ INSTMUL(imul_15, "imul", IUM_RD, BAD_CODE, 0x4400003868, #define SSE38(c) PSSE38(0x66, c) #define SSE3A(c) PSSE3A(0x66, c) +#define AVX3A(c) PSSE3A(0xf3, c) // VEX* encodes the implied leading opcode bytes in c1: // 1: implied 0f, 2: implied 0f 38, 3: implied 0f 3a @@ -884,6 +889,54 @@ INST3(vpmultishiftqb, "pmultishiftqb", IUM_WR, BAD_CODE, BAD_ INST3(LAST_AVX512_INSTRUCTION, "LAST_AVX512_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_TT_NONE, INS_FLAGS_None) +INST3(FIRST_AVX10v2_INSTRUCTION, "FIRST_AVX10v2_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_TT_NONE, INS_FLAGS_None) +INST3(vcomxsd, "comxsd", IUM_RD, BAD_CODE, BAD_CODE, SSEFLT(0x2f), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | Writes_OF | Writes_SF | Writes_ZF | Writes_PF | Writes_CF | Resets_AF) // Compare double precision floating point values and set flags +INST3(vcomxss, "comxss", IUM_RD, BAD_CODE, BAD_CODE, SSEDBL(0x2f), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | Writes_OF | Writes_SF | Writes_ZF | Writes_PF | Writes_CF | Resets_AF) // Compare single precision floating point values and set flags +INST3(vucomxsd, "ucomxsd", IUM_RD, BAD_CODE, BAD_CODE, SSEFLT(0x2f), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | Writes_OF | Writes_SF | Writes_ZF | Writes_PF | Writes_CF | Resets_AF) // Perform an unordered compare of double precision floating point values and set flags +INST3(vucomxss, "ucomxss", IUM_RD, BAD_CODE, BAD_CODE, SSEDBL(0x2E), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | Writes_OF | Writes_SF | Writes_ZF | Writes_PF | Writes_CF | Resets_AF) // Perform an unordered compare of single precision floating point values and set flags +INST3(vcvttps2dqs, "cvttps2dqs", IUM_WR, BAD_CODE, BAD_CODE, PCKFLTMAP(0x05, 0x6D), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported) // cvt with truncation/saturation packed singles to DWORDs +INST3(vcvttps2udqs, "cvttps2udqs", IUM_WR, BAD_CODE, BAD_CODE, PCKFLTMAP(0x05, 0x6C), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported) // cvt with truncation/saturation packed singles to unsigned DWORDs +INST3(vcvttps2qqs, "cvttps2qqs", IUM_WR, BAD_CODE, BAD_CODE, PCKDBLMAP(0x05, 0x6D), INS_TT_HALF, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported) // cvt with truncation/saturation packed singles to signed QWORDs +INST3(vcvttps2uqqs, "cvttps2uqqs", IUM_WR, BAD_CODE, BAD_CODE, PCKDBLMAP(0x05, 0x6C), INS_TT_HALF, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported) // cvt with truncation/saturation packed singles to unsigned QWORDs +INST3(vcvttpd2dqs, "cvttpd2dqs", IUM_WR, BAD_CODE, BAD_CODE, PCKFLTMAP(0x05, 0x6D), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported) // cvt with truncation/saturation packed doubles to DWORDs +INST3(vcvttpd2udqs, "cvttpd2udqs", IUM_WR, BAD_CODE, BAD_CODE, PCKFLTMAP(0x05, 0x6C), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported) // cvt with truncation/saturation packed doubles to unsigned DWORDs +INST3(vcvttpd2qqs, "cvttpd2qqs", IUM_WR, BAD_CODE, BAD_CODE, PCKDBLMAP(0x05, 0x6D), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported) // cvt with truncation/saturation packed doubles to signed QWORDs +INST3(vcvttpd2uqqs, "cvttpd2uqqs", IUM_WR, BAD_CODE, BAD_CODE, PCKDBLMAP(0x05, 0x6C), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported) // cvt with truncation/saturation packed doubles to signed QWORDs +INST3(vcvttsd2sis32, "cvttsd2sis", IUM_WR, BAD_CODE, BAD_CODE, SSEDBLMAP(0x05, 0x6D), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W0 | Encoding_EVEX) // cvt with truncation/saturation scalar double to signed DWORDs +INST3(vcvttsd2sis64, "cvttsd2sis", IUM_WR, BAD_CODE, BAD_CODE, SSEDBLMAP(0x05, 0x6D), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt with truncation/saturation scalar double to signed DWORDs +INST3(vcvttsd2usis32, "cvttsd2usis", IUM_WR, BAD_CODE, BAD_CODE, SSEDBLMAP(0x05, 0x6C), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W0 | Encoding_EVEX) // cvt with truncation/saturation scalar double to unsigned DWORD +INST3(vcvttsd2usis64, "cvttsd2usis", IUM_WR, BAD_CODE, BAD_CODE, SSEDBLMAP(0x05, 0x6C), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX) // cvt with truncation/saturation scalar double to unsigned QWORD +INST3(vcvttss2sis32, "cvttss2sis", IUM_WR, BAD_CODE, BAD_CODE, SSEFLTMAP(0x05, 0x6D), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt with truncation/saturation scalar single to DWORD +INST3(vcvttss2sis64, "cvttss2sis", IUM_WR, BAD_CODE, BAD_CODE, SSEFLTMAP(0x05, 0x6D), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W1 | Encoding_EVEX) // cvt with truncation/saturation scalar single to DWORD +INST3(vcvttss2usis32, "cvttss2usis", IUM_WR, BAD_CODE, BAD_CODE, SSEFLTMAP(0x05, 0x6C), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt with truncation/saturation scalar single to unsigned DWORD/QWORD +INST3(vcvttss2usis64, "cvttss2usis", IUM_WR, BAD_CODE, BAD_CODE, SSEFLTMAP(0x05, 0x6C), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W1 | Encoding_EVEX) // cvt with truncation/saturation scalar single to unsigned DWORD/QWORD + +INST3(vcvtps2ibs, "cvtps2ibs", IUM_WR, BAD_CODE, BAD_CODE, PCKDBLMAP(0x05, 0x69), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) +INST3(vcvtps2iubs, "cvtps2iubs", IUM_WR, BAD_CODE, BAD_CODE, PCKDBLMAP(0x05, 0x6B), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt with truncation/saturation scalar single to unsigned DWORD/QWORD +INST3(vcvttps2ibs, "cvttps2ibs", IUM_WR, BAD_CODE, BAD_CODE, PCKDBLMAP(0x05, 0x68), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt with truncation/saturation scalar single to unsigned DWORD/QWORD +INST3(vcvttps2iubs, "cvttps2iubs", IUM_WR, BAD_CODE, BAD_CODE, PCKDBLMAP(0x05, 0x6A), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // cvt with truncation/saturation scalar single to unsigned DWORD/QWORD +INST3(vmpsadbw, "mpsadbw", IUM_WR, BAD_CODE, BAD_CODE, AVX3A(0x42), INS_TT_FULL, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Compute Multiple Packed Sums of Absolute Difference + +INST3(vminmaxsd, "minmaxsd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x53), INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Return Minimum/Maximum scalar double +INST3(vminmaxss, "minmaxss", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x53), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Return Minimum/Maximum scalar single +INST3(vminmaxpd, "minmaxpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x52), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Return Maximum packed doubles +INST3(vminmaxps, "minmaxps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x52), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Return Maximum packed singles +INST3(vmovd, "movd", IUM_WR, PCKDBL(0xD6), BAD_CODE, SSEFLT(0x7E), INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_EVEX) // Move DWORD between xmm regs <-> memory/xmm regs +INST3(vmovw, "movw", IUM_WR, SSEFLTMAP(0x05, 0x7E), BAD_CODE, SSEFLTMAP(0x05, 0x6E), INS_TT_TUPLE1_SCALAR, Input_16Bit | REX_W0 | Encoding_EVEX) // Move WORD between xmm regs <-> memory/xmm regs +INST3(vpdpwsud, "pdpwsud", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xf3, 0xD2), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual words of first source operand with individual words of second source operand and add the results +INST3(vpdpwsuds, "pdpwsuds", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xf3, 0xD3), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual words of first source operand with individual words of second source operand and add the results +INST3(vpdpwusd, "pdpwusd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xD2), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual words of first source operand with individual words of second source operand and add the results +INST3(vpdpwusds, "pdpwusds", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xD3), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual words of first source operand with individual words of second source operand and add the results +INST3(vpdpwuud, "pdpwuud", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0x00, 0xD2), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual words of first source operand with individual words of second source operand and add the results +INST3(vpdpwuuds, "pdpwuuds", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0x00, 0xD3), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual words of first source operand with individual words of second source operand and add the results +INST3(vpdpbssd, "pdpbssd", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xf2, 0x50), INS_TT_FULL, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual bytes of first source operand with individual bytes of second source operand and add the results +INST3(vpdpbssds, "pdpbssds", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xf2, 0x51), INS_TT_FULL, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual bytes of first source operand with individual bytes of second source operand and add the results +INST3(vpdpbsud, "pdpbsud", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xf3, 0x50), INS_TT_FULL, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual bytes of first source operand with individual bytes of second source operand and add the results +INST3(vpdpbsuds, "pdpbsuds", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xf3, 0x51), INS_TT_FULL, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual bytes of first source operand with individual bytes of second source operand and add the results +INST3(vpdpbuud, "pdpbuud", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0x00, 0x50), INS_TT_FULL, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual bytes of first source operand with individual bytes of second source operand and add the results +INST3(vpdpbuuds, "pdpbuuds", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0x00, 0x51), INS_TT_FULL, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_EmbeddedBroadcastSupported | INS_Flags_IsDstSrcSrcAVXInstruction) // Multiply individual bytes of first source operand with individual bytes of second source operand and add the results +INST3(LAST_AVX10v2_INSTRUCTION, "LAST_AVX10v2_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_TT_NONE, INS_FLAGS_None) + // Scalar instructions in SSE4.2 INST3(crc32, "crc32", IUM_RW, BAD_CODE, BAD_CODE, PSSE38(0xF2, 0xF0), INS_TT_NONE, INS_FLAGS_None) diff --git a/src/coreclr/jit/jiteh.cpp b/src/coreclr/jit/jiteh.cpp index 703c615fcd6339..60c830aad8d592 100644 --- a/src/coreclr/jit/jiteh.cpp +++ b/src/coreclr/jit/jiteh.cpp @@ -354,6 +354,28 @@ bool Compiler::bbInFilterILRange(BasicBlock* blk) return HBtab->InFilterRegionILRange(blk); } +//------------------------------------------------------------------------ +// bbInCatchHandlerBBRange: +// Check if this block is part of a catch handler. +// +// Arguments: +// blk - The block +// +// Return Value: +// True if the block is part of a catch handler clause. Otherwise false. +// +bool Compiler::bbInCatchHandlerBBRange(BasicBlock* blk) +{ + EHblkDsc* HBtab = ehGetBlockHndDsc(blk); + + if (HBtab == nullptr) + { + return false; + } + + return HBtab->HasCatchHandler() && HBtab->InHndRegionBBRange(blk); +} + //------------------------------------------------------------------------ // bbInFilterBBRange: // Check if this block is part of a filter. diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index cc02a343cf67ed..471ec849686e92 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -304,6 +304,11 @@ bool Lowering::IsContainableUnaryOrBinaryOp(GenTree* parentNode, GenTree* childN } } + if (childNode->OperIs(GT_LSH, GT_RSH, GT_RSZ) && parentNode->OperIs(GT_AND_NOT)) + { + return true; + } + // TODO: Handle CMN, NEG/NEGS, BIC/BICS, EON, MVN, ORN, TST return false; } diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 8b38842d8e9fc0..2b0300ccd85d7c 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -9602,10 +9602,6 @@ void Lowering::TryFoldCnsVecForEmbeddedBroadcast(GenTreeHWIntrinsic* parentNode, { assert(!childNode->IsAllBitsSet()); assert(!childNode->IsZero()); - var_types simdType = parentNode->TypeGet(); - var_types simdBaseType = parentNode->GetSimdBaseType(); - CorInfoType simdBaseJitType = parentNode->GetSimdBaseJitType(); - bool isCreatedFromScalar = true; if (!comp->canUseEmbeddedBroadcast()) { @@ -9613,10 +9609,16 @@ void Lowering::TryFoldCnsVecForEmbeddedBroadcast(GenTreeHWIntrinsic* parentNode, return; } - if (simdType == TYP_MASK) - { - simdType = Compiler::getSIMDTypeForSize(parentNode->GetSimdSize()); - } + // We use the child node's size for the broadcast node, because the parent may consume more than its own size. + // The containment check has already validated that the child is sufficiently large. + // + // We use the parent node's base type, because we must ensure that the constant repeats correctly for that size, + // regardless of how the constant vector was created. + + var_types simdType = childNode->TypeGet(); + var_types simdBaseType = parentNode->GetSimdBaseType(); + CorInfoType simdBaseJitType = parentNode->GetSimdBaseJitType(); + bool isCreatedFromScalar = true; if (varTypeIsSmall(simdBaseType)) { @@ -10971,6 +10973,10 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AVX10v1_V512_InsertVector128: case NI_AVX10v1_V512_InsertVector256: case NI_AVX10v1_V512_Range: + case NI_AVX10v2_MinMaxScalar: + case NI_AVX10v2_MinMax: + case NI_AVX10v2_V512_MinMax: + case NI_AVX10v2_V512_MultipleSumAbsoluteDifferences: case NI_GFNI_GaloisFieldAffineTransform: case NI_GFNI_GaloisFieldAffineTransformInverse: case NI_GFNI_V256_GaloisFieldAffineTransform: diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index a7071e4ec4de9c..31785e2e052e49 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7755,14 +7755,23 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA break; case GT_STOREIND: - if (op1->OperIs(GT_FIELD_ADDR) && varTypeIsGC(tree)) + if (varTypeIsGC(tree)) { - CORINFO_FIELD_HANDLE fieldHandle = op1->AsFieldAddr()->gtFldHnd; - if (eeIsByrefLike(info.compCompHnd->getFieldClass(fieldHandle))) + GenTree* addr = op1; + // If we're storing a reference to a field (GT_FIELD_ADDR), let's check if the field's owner is a + // byref-like struct. + while ((addr != nullptr) && addr->OperIs(GT_FIELD_ADDR)) { - JITDUMP("Marking [%06u] STOREIND as GTF_IND_TGT_NOT_HEAP: field's owner is a byref-like struct\n", + CORINFO_FIELD_HANDLE fieldHandle = addr->AsFieldAddr()->gtFldHnd; + if (eeIsByrefLike(info.compCompHnd->getFieldClass(fieldHandle))) + { + JITDUMP( + "Marking [%06u] STOREIND as GTF_IND_TGT_NOT_HEAP: field's owner is a byref-like struct\n", dspTreeID(tree)); - tree->gtFlags |= GTF_IND_TGT_NOT_HEAP; + tree->gtFlags |= GTF_IND_TGT_NOT_HEAP; + break; + } + addr = addr->AsFieldAddr()->GetFldObj(); } } break; diff --git a/src/coreclr/jit/morphblock.cpp b/src/coreclr/jit/morphblock.cpp index 4b81ca7d79eaa3..c5ab836fdc2281 100644 --- a/src/coreclr/jit/morphblock.cpp +++ b/src/coreclr/jit/morphblock.cpp @@ -1363,6 +1363,10 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField() if (m_store->OperIs(GT_STORE_BLK, GT_STOREIND)) { indirFlags = m_store->gtFlags & (GTF_IND_TGT_NOT_HEAP | GTF_IND_TGT_HEAP); + if (m_store->OperIs(GT_STORE_BLK) && m_store->AsBlk()->GetLayout()->IsStackOnly(m_comp)) + { + indirFlags |= GTF_IND_TGT_NOT_HEAP; + } } dstFldStore = m_comp->gtNewStoreIndNode(srcType, fldAddr, srcFld, indirFlags); } diff --git a/src/coreclr/jit/objectalloc.cpp b/src/coreclr/jit/objectalloc.cpp index 8a18a39015c74e..7736f0b9aaf161 100644 --- a/src/coreclr/jit/objectalloc.cpp +++ b/src/coreclr/jit/objectalloc.cpp @@ -392,6 +392,7 @@ bool ObjectAllocator::MorphAllocObjNodes() bool didStackAllocate = false; m_PossiblyStackPointingPointers = BitVecOps::MakeEmpty(&m_bitVecTraits); m_DefinitelyStackPointingPointers = BitVecOps::MakeEmpty(&m_bitVecTraits); + const bool isReadyToRun = comp->opts.IsReadyToRun() && !comp->IsTargetAbi(CORINFO_NATIVEAOT_ABI); for (BasicBlock* const block : comp->Blocks()) { @@ -419,7 +420,7 @@ bool ObjectAllocator::MorphAllocObjNodes() { allocType = OAT_NEWOBJ; } - else if (!comp->opts.IsReadyToRun() && data->IsHelperCall()) + else if (!isReadyToRun && data->IsHelperCall()) { switch (data->AsCall()->GetHelperNum()) { @@ -471,7 +472,7 @@ bool ObjectAllocator::MorphAllocObjNodes() // R2R not yet supported // - assert(!comp->opts.IsReadyToRun()); + assert(!isReadyToRun); //------------------------------------------------------------------------ // We expect the following expression tree at this point diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index c0049564371ebf..f427e3fc068d07 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -40,9 +40,20 @@ DataFlow::DataFlow(Compiler* pCompiler) PhaseStatus Compiler::optSetBlockWeights() { noway_assert(opts.OptimizationEnabled()); + assert(m_dfsTree != nullptr); + const bool usingProfileWeights = fgIsUsingProfileWeights(); + + // Rely on profile synthesis to propagate weights when we have PGO data. + // TODO: Replace optSetBlockWeights with profile synthesis entirely. + if (usingProfileWeights) + { + // Leave breadcrumb for loop alignment + fgHasLoops = m_dfsTree->HasCycle(); + return PhaseStatus::MODIFIED_NOTHING; + } + bool madeChanges = false; - assert(m_dfsTree != nullptr); if (m_domTree == nullptr) { m_domTree = FlowGraphDominatorTree::Build(m_dfsTree); @@ -59,8 +70,7 @@ PhaseStatus Compiler::optSetBlockWeights() optFindAndScaleGeneralLoopBlocks(); } - bool firstBBDominatesAllReturns = true; - const bool usingProfileWeights = fgIsUsingProfileWeights(); + bool firstBBDominatesAllReturns = true; fgComputeReturnBlocks(); diff --git a/src/coreclr/jit/promotiondecomposition.cpp b/src/coreclr/jit/promotiondecomposition.cpp index cde869becbe2b5..b7538acddbf2f3 100644 --- a/src/coreclr/jit/promotiondecomposition.cpp +++ b/src/coreclr/jit/promotiondecomposition.cpp @@ -523,16 +523,21 @@ class DecompositionPlan target_ssize_t addrBaseOffs = 0; FieldSeq* addrBaseOffsFldSeq = nullptr; GenTreeFlags indirFlags = GTF_EMPTY; - + GenTreeFlags flagsToPropagate = GTF_IND_COPYABLE_FLAGS; if (m_store->OperIs(GT_STORE_BLK)) { + flagsToPropagate |= GTF_IND_TGT_NOT_HEAP | GTF_IND_TGT_HEAP; addr = m_store->AsIndir()->Addr(); - indirFlags = m_store->gtFlags & GTF_IND_COPYABLE_FLAGS; + indirFlags = m_store->gtFlags & flagsToPropagate; + if (m_store->AsBlk()->GetLayout()->IsStackOnly(m_compiler)) + { + indirFlags |= GTF_IND_TGT_NOT_HEAP; + } } else if (m_src->OperIs(GT_BLK)) { addr = m_src->AsIndir()->Addr(); - indirFlags = m_src->gtFlags & GTF_IND_COPYABLE_FLAGS; + indirFlags = m_src->gtFlags & flagsToPropagate; } int numAddrUses = 0; diff --git a/src/coreclr/jit/redundantbranchopts.cpp b/src/coreclr/jit/redundantbranchopts.cpp index 7fae5edd0dd07a..3d028bbc764d65 100644 --- a/src/coreclr/jit/redundantbranchopts.cpp +++ b/src/coreclr/jit/redundantbranchopts.cpp @@ -417,8 +417,10 @@ void Compiler::optRelopImpliesRelop(RelopImplicationInfo* rii) const ValueNum relatedVN = vnStore->GetRelatedRelop(rii->domCmpNormVN, vnRelation); if ((relatedVN != ValueNumStore::NoVN) && (relatedVN == rii->treeNormVN)) { - rii->canInfer = true; - rii->vnRelation = vnRelation; + rii->canInfer = true; + rii->vnRelation = vnRelation; + rii->reverseSense = (rii->vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_Reverse) || + (rii->vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_SwapReverse); return; } } @@ -543,21 +545,40 @@ void Compiler::optRelopImpliesRelop(RelopImplicationInfo* rii) // If dom predicate is wrapped in EQ(*,0) then a true dom // predicate implies a false branch outcome, and vice versa. // - // And if the dom predicate is GT_NOT we reverse yet again. - // - rii->reverseSense = (oper == GT_EQ) ^ (predOper == GT_NOT); + rii->reverseSense = (rii->vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_Reverse) || + (rii->vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_SwapReverse); - // We only get partial knowledge in these cases. + // We only get partial knowledge in the AND/OR cases. // // AND(p1,p2) = true ==> both p1 and p2 must be true // AND(p1,p2) = false ==> don't know p1 or p2 // OR(p1,p2) = true ==> don't know p1 or p2 // OR(p1,p2) = false ==> both p1 and p2 must be false // - if (predOper != GT_NOT) + if (predOper == GT_AND) + { + // EQ(AND, 0) false ==> AND true ==> AND operands true + rii->canInferFromFalse = (oper == GT_EQ); + // NE(AND, 0) true ==> AND true ==> AND operands true + rii->canInferFromTrue = (oper == GT_NE); + rii->reverseSense ^= (oper == GT_EQ); + } + else if (predOper == GT_OR) { - rii->canInferFromFalse = rii->reverseSense ^ (predOper == GT_OR); - rii->canInferFromTrue = rii->reverseSense ^ (predOper == GT_AND); + // NE(OR, 0) false ==> OR false ==> OR operands false + rii->canInferFromFalse = (oper == GT_NE); + // EQ(OR, 0) true ==> OR false ==> OR operands false + rii->canInferFromTrue = (oper == GT_EQ); + rii->reverseSense ^= (oper == GT_EQ); + } + else + { + assert(predOper == GT_NOT); + // NE(NOT(x), 0) ==> NOT(X) + // EQ(NOT(x), 0) ==> X + rii->canInferFromTrue = true; + rii->canInferFromFalse = true; + rii->reverseSense ^= (oper == GT_NE); } JITDUMP("Inferring predicate value from %s\n", GenTree::OpName(predOper)); @@ -660,19 +681,21 @@ bool Compiler::optRelopTryInferWithOneEqualOperand(const VNFuncApp& domApp, // BB4: // return; - // Check whether the dominating compare being "false" implies the dominated compare is known + // Check whether the dominating compare being "true" or false" implies the dominated compare is known // to be either "true" or "false". - RelopResult treeOperStatus = IsCmp2ImpliedByCmp1(GenTree::ReverseRelop(domOper), domCns, treeOper, treeCns); - if (treeOperStatus == RelopResult::Unknown) + RelopResult ifTrueStatus = IsCmp2ImpliedByCmp1(domOper, domCns, treeOper, treeCns); + RelopResult ifFalseStatus = IsCmp2ImpliedByCmp1(GenTree::ReverseRelop(domOper), domCns, treeOper, treeCns); + + if ((ifTrueStatus == RelopResult::Unknown) && (ifFalseStatus == RelopResult::Unknown)) { return false; } rii->canInfer = true; rii->vnRelation = ValueNumStore::VN_RELATION_KIND::VRK_Inferred; - rii->canInferFromTrue = false; - rii->canInferFromFalse = true; - rii->reverseSense = treeOperStatus == RelopResult::AlwaysTrue; + rii->canInferFromTrue = (ifTrueStatus != RelopResult::Unknown); + rii->canInferFromFalse = (ifFalseStatus != RelopResult::Unknown); + rii->reverseSense = (ifFalseStatus == RelopResult::AlwaysTrue) || (ifTrueStatus == RelopResult::AlwaysFalse); return true; } @@ -811,10 +834,12 @@ bool Compiler::optRedundantBranch(BasicBlock* const block) // if (domIsInferredRelop) { - // This inference should be one-sided + // We used to assert rii.canInferFromTrue ^ rii.canInferFromFalse here. // - assert(rii.canInferFromTrue ^ rii.canInferFromFalse); - JITDUMP("\nDominator " FMT_BB " of " FMT_BB " has same VN operands but different relop\n", + // But now we can find fully redundant compares with different relops, + // eg LT x, 47 dominating LE x, 46. The second relop's value is equal to the first. + // + JITDUMP("\nDominator " FMT_BB " of " FMT_BB " can infer value of dominated relop\n", domBlock->bbNum, block->bbNum); } else @@ -826,9 +851,6 @@ bool Compiler::optRedundantBranch(BasicBlock* const block) JITDUMP(" Redundant compare; current relop:\n"); DISPTREE(tree); - const bool domIsSameRelop = (rii.vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_Same) || - (rii.vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_Swap); - BasicBlock* const trueSuccessor = domBlock->GetTrueTarget(); BasicBlock* const falseSuccessor = domBlock->GetFalseTarget(); @@ -851,7 +873,7 @@ bool Compiler::optRedundantBranch(BasicBlock* const block) // However we may be able to update the flow from block's predecessors so they // bypass block and instead transfer control to jump's successors (aka jump threading). // - const bool wasThreaded = optJumpThreadDom(block, domBlock, domIsSameRelop); + const bool wasThreaded = optJumpThreadDom(block, domBlock, !rii.reverseSense); if (wasThreaded) { @@ -862,7 +884,7 @@ bool Compiler::optRedundantBranch(BasicBlock* const block) { // True path in dominator reaches, false path doesn't; relop must be true/false. // - const bool relopIsTrue = rii.reverseSense ^ (domIsSameRelop | domIsInferredRelop); + const bool relopIsTrue = !rii.reverseSense; JITDUMP("True successor " FMT_BB " of " FMT_BB " reaches, relop [%06u] must be %s\n", domBlock->GetTrueTarget()->bbNum, domBlock->bbNum, dspTreeID(tree), relopIsTrue ? "true" : "false"); @@ -873,7 +895,7 @@ bool Compiler::optRedundantBranch(BasicBlock* const block) { // False path from dominator reaches, true path doesn't; relop must be false/true. // - const bool relopIsFalse = rii.reverseSense ^ (domIsSameRelop | domIsInferredRelop); + const bool relopIsFalse = !rii.reverseSense; JITDUMP("False successor " FMT_BB " of " FMT_BB " reaches, relop [%06u] must be %s\n", domBlock->GetFalseTarget()->bbNum, domBlock->bbNum, dspTreeID(tree), relopIsFalse ? "false" : "true"); diff --git a/src/coreclr/jit/scev.cpp b/src/coreclr/jit/scev.cpp index a91a8f32ac58ba..94e75dc22a35af 100644 --- a/src/coreclr/jit/scev.cpp +++ b/src/coreclr/jit/scev.cpp @@ -1559,22 +1559,18 @@ RelopEvaluationResult ScalarEvolutionContext::EvaluateRelop(ValueNum vn) continue; } - bool domIsInferredRelop = (rii.vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_Inferred); - bool domIsSameRelop = (rii.vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_Same) || - (rii.vnRelation == ValueNumStore::VN_RELATION_KIND::VRK_Swap); - bool trueReaches = m_comp->optReachable(idom->GetTrueTarget(), m_loop->GetHeader(), idom); bool falseReaches = m_comp->optReachable(idom->GetFalseTarget(), m_loop->GetHeader(), idom); if (trueReaches && !falseReaches && rii.canInferFromTrue) { - bool relopIsTrue = rii.reverseSense ^ (domIsSameRelop | domIsInferredRelop); + bool relopIsTrue = !rii.reverseSense; return relopIsTrue ? RelopEvaluationResult::True : RelopEvaluationResult::False; } if (falseReaches && !trueReaches && rii.canInferFromFalse) { - bool relopIsFalse = rii.reverseSense ^ (domIsSameRelop | domIsInferredRelop); + bool relopIsFalse = !rii.reverseSense; return relopIsFalse ? RelopEvaluationResult::False : RelopEvaluationResult::True; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs index 860a18b73565a2..a64ae72b6cd4e0 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs @@ -381,8 +381,8 @@ private List EnumerateInterruptibleRanges(byte[] image, int uint normRangeStartOffset = normLastinterruptibleRangeStopOffset + normStartDelta; uint normRangeStopOffset = normRangeStartOffset + normStopDelta; - uint rangeStartOffset = _gcInfoTypes.DenormalizeCodeOffset(normRangeStopOffset); - uint rangeStopOffset = _gcInfoTypes.DenormalizeCodeOffset(normRangeStartOffset); + uint rangeStartOffset = _gcInfoTypes.DenormalizeCodeOffset(normRangeStartOffset); + uint rangeStopOffset = _gcInfoTypes.DenormalizeCodeOffset(normRangeStopOffset); ranges.Add(new InterruptibleRange(i, rangeStartOffset, rangeStopOffset)); normLastinterruptibleRangeStopOffset = normRangeStopOffset; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcTransition.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcTransition.cs index 68e4385e1992d9..749f7e48f22e2f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcTransition.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcTransition.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Reflection.PortableExecutable; using System.Text; @@ -16,6 +17,7 @@ public struct InterruptibleRange public InterruptibleRange(uint index, uint start, uint stop) { Index = index; + Debug.Assert(start <= stop); StartOffset = start; StopOffset = stop; } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/TestData.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/TestData.cs index 3c78b73ca5d9e0..20fb1159cd966b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/TestData.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/TestData.cs @@ -2398,53 +2398,54 @@ internal struct ECDsaCngKeyValues "-----END CERTIFICATE REQUEST-----"; internal static byte[] EmptySubjectCertificate = ( - "308202A73082018FA003020102020103300D06092A864886F70D01010B050030" + - "1F311D301B06035504031314456D707479205375626A65637420497373756572" + - "301E170D3138303631353134343030365A170D3333303631353134323030365A" + - "300030820122300D06092A864886F70D01010105000382010F003082010A0282" + - "0101008BFA2727E0D93BEF2A992E912A829FF7A374992F2BD910291BF2BD747D" + - "5CCCF997276ABC2F1CACEAD3F964333F5FF9D7F116A0AC392E711866CCEB0E48" + - "80716367613E4ABD26FCB946E0A2C6AB84ABFD1EF377CD4F6C497D49D9B99CBE" + - "DA878CA4E962307DE110345D2B22CB95A2CC3E0AB94D505CF43FA3B0343B4957" + - "AF361E3604507732150254D77162909887509D5990499C039E5C3871326E09C2" + - "DE132786032B4CD9F460CE35DD0650BE77B0AD9963BC498773CAC858AD15000E" + - "A97793A906D5052A381AA2EE84BF2734833BF12DE932CF67A6D567E627898D96" + - "2FEA2B4F55DE992C205DD67B5B2A59CDD25C04070363D48C8ED854BE013C5D1E" + - "3E57FF0203010001A30D300B30090603551D1304023000300D06092A864886F7" + - "0D01010B0500038201010001BF6D51DA7C45965CB2B6B889E0B1875DFEFDBAC1" + - "558978A53E37BB796E10CBA9AFB698168F55DBD2EC4D26E9FABB7D40D55A2FCA" + - "57F7BBC8509D1B88EB753468F3B57A42718081F00430115A48035CE72CBF9294" + - "2837DF2C2FDC38CE213F2258C5E071A4E18ED70DFC281CD376E84ADC92922416" + - "43389C87098AFAD976F811AA95B48B69DAF7CB31C79953BBFD1C96839561CE12" + - "435F83CEA9F2CB9A94235B0B21FB0D591CDC41676FE927E41CC3A776FAF97146" + - "BF14B08041CB1A90AC7339E7BD1DAF9A600479754F42C88D418B5449F5D34050" + - "4E543013489C47297C83440C3EEF49C9A9D96E398949F03ACB0D5F72E7B4E9D3" + - "895D82CAB526DB74AC5629").HexToByteArray(); + "308202D1308201B9A003020102020A258B80E19011363C8AE6300D06092A8648" + + "86F70D01010B0500301F311D301B06035504031314456D707479205375626A65" + + "637420497373756572301E170D3235303131393030303330375A170D34343031" + + "31393030303330375A300030820122300D06092A864886F70D01010105000382" + + "010F003082010A0282010100D9E161DE2C29CABD97ABC3E0D246C46A061E74E1" + + "D947DCC3D8E0B536185DF3206FCFE24F3CBA7AD351FEE031A3771D95DC6C53A0" + + "3E5D6EEE6A25E2AD9FE1BEA7AF95E6FB9E309B7E954780DC9EDA2EC6E765534F" + + "DCF8FAB09D8C00617E5FDE07A95FB855738513CA4386419D3C61F3BAD16EB92B" + + "9039D42377C12851B4CA8A7A3076A8F000F416EF3DAA69F2EB776BF63FA1FE93" + + "AA83806EC85AB0FF0F0A1EB5598AD904D3A9687C53E05FD21967053428D7A502" + + "18F47E00F770B8ED8C393D876F926BC2B1D1E46F54E48F60E0DB67E33755FA4C" + + "724B081D59128A6D014720654ADC0714D344788BF0DB5A8E2955C90F99326FEE" + + "ABDA354C6F923815F9C586590203010001A32E302C301F0603551D110101FF04" + + "15301382116D6963726F736F66742E6578616D706C6530090603551D13040230" + + "00300D06092A864886F70D01010B050003820101005ABEB15466AC8775278E18" + + "811D00F16FE1E4FDD7A3BFBED0D5578859F258018CD2D84657D1B1C71F8077A5" + + "C3DF29E907E737E8F2129644F98F0FBA47A1C2480DF4DE4767850841412036B0" + + "0AD2B21728DCAF463EBBA803CD0FB9A55F8579A895E339733561319767213EF0" + + "7265BED608FD22ECCDD207E970C0386F21E8A04354B5BD43F7D394C461B9A109" + + "0C8113D86CA437AEC5B1014A06D3A8EB57D2D214EF2E9FA864831803DCEEED8E" + + "01C60EA4E85F7983F55A2C0BED6B3A5BC37EC01584D67CFC53B2C6D54AE963D0" + + "4F99BB8CAB6E2C941BF7F0DAA3AD25AC9F16377295DF744B6281C53954137EC3" + + "1D4B90590E0E0E39CD7B2F574951C4178D9DC5D4C3").HexToByteArray(); internal static byte[] EmptySubjectIssuerCertificate = ( - "308202D4308201BCA003020102020900F68AD256DB542CF9300D06092A864886" + - "F70D01010B0500301F311D301B06035504031314456D707479205375626A6563" + - "7420497373756572301E170D3137303631353134343030365A170D3333303631" + - "353134343030365A301F311D301B06035504031314456D707479205375626A65" + - "63742049737375657230820122300D06092A864886F70D01010105000382010F" + - "003082010A0282010100A67F5898CCA5FC235EEB2FF14BF0BF490BB507C4D552" + - "76E0D86CAA72BFDBDE7E7F38EC3184B18D32AEA7F5A1EEF0D2D24B7B8ED340F5" + - "00703D3758B7E3824848CD9A4CDF15F73EBB1D4A02ED8182673138822C148463" + - "B6126D14BE03C9A4DF62D35109BF7A8CDDFF6AE5A55C75496C13376C9B0096A0" + - "5F398703FFBB6B69F7EA79B1F1F955F07CEBDAF3FB87D6E6F9C33678C49EC5E5" + - "7EF10AEB14E009C83DC3DD3A2707F36D1A8723849DCD020CFBB0D38972B15F12" + - "53209E015915A2275ADFB0164DB5A6C79BA53EA5782B001D92764D21694E5992" + - "33B4D2C7FE260F925194C372EE473812B4F82381B4027E1F7F52E72A6ECC5BEE" + - "656FE161E7681A06A9BF0203010001A3133011300F0603551D130101FF040530" + - "030101FF300D06092A864886F70D01010B050003820101008D239025B8266EFF" + - "AEB1B76EA159ED7BF6A6F2E5A23266DF07767DEDF26B43983EC8717AC2E6B99E" + - "A21625D787D39BF94110D5A9B37CF0E6FB3062090D280B889A0E8DA5952E46D5" + - "107F9BE829119282ADD53414CE0BA47C1E04D82BCC50118BB9CB3905E22FADD5" + - "1905F23373D7F5E9E32C5C7D27B68CD15D1E079153B66B3DBE148D4DF2BF8EA1" + - "8E68D838BE1C86E68E4CAF09A90F7428A4A50922BCB01010A1B585227930CEE0" + - "027D561804C2F023AEBAA63F312F49A37B74BED2DB8B6D8AA1A6E60320589EB5" + - "B14EB93CC47DAF7F07D67C25FD275493C0AF0CC23E8AED47963DCCE7C2ADFD56" + - "5B8A77118C2978E15D1511572C4496CD1180094D43AE50FD").HexToByteArray(); + "308202D3308201BBA00302010202083875DCB8D7B865B5300D06092A864886F7" + + "0D01010B0500301F311D301B06035504031314456D707479205375626A656374" + + "20497373756572301E170D3235303131383030303330375A170D343530313139" + + "3030303330375A301F311D301B06035504031314456D707479205375626A6563" + + "742049737375657230820122300D06092A864886F70D01010105000382010F00" + + "3082010A0282010100DC1542882EF660F49EFCB483151A9D9AC1E7801A3BA4A2" + + "176427F0F6A59137687C096CB59B2D9398A1E3FC3AE11D0301D343D3206B8EF2" + + "F558025889B84BAAA7337750C5E878E278132A53AD8DCBA3061D241B44008772" + + "4BED8E6875BD509EB6C2D920F2E74529609F02E1639FF6839E5E18D5F4A7BB6C" + + "021848274EBB4E1207A5C18873EB9A171FFAD2A0F5CC3B82E60B1CF06F7C482C" + + "3555CC45D011245C242D33FD989953383F6F7E9D5B6246DAE7D241C0575E7872" + + "06329A58151E97232C510E5609745D84EB3768A82C350CAB0230C522963B93E0" + + "5025FBC4B0865705310F35A8BA589D8D3B794765BD0F4D34BE9A057AA7CEF98F" + + "46125C50A4856766D90203010001A3133011300F0603551D130101FF04053003" + + "0101FF300D06092A864886F70D01010B0500038201010042940334A754ACA256" + + "C27BD14FD05FEC3730DC6633C5DF5DAD7323CD8FB9C01473DF129A7D4F03751B" + + "2A9B53C8E954770090BD5153991A43DAD8ED9602AB93DFEFFF4D651354775CE8" + + "2A105B5653EB6F2A6E369BC1D98361699F6CD2AB0418C6E57C18647895D77F3F" + + "402909F85085037F13C6BEF847A4218B4F8FBC8823BFA9C4491CA3F510423A8C" + + "BF192CAEE3C190C15D367067F91E235835A502C9219499A443833E40AC660DC6" + + "268CB44411AA2482CB11087BD4DBED936FB564367FB85903BDE2B778CE64D976" + + "28C17EA2B73F84C6D7D6BBF387F4484DCE45ECEE3495530103F37AE656DC0602" + + "22DCE1EB7F2DC5E0B1DF67B62FBA8C705A3D4838662E8D").HexToByteArray(); internal static byte[] T61StringCertificate = ( "2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d494943" + diff --git a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs index cdab35da2b134b..4fe7c4821a2aa8 100644 --- a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs +++ b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs @@ -813,9 +813,11 @@ static string ToStringPadded(Half value) /// Verifies that two values are equal, within the . /// The expected value /// The value to be compared against - /// The total variance allowed between the expected and actual results. + /// The total variance allowed between the expected and actual results. + /// The banner to show; if null, then the standard + /// banner of "Values differ" will be used /// Thrown when the values are not equal - public static void Equal(double expected, double actual, double variance) + public static void Equal(double expected, double actual, double variance, string? banner = null) { if (double.IsNaN(expected)) { @@ -824,11 +826,11 @@ public static void Equal(double expected, double actual, double variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (double.IsNaN(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (double.IsNegativeInfinity(expected)) @@ -838,11 +840,11 @@ public static void Equal(double expected, double actual, double variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (double.IsNegativeInfinity(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (double.IsPositiveInfinity(expected)) @@ -852,11 +854,11 @@ public static void Equal(double expected, double actual, double variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (double.IsPositiveInfinity(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (IsNegativeZero(expected)) @@ -868,7 +870,7 @@ public static void Equal(double expected, double actual, double variance) if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -879,7 +881,7 @@ public static void Equal(double expected, double actual, double variance) { if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -896,7 +898,7 @@ public static void Equal(double expected, double actual, double variance) if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -907,7 +909,7 @@ public static void Equal(double expected, double actual, double variance) { if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -919,7 +921,7 @@ public static void Equal(double expected, double actual, double variance) if (delta > variance) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } } @@ -927,8 +929,10 @@ public static void Equal(double expected, double actual, double variance) /// The expected value /// The value to be compared against /// The total variance allowed between the expected and actual results. + /// The banner to show; if null, then the standard + /// banner of "Values differ" will be used /// Thrown when the values are not equal - public static void Equal(float expected, float actual, float variance) + public static void Equal(float expected, float actual, float variance, string? banner = null) { if (float.IsNaN(expected)) { @@ -937,11 +941,11 @@ public static void Equal(float expected, float actual, float variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (float.IsNaN(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (float.IsNegativeInfinity(expected)) @@ -951,11 +955,11 @@ public static void Equal(float expected, float actual, float variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (float.IsNegativeInfinity(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (float.IsPositiveInfinity(expected)) @@ -965,11 +969,11 @@ public static void Equal(float expected, float actual, float variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (float.IsPositiveInfinity(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (IsNegativeZero(expected)) @@ -981,7 +985,7 @@ public static void Equal(float expected, float actual, float variance) if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -992,7 +996,7 @@ public static void Equal(float expected, float actual, float variance) { if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -1009,7 +1013,7 @@ public static void Equal(float expected, float actual, float variance) if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -1020,7 +1024,7 @@ public static void Equal(float expected, float actual, float variance) { if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -1032,7 +1036,7 @@ public static void Equal(float expected, float actual, float variance) if (delta > variance) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } } @@ -1041,8 +1045,10 @@ public static void Equal(float expected, float actual, float variance) /// The expected value /// The value to be compared against /// The total variance allowed between the expected and actual results. + /// The banner to show; if null, then the standard + /// banner of "Values differ" will be used /// Thrown when the values are not equal - public static void Equal(Half expected, Half actual, Half variance) + public static void Equal(Half expected, Half actual, Half variance, string? banner = null) { if (Half.IsNaN(expected)) { @@ -1051,11 +1057,11 @@ public static void Equal(Half expected, Half actual, Half variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (Half.IsNaN(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (Half.IsNegativeInfinity(expected)) @@ -1065,11 +1071,11 @@ public static void Equal(Half expected, Half actual, Half variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (Half.IsNegativeInfinity(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (Half.IsPositiveInfinity(expected)) @@ -1079,11 +1085,11 @@ public static void Equal(Half expected, Half actual, Half variance) return; } - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } else if (Half.IsPositiveInfinity(actual)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } if (IsNegativeZero(expected)) @@ -1095,7 +1101,7 @@ public static void Equal(Half expected, Half actual, Half variance) if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -1106,7 +1112,7 @@ public static void Equal(Half expected, Half actual, Half variance) { if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -1123,7 +1129,7 @@ public static void Equal(Half expected, Half actual, Half variance) if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -1134,7 +1140,7 @@ public static void Equal(Half expected, Half actual, Half variance) { if (IsPositiveZero(variance) || IsNegativeZero(variance)) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } // When the variance is not +-0.0, then we are handling a case where @@ -1146,7 +1152,7 @@ public static void Equal(Half expected, Half actual, Half variance) if (delta > variance) { - throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); + throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual), banner); } } #endif diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs index f0924cdedf5fdb..59c0b9a29d3932 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs @@ -51,9 +51,10 @@ public static partial class PlatformDetection throw new PlatformNotSupportedException(); private static readonly Version s_openssl3Version = new Version(3, 0, 0); - public static bool IsOpenSsl3 => !IsApplePlatform && !IsWindows && !IsAndroid && !IsBrowser ? - GetOpenSslVersion() >= s_openssl3Version : - false; + private static readonly Version s_openssl3_4Version = new Version(3, 4, 0); + + public static bool IsOpenSsl3 => IsOpenSslVersionAtLeast(s_openssl3Version); + public static bool IsOpenSsl3_4 => IsOpenSslVersionAtLeast(s_openssl3_4Version); /// /// If gnulibc is available, returns the release, such as "stable". @@ -140,6 +141,18 @@ private static Version GetOpenSslVersion() return s_opensslVersion; } + // The "IsOpenSsl" properties answer false on Apple, even if OpenSSL is present for lightup, + // as they are answering the question "is OpenSSL the primary crypto provider". + private static bool IsOpenSslVersionAtLeast(Version minVersion) + { + if (IsApplePlatform || IsWindows || IsAndroid || IsBrowser) + { + return false; + } + + return GetOpenSslVersion() >= minVersion; + } + private static Version ToVersion(string versionString) { // In some distros/versions we cannot discover the distro version; return something valid. diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs index 0c95499694451a..90b6931ba88acd 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs @@ -2,11 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; @@ -81,15 +83,7 @@ public MemoryCache(IOptions optionsAccessor, ILoggerFactory /// Gets an enumerable of the all the keys in the . /// public IEnumerable Keys - { - get - { - foreach (KeyValuePair pairs in _coherentState._entries) - { - yield return pairs.Key; - } - } - } + => _coherentState.GetAllKeys(); /// /// Internal accessor for Size for testing only. @@ -141,7 +135,7 @@ internal void SetEntry(CacheEntry entry) entry.LastAccessed = utcNow; CoherentState coherentState = _coherentState; // Clear() can update the reference in the meantime - if (coherentState._entries.TryGetValue(entry.Key, out CacheEntry? priorEntry)) + if (coherentState.TryGetValue(entry.Key, out CacheEntry? priorEntry)) { priorEntry.SetExpired(EvictionReason.Replaced); } @@ -160,19 +154,19 @@ internal void SetEntry(CacheEntry entry) if (priorEntry == null) { // Try to add the new entry if no previous entries exist. - entryAdded = coherentState._entries.TryAdd(entry.Key, entry); + entryAdded = coherentState.TryAdd(entry.Key, entry); } else { // Try to update with the new entry if a previous entries exist. - entryAdded = coherentState._entries.TryUpdate(entry.Key, entry, priorEntry); + entryAdded = coherentState.TryUpdate(entry.Key, entry, priorEntry); if (!entryAdded) { // The update will fail if the previous entry was removed after retrieval. // Adding the new entry will succeed only if no entry has been added since. // This guarantees removing an old entry does not prevent adding a new entry. - entryAdded = coherentState._entries.TryAdd(entry.Key, entry); + entryAdded = coherentState.TryAdd(entry.Key, entry); } } @@ -217,7 +211,7 @@ public bool TryGetValue(object key, out object? result) DateTime utcNow = UtcNow; CoherentState coherentState = _coherentState; // Clear() can update the reference in the meantime - if (coherentState._entries.TryGetValue(key, out CacheEntry? tmp)) + if (coherentState.TryGetValue(key, out CacheEntry? tmp)) { CacheEntry entry = tmp; // Check if expired due to expiration tokens, timers, etc. and if so, remove it. @@ -276,7 +270,8 @@ public void Remove(object key) CheckDisposed(); CoherentState coherentState = _coherentState; // Clear() can update the reference in the meantime - if (coherentState._entries.TryRemove(key, out CacheEntry? entry)) + + if (coherentState.TryRemove(key, out CacheEntry? entry)) { if (_options.HasSizeLimit) { @@ -298,10 +293,10 @@ public void Clear() CheckDisposed(); CoherentState oldState = Interlocked.Exchange(ref _coherentState, new CoherentState()); - foreach (KeyValuePair entry in oldState._entries) + foreach (CacheEntry entry in oldState.GetAllValues()) { - entry.Value.SetExpired(EvictionReason.Removed); - entry.Value.InvokeEvictionCallbacks(); + entry.SetExpired(EvictionReason.Removed); + entry.InvokeEvictionCallbacks(); } } @@ -422,10 +417,9 @@ private void ScanForExpiredItems() DateTime utcNow = _lastExpirationScan = UtcNow; CoherentState coherentState = _coherentState; // Clear() can update the reference in the meantime - foreach (KeyValuePair item in coherentState._entries) - { - CacheEntry entry = item.Value; + foreach (CacheEntry entry in coherentState.GetAllValues()) + { if (entry.CheckExpired(utcNow)) { coherentState.RemoveEntry(entry, _options); @@ -547,9 +541,8 @@ private void Compact(long removalSizeTarget, Func computeEntry // Sort items by expired & priority status DateTime utcNow = UtcNow; - foreach (KeyValuePair item in coherentState._entries) + foreach (CacheEntry entry in coherentState.GetAllValues()) { - CacheEntry entry = item.Value; if (entry.CheckExpired(utcNow)) { entriesToRemove.Add(entry); @@ -676,18 +669,71 @@ private static void ValidateCacheKey(object key) /// private sealed class CoherentState { - internal ConcurrentDictionary _entries = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _stringEntries = new ConcurrentDictionary(StringKeyComparer.Instance); + private readonly ConcurrentDictionary _nonStringEntries = new ConcurrentDictionary(); internal long _cacheSize; - private ICollection> EntriesCollection => _entries; + internal bool TryGetValue(object key, [NotNullWhen(true)] out CacheEntry? entry) + => key is string s ? _stringEntries.TryGetValue(s, out entry) : _nonStringEntries.TryGetValue(key, out entry); + + internal bool TryRemove(object key, [NotNullWhen(true)] out CacheEntry? entry) + => key is string s ? _stringEntries.TryRemove(s, out entry) : _nonStringEntries.TryRemove(key, out entry); + + internal bool TryAdd(object key, CacheEntry entry) + => key is string s ? _stringEntries.TryAdd(s, entry) : _nonStringEntries.TryAdd(key, entry); + + internal bool TryUpdate(object key, CacheEntry entry, CacheEntry comparison) + => key is string s ? _stringEntries.TryUpdate(s, entry, comparison) : _nonStringEntries.TryUpdate(key, entry, comparison); + + public IEnumerable GetAllValues() + { + // note this mimics the outgoing code in that we don't just access + // .Values, which has additional overheads; this is only used for rare + // calls - compaction, clear, etc - so the additional overhead of a + // generated enumerator is not alarming + foreach (KeyValuePair entry in _stringEntries) + { + yield return entry.Value; + } + foreach (KeyValuePair entry in _nonStringEntries) + { + yield return entry.Value; + } + } + + public IEnumerable GetAllKeys() + { + foreach (KeyValuePair pairs in _stringEntries) + { + yield return pairs.Key; + } + foreach (KeyValuePair pairs in _nonStringEntries) + { + yield return pairs.Key; + } + } + + private ICollection> StringEntriesCollection => _stringEntries; + private ICollection> NonStringEntriesCollection => _nonStringEntries; - internal int Count => _entries.Count; + internal int Count => _stringEntries.Count + _nonStringEntries.Count; internal long Size => Volatile.Read(ref _cacheSize); internal void RemoveEntry(CacheEntry entry, MemoryCacheOptions options) { - if (EntriesCollection.Remove(new KeyValuePair(entry.Key, entry))) + if (entry.Key is string s) + { + if (StringEntriesCollection.Remove(new KeyValuePair(s, entry))) + { + if (options.SizeLimit.HasValue) + { + Interlocked.Add(ref _cacheSize, -entry.Size); + } + entry.InvokeEvictionCallbacks(); + } + } + else if (NonStringEntriesCollection.Remove(new KeyValuePair(entry.Key, entry))) { if (options.SizeLimit.HasValue) { @@ -696,6 +742,35 @@ internal void RemoveEntry(CacheEntry entry, MemoryCacheOptions options) entry.InvokeEvictionCallbacks(); } } + +#if NETCOREAPP + // on .NET Core, the inbuilt comparer has Marvin built in; no need to intercept + private static class StringKeyComparer + { + internal static IEqualityComparer Instance => EqualityComparer.Default; + } +#else + // otherwise, we need a custom comparer that manually implements Marvin + private sealed class StringKeyComparer : IEqualityComparer, IEqualityComparer + { + private StringKeyComparer() { } + + internal static readonly IEqualityComparer Instance = new StringKeyComparer(); + + // special-case string keys and use Marvin hashing + public int GetHashCode(string? s) => s is null ? 0 + : Marvin.ComputeHash32(MemoryMarshal.AsBytes(s.AsSpan()), Marvin.DefaultSeed); + + public bool Equals(string? x, string? y) + => string.Equals(x, y); + + bool IEqualityComparer.Equals(object x, object y) + => object.Equals(x, y); + + int IEqualityComparer.GetHashCode(object obj) + => obj is string s ? GetHashCode(s) : 0; + } +#endif } } } diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/Microsoft.Extensions.Caching.Memory.csproj b/src/libraries/Microsoft.Extensions.Caching.Memory/src/Microsoft.Extensions.Caching.Memory.csproj index 469e6e572536ef..a69e95d7bf2028 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/src/Microsoft.Extensions.Caching.Memory.csproj +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/Microsoft.Extensions.Caching.Memory.csproj @@ -5,6 +5,7 @@ true true In-memory cache implementation of Microsoft.Extensions.Caching.Memory.IMemoryCache. + true @@ -21,4 +22,8 @@ + + + + diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheSetAndRemoveTests.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheSetAndRemoveTests.cs index cebc0a374b3102..57c3f56913b60d 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheSetAndRemoveTests.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheSetAndRemoveTests.cs @@ -850,6 +850,21 @@ public async Task GetOrCreateAsyncWithCacheEntryOptions() Assert.False(cache.TryGetValue(cacheKey, out _)); } + [Fact] + public void MixedKeysUsage() + { + // keys are split internally into 2 separate chunks + var cache = CreateCache(); + var typed = Assert.IsType(cache); + object key0 = 123.45M, key1 = "123.45"; + cache.Set(key0, "string value"); + cache.Set(key1, "decimal value"); + + Assert.Equal(2, typed.Count); + Assert.Equal("string value", cache.Get(key0)); + Assert.Equal("decimal value", cache.Get(key1)); + } + private class TestKey { public override bool Equals(object obj) => true; diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs index cdb8551bffdca4..93250857111adf 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs @@ -1212,14 +1212,14 @@ private void WriteDataDescriptor() BinaryPrimitives.WriteInt64LittleEndian(dataDescriptor[ZipLocalFileHeader.Zip64DataDescriptor.FieldLocations.CompressedSize..], _compressedSize); BinaryPrimitives.WriteInt64LittleEndian(dataDescriptor[ZipLocalFileHeader.Zip64DataDescriptor.FieldLocations.UncompressedSize..], _uncompressedSize); - bytesToWrite = ZipLocalFileHeader.Zip64DataDescriptor.FieldLocations.CompressedSize + ZipLocalFileHeader.Zip64DataDescriptor.FieldLengths.UncompressedSize; + bytesToWrite = ZipLocalFileHeader.Zip64DataDescriptor.FieldLocations.UncompressedSize + ZipLocalFileHeader.Zip64DataDescriptor.FieldLengths.UncompressedSize; } else { BinaryPrimitives.WriteUInt32LittleEndian(dataDescriptor[ZipLocalFileHeader.ZipDataDescriptor.FieldLocations.CompressedSize..], (uint)_compressedSize); BinaryPrimitives.WriteUInt32LittleEndian(dataDescriptor[ZipLocalFileHeader.ZipDataDescriptor.FieldLocations.UncompressedSize..], (uint)_uncompressedSize); - bytesToWrite = ZipLocalFileHeader.ZipDataDescriptor.FieldLocations.CompressedSize + ZipLocalFileHeader.ZipDataDescriptor.FieldLengths.UncompressedSize; + bytesToWrite = ZipLocalFileHeader.ZipDataDescriptor.FieldLocations.UncompressedSize + ZipLocalFileHeader.ZipDataDescriptor.FieldLengths.UncompressedSize; } _archive.ArchiveStream.Write(dataDescriptor[..bytesToWrite]); diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs index a4567fe6769abf..6365fafab66b96 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs @@ -340,28 +340,33 @@ public static void RemoveZip64Blocks(List extraFields) public void WriteBlock(Stream stream) { Span extraFieldData = stackalloc byte[TotalSize]; + int startOffset = ZipGenericExtraField.FieldLocations.DynamicData; BinaryPrimitives.WriteUInt16LittleEndian(extraFieldData[FieldLocations.Tag..], TagConstant); BinaryPrimitives.WriteUInt16LittleEndian(extraFieldData[FieldLocations.Size..], _size); if (_uncompressedSize != null) { - BinaryPrimitives.WriteInt64LittleEndian(extraFieldData[FieldLocations.UncompressedSize..], _uncompressedSize.Value); + BinaryPrimitives.WriteInt64LittleEndian(extraFieldData[startOffset..], _uncompressedSize.Value); + startOffset += FieldLengths.UncompressedSize; } if (_compressedSize != null) { - BinaryPrimitives.WriteInt64LittleEndian(extraFieldData[FieldLocations.CompressedSize..], _compressedSize.Value); + BinaryPrimitives.WriteInt64LittleEndian(extraFieldData[startOffset..], _compressedSize.Value); + startOffset += FieldLengths.CompressedSize; } if (_localHeaderOffset != null) { - BinaryPrimitives.WriteInt64LittleEndian(extraFieldData[FieldLocations.LocalHeaderOffset..], _localHeaderOffset.Value); + BinaryPrimitives.WriteInt64LittleEndian(extraFieldData[startOffset..], _localHeaderOffset.Value); + startOffset += FieldLengths.LocalHeaderOffset; } if (_startDiskNumber != null) { - BinaryPrimitives.WriteUInt32LittleEndian(extraFieldData[FieldLocations.StartDiskNumber..], _startDiskNumber.Value); + BinaryPrimitives.WriteUInt32LittleEndian(extraFieldData[startOffset..], _startDiskNumber.Value); + startOffset += FieldLengths.StartDiskNumber; } stream.Write(extraFieldData); diff --git a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs index e485b71f87639e..09126f59f097eb 100644 --- a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs +++ b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs @@ -77,7 +77,9 @@ public partial struct Matrix4x4 : System.IEquatable public System.Numerics.Vector3 Translation { readonly get { throw null; } set { } } public static System.Numerics.Matrix4x4 Add(System.Numerics.Matrix4x4 value1, System.Numerics.Matrix4x4 value2) { throw null; } public static System.Numerics.Matrix4x4 CreateBillboard(System.Numerics.Vector3 objectPosition, System.Numerics.Vector3 cameraPosition, System.Numerics.Vector3 cameraUpVector, System.Numerics.Vector3 cameraForwardVector) { throw null; } + public static System.Numerics.Matrix4x4 CreateBillboardLeftHanded(System.Numerics.Vector3 objectPosition, System.Numerics.Vector3 cameraPosition, System.Numerics.Vector3 cameraUpVector, System.Numerics.Vector3 cameraForwardVector) { throw null; } public static System.Numerics.Matrix4x4 CreateConstrainedBillboard(System.Numerics.Vector3 objectPosition, System.Numerics.Vector3 cameraPosition, System.Numerics.Vector3 rotateAxis, System.Numerics.Vector3 cameraForwardVector, System.Numerics.Vector3 objectForwardVector) { throw null; } + public static System.Numerics.Matrix4x4 CreateConstrainedBillboardLeftHanded(System.Numerics.Vector3 objectPosition, System.Numerics.Vector3 cameraPosition, System.Numerics.Vector3 rotateAxis, System.Numerics.Vector3 cameraForwardVector, System.Numerics.Vector3 objectForwardVector) { throw null; } public static System.Numerics.Matrix4x4 CreateFromAxisAngle(System.Numerics.Vector3 axis, float angle) { throw null; } public static System.Numerics.Matrix4x4 CreateFromQuaternion(System.Numerics.Quaternion quaternion) { throw null; } public static System.Numerics.Matrix4x4 CreateFromYawPitchRoll(float yaw, float pitch, float roll) { throw null; } diff --git a/src/libraries/System.Numerics.Vectors/tests/Matrix4x4Tests.cs b/src/libraries/System.Numerics.Vectors/tests/Matrix4x4Tests.cs index 2107bcf184f8d9..fa52f037b22cd5 100644 --- a/src/libraries/System.Numerics.Vectors/tests/Matrix4x4Tests.cs +++ b/src/libraries/System.Numerics.Vectors/tests/Matrix4x4Tests.cs @@ -9,7 +9,7 @@ namespace System.Numerics.Tests { public sealed class Matrix4x4Tests { - static Matrix4x4 GenerateIncrementalMatrixNumber(float value = 0.0f) + private static Matrix4x4 GenerateIncrementalMatrixNumber(float value = 0.0f) { Matrix4x4 a = new Matrix4x4(); a.M11 = value + 1.0f; @@ -31,7 +31,7 @@ static Matrix4x4 GenerateIncrementalMatrixNumber(float value = 0.0f) return a; } - static Matrix4x4 GenerateTestMatrix() + private static Matrix4x4 GenerateTestMatrix() { Matrix4x4 m = Matrix4x4.CreateRotationX(MathHelper.ToRadians(30.0f)) * @@ -41,6 +41,57 @@ static Matrix4x4 GenerateTestMatrix() return m; } + private static Matrix4x4 DefaultVarianceMatrix = GenerateFilledMatrix(1e-5f); + + private static Matrix4x4 GenerateFilledMatrix(float value) => new Matrix4x4 + { + M11 = value, + M12 = value, + M13 = value, + M14 = value, + M21 = value, + M22 = value, + M23 = value, + M24 = value, + M31 = value, + M32 = value, + M33 = value, + M34 = value, + M41 = value, + M42 = value, + M43 = value, + M44 = value + }; + + private static Vector3 InverseHandedness(Vector3 vector) => new Vector3(vector.X, vector.Y, -vector.Z); + + // The handedness-swapped matrix of matrix M is B^-1 * M * B where B is the change of handedness matrix. + // Since only the Z coordinate is flipped when changing handedness, + // + // B = [ 1 0 0 0 + // 0 1 0 0 + // 0 0 -1 0 + // 0 0 0 1 ] + // + // and B is its own inverse. So the handedness swap can be simplified to + // + // B^-1 * M * B = [ m11 m12 -m13 m14 + // m21 m22 -m23 m24 + // -m31 -m32 m33 -m34 + // m41 m42 -m43 m44 ] + private static Matrix4x4 InverseHandedness(Matrix4x4 matrix) => new Matrix4x4( + matrix.M11, matrix.M12, -matrix.M13, matrix.M14, + matrix.M21, matrix.M22, -matrix.M23, matrix.M24, + -matrix.M31, -matrix.M32, matrix.M33, -matrix.M34, + matrix.M41, matrix.M42, -matrix.M43, matrix.M44); + + private static void AssertEqual(Matrix4x4 expected, Matrix4x4 actual, Matrix4x4 variance) + { + for (var r = 0; r < 4; r++) + for (var c = 0; c < 4; c++) + AssertExtensions.Equal(expected[r, c], actual[r, c], variance[r, c], $"Values differ at Matrix4x4.M{r + 1}{c + 1}"); + } + [Theory] [InlineData(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f)] [InlineData(1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f)] @@ -2137,13 +2188,25 @@ public void Matrix4x4SubtractTest() Assert.Equal(expected, actual); } - private void CreateBillboardFact(Vector3 placeDirection, Vector3 cameraUpVector, Matrix4x4 expectedRotation) + private void CreateBillboardFact(Vector3 placeDirection, Vector3 cameraUpVector, Matrix4x4 expectedRotationRightHanded, Matrix4x4 expectedRotationLeftHanded) { Vector3 cameraPosition = new Vector3(3.0f, 4.0f, 5.0f); Vector3 objectPosition = cameraPosition + placeDirection * 10.0f; - Matrix4x4 expected = expectedRotation * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateBillboard(objectPosition, cameraPosition, cameraUpVector, new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateBillboard did not return the expected value."); + Matrix4x4 expected = expectedRotationRightHanded * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualRH = Matrix4x4.CreateBillboard(objectPosition, cameraPosition, cameraUpVector, new Vector3(0, 0, -1)); + Assert.True(MathHelper.Equal(expected, actualRH), "Matrix4x4.CreateBillboard did not return the expected value."); + + placeDirection = InverseHandedness(placeDirection); + cameraUpVector = InverseHandedness(cameraUpVector); + + cameraPosition = new Vector3(3.0f, 4.0f, -5.0f); + objectPosition = cameraPosition + placeDirection * 10.0f; + expected = expectedRotationLeftHanded * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualLH = Matrix4x4.CreateBillboardLeftHanded(objectPosition, cameraPosition, cameraUpVector, Vector3.UnitZ); + Assert.True(MathHelper.Equal(expected, actualLH), "Matrix4x4.CreateBillboardLeftHanded did not return the expected value."); + + AssertEqual(actualRH, InverseHandedness(actualLH), DefaultVarianceMatrix); + AssertEqual(InverseHandedness(actualRH), actualLH, DefaultVarianceMatrix); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2152,7 +2215,11 @@ private void CreateBillboardFact(Vector3 placeDirection, Vector3 cameraUpVector, public void Matrix4x4CreateBillboardTest01() { // Object placed at Forward of camera. result must be same as 180 degrees rotate along y-axis. - CreateBillboardFact(new Vector3(0, 0, -1), new Vector3(0, 1, 0), Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f))); + CreateBillboardFact( + new Vector3(0, 0, -1), + Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2161,7 +2228,11 @@ public void Matrix4x4CreateBillboardTest01() public void Matrix4x4CreateBillboardTest02() { // Object placed at Backward of camera. This result must be same as 0 degrees rotate along y-axis. - CreateBillboardFact(new Vector3(0, 0, 1), new Vector3(0, 1, 0), Matrix4x4.CreateRotationY(MathHelper.ToRadians(0))); + CreateBillboardFact( + Vector3.UnitZ, + Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(0)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(0))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2170,7 +2241,11 @@ public void Matrix4x4CreateBillboardTest02() public void Matrix4x4CreateBillboardTest03() { // Place object at Right side of camera. This result must be same as 90 degrees rotate along y-axis. - CreateBillboardFact(new Vector3(1, 0, 0), new Vector3(0, 1, 0), Matrix4x4.CreateRotationY(MathHelper.ToRadians(90))); + CreateBillboardFact( + Vector3.UnitX, + Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(90)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(-90))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2179,7 +2254,11 @@ public void Matrix4x4CreateBillboardTest03() public void Matrix4x4CreateBillboardTest04() { // Place object at Left side of camera. This result must be same as -90 degrees rotate along y-axis. - CreateBillboardFact(new Vector3(-1, 0, 0), new Vector3(0, 1, 0), Matrix4x4.CreateRotationY(MathHelper.ToRadians(-90))); + CreateBillboardFact( + new Vector3(-1, 0, 0), + Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(-90)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(90))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2188,8 +2267,11 @@ public void Matrix4x4CreateBillboardTest04() public void Matrix4x4CreateBillboardTest05() { // Place object at Up side of camera. result must be same as 180 degrees rotate along z-axis after 90 degrees rotate along x-axis. - CreateBillboardFact(new Vector3(0, 1, 0), new Vector3(0, 0, 1), - Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(180))); + CreateBillboardFact( + Vector3.UnitY, + Vector3.UnitZ, + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(180)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(180))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2198,8 +2280,11 @@ public void Matrix4x4CreateBillboardTest05() public void Matrix4x4CreateBillboardTest06() { // Place object at Down side of camera. result must be same as 0 degrees rotate along z-axis after 90 degrees rotate along x-axis. - CreateBillboardFact(new Vector3(0, -1, 0), new Vector3(0, 0, 1), - Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(0))); + CreateBillboardFact( + new Vector3(0, -1, 0), + Vector3.UnitZ, + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(0)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(0))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2208,8 +2293,11 @@ public void Matrix4x4CreateBillboardTest06() public void Matrix4x4CreateBillboardTest07() { // Place object at Right side of camera. result must be same as 90 degrees rotate along z-axis after 90 degrees rotate along x-axis. - CreateBillboardFact(new Vector3(1, 0, 0), new Vector3(0, 0, 1), - Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f))); + CreateBillboardFact( + Vector3.UnitX, + Vector3.UnitZ, + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2218,8 +2306,11 @@ public void Matrix4x4CreateBillboardTest07() public void Matrix4x4CreateBillboardTest08() { // Place object at Left side of camera. result must be same as -90 degrees rotate along z-axis after 90 degrees rotate along x-axis. - CreateBillboardFact(new Vector3(-1, 0, 0), new Vector3(0, 0, 1), - Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f))); + CreateBillboardFact( + new Vector3(-1, 0, 0), + Vector3.UnitZ, + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2228,8 +2319,11 @@ public void Matrix4x4CreateBillboardTest08() public void Matrix4x4CreateBillboardTest09() { // Place object at Up side of camera. result must be same as -90 degrees rotate along x-axis after 90 degrees rotate along z-axis. - CreateBillboardFact(new Vector3(0, 1, 0), new Vector3(-1, 0, 0), - Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f))); + CreateBillboardFact( + Vector3.UnitY, + new Vector3(-1, 0, 0), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2238,8 +2332,11 @@ public void Matrix4x4CreateBillboardTest09() public void Matrix4x4CreateBillboardTest10() { // Place object at Down side of camera. result must be same as 90 degrees rotate along x-axis after 90 degrees rotate along z-axis. - CreateBillboardFact(new Vector3(0, -1, 0), new Vector3(-1, 0, 0), - Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f))); + CreateBillboardFact( + new Vector3(0, -1, 0), + new Vector3(-1, 0, 0), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f))); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2248,7 +2345,10 @@ public void Matrix4x4CreateBillboardTest10() public void Matrix4x4CreateBillboardTest11() { // Place object at Forward side of camera. result must be same as 180 degrees rotate along x-axis after 90 degrees rotate along z-axis. - CreateBillboardFact(new Vector3(0, 0, -1), new Vector3(-1, 0, 0), + CreateBillboardFact( + new Vector3(0, 0, -1), + new Vector3(-1, 0, 0), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(180.0f)), Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(180.0f))); } @@ -2258,7 +2358,10 @@ public void Matrix4x4CreateBillboardTest11() public void Matrix4x4CreateBillboardTest12() { // Place object at Backward side of camera. result must be same as 0 degrees rotate along x-axis after 90 degrees rotate along z-axis. - CreateBillboardFact(new Vector3(0, 0, 1), new Vector3(-1, 0, 0), + CreateBillboardFact( + Vector3.UnitZ, + new Vector3(-1, 0, 0), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(0.0f)), Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(0.0f))); } @@ -2269,12 +2372,23 @@ public void Matrix4x4CreateBillboardTooCloseTest1() { Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); Vector3 cameraPosition = objectPosition; - Vector3 cameraUpVector = new Vector3(0, 1, 0); + Vector3 cameraUpVector = Vector3.UnitY; // Doesn't pass camera face direction. CreateBillboard uses new Vector3f(0, 0, -1) direction. Result must be same as 180 degrees rotate along y-axis. Matrix4x4 expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateBillboard(objectPosition, cameraPosition, cameraUpVector, new Vector3(0, 0, 1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateBillboard did not return the expected value."); + Matrix4x4 actualRH = Matrix4x4.CreateBillboard(objectPosition, cameraPosition, cameraUpVector, Vector3.UnitZ); + Assert.True(MathHelper.Equal(expected, actualRH), "Matrix4x4.CreateBillboard did not return the expected value."); + + objectPosition = new Vector3(3.0f, 4.0f, -5.0f); + cameraPosition = objectPosition; + cameraUpVector = Vector3.UnitY; + + expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)) * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualLH = Matrix4x4.CreateBillboardLeftHanded(objectPosition, cameraPosition, cameraUpVector, new Vector3(0, 0, -1)); + Assert.True(MathHelper.Equal(expected, actualLH), "Matrix4x4.CreateBillboardLeftHanded did not return the expected value."); + + AssertEqual(actualRH, InverseHandedness(actualLH), DefaultVarianceMatrix); + AssertEqual(InverseHandedness(actualRH), actualLH, DefaultVarianceMatrix); } // A test for CreateBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2284,30 +2398,65 @@ public void Matrix4x4CreateBillboardTooCloseTest2() { Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); Vector3 cameraPosition = objectPosition; - Vector3 cameraUpVector = new Vector3(0, 1, 0); + Vector3 cameraUpVector = Vector3.UnitY; // Passes Vector3f.Right as camera face direction. Result must be same as -90 degrees rotate along y-axis. Matrix4x4 expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateBillboard(objectPosition, cameraPosition, cameraUpVector, new Vector3(1, 0, 0)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateBillboard did not return the expected value."); + Matrix4x4 actualRH = Matrix4x4.CreateBillboard(objectPosition, cameraPosition, cameraUpVector, Vector3.UnitX); + Assert.True(MathHelper.Equal(expected, actualRH), "Matrix4x4.CreateBillboard did not return the expected value."); + + objectPosition = new Vector3(3.0f, 4.0f, -5.0f); + cameraPosition = objectPosition; + cameraUpVector = Vector3.UnitY; + + expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualLH = Matrix4x4.CreateBillboardLeftHanded(objectPosition, cameraPosition, cameraUpVector, Vector3.UnitX); + Assert.True(MathHelper.Equal(expected, actualLH), "Matrix4x4.CreateBillboardLeftHanded did not return the expected value."); } - private void CreateConstrainedBillboardFact(Vector3 placeDirection, Vector3 rotateAxis, Matrix4x4 expectedRotation) + private void CreateConstrainedBillboardFact(Vector3 placeDirection, Vector3 rotateAxis, Matrix4x4 expectedRotationRightHanded, Matrix4x4 expectedRotationLeftHanded) { Vector3 cameraPosition = new Vector3(3.0f, 4.0f, 5.0f); Vector3 objectPosition = cameraPosition + placeDirection * 10.0f; - Matrix4x4 expected = expectedRotation * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4 expected = expectedRotationRightHanded * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualRH = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); + Assert.True(MathHelper.Equal(expected, actualRH), $"{nameof(Matrix4x4.CreateConstrainedBillboard)} did not return the expected value."); + + // When you move camera along rotateAxis, result must be same. + cameraPosition += rotateAxis * 10.0f; + Matrix4x4 actualTranslatedUpRH = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); + Assert.True(MathHelper.Equal(expected, actualTranslatedUpRH), $"{nameof(Matrix4x4.CreateConstrainedBillboard)} did not return the expected value."); + + cameraPosition -= rotateAxis * 30.0f; + Matrix4x4 actualTranslatedDownRH = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); + Assert.True(MathHelper.Equal(expected, actualTranslatedDownRH), $"{nameof(Matrix4x4.CreateConstrainedBillboard)} did not return the expected value."); + + placeDirection = InverseHandedness(placeDirection); + rotateAxis = InverseHandedness(rotateAxis); + + cameraPosition = new Vector3(3.0f, 4.0f, -5.0f); + objectPosition = cameraPosition + placeDirection * 10.0f; + expected = expectedRotationLeftHanded * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualLH = Matrix4x4.CreateConstrainedBillboardLeftHanded(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), Vector3.UnitZ); + Assert.True(MathHelper.Equal(expected, actualLH), $"{nameof(Matrix4x4.CreateConstrainedBillboardLeftHanded)} did not return the expected value."); // When you move camera along rotateAxis, result must be same. cameraPosition += rotateAxis * 10.0f; - actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4 actualTranslatedUpLH = Matrix4x4.CreateConstrainedBillboardLeftHanded(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), Vector3.UnitZ); + Assert.True(MathHelper.Equal(expected, actualTranslatedUpLH), $"{nameof(Matrix4x4.CreateConstrainedBillboardLeftHanded)} did not return the expected value."); cameraPosition -= rotateAxis * 30.0f; - actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4 actualTranslatedDownLH = Matrix4x4.CreateConstrainedBillboardLeftHanded(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), Vector3.UnitZ); + Assert.True(MathHelper.Equal(expected, actualTranslatedDownLH), $"{nameof(Matrix4x4.CreateConstrainedBillboardLeftHanded)} did not return the expected value."); + + AssertEqual(actualRH, InverseHandedness(actualLH), DefaultVarianceMatrix); + AssertEqual(InverseHandedness(actualRH), actualLH, DefaultVarianceMatrix); + + AssertEqual(actualTranslatedUpRH, InverseHandedness(actualTranslatedUpLH), DefaultVarianceMatrix); + AssertEqual(InverseHandedness(actualTranslatedUpRH), actualTranslatedUpLH, DefaultVarianceMatrix); + + AssertEqual(actualTranslatedDownRH, InverseHandedness(actualTranslatedDownLH), DefaultVarianceMatrix); + AssertEqual(InverseHandedness(actualTranslatedDownRH), actualTranslatedDownLH, DefaultVarianceMatrix); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2316,7 +2465,11 @@ private void CreateConstrainedBillboardFact(Vector3 placeDirection, Vector3 rota public void Matrix4x4CreateConstrainedBillboardTest01() { // Object placed at Forward of camera. result must be same as 180 degrees rotate along y-axis. - CreateConstrainedBillboardFact(new Vector3(0, 0, -1), new Vector3(0, 1, 0), Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f))); + CreateConstrainedBillboardFact( + new Vector3(0, 0, -1), + Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2325,7 +2478,11 @@ public void Matrix4x4CreateConstrainedBillboardTest01() public void Matrix4x4CreateConstrainedBillboardTest02() { // Object placed at Backward of camera. This result must be same as 0 degrees rotate along y-axis. - CreateConstrainedBillboardFact(new Vector3(0, 0, 1), new Vector3(0, 1, 0), Matrix4x4.CreateRotationY(MathHelper.ToRadians(0))); + CreateConstrainedBillboardFact( + Vector3.UnitZ, + Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(0)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(0))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2334,7 +2491,11 @@ public void Matrix4x4CreateConstrainedBillboardTest02() public void Matrix4x4CreateConstrainedBillboardTest03() { // Place object at Right side of camera. This result must be same as 90 degrees rotate along y-axis. - CreateConstrainedBillboardFact(new Vector3(1, 0, 0), new Vector3(0, 1, 0), Matrix4x4.CreateRotationY(MathHelper.ToRadians(90))); + CreateConstrainedBillboardFact( + Vector3.UnitX, + Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(90)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(-90))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2343,7 +2504,11 @@ public void Matrix4x4CreateConstrainedBillboardTest03() public void Matrix4x4CreateConstrainedBillboardTest04() { // Place object at Left side of camera. This result must be same as -90 degrees rotate along y-axis. - CreateConstrainedBillboardFact(new Vector3(-1, 0, 0), new Vector3(0, 1, 0), Matrix4x4.CreateRotationY(MathHelper.ToRadians(-90))); + CreateConstrainedBillboardFact( + new Vector3(-1, 0, 0), + Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(-90)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(90))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2352,8 +2517,11 @@ public void Matrix4x4CreateConstrainedBillboardTest04() public void Matrix4x4CreateConstrainedBillboardTest05() { // Place object at Up side of camera. result must be same as 180 degrees rotate along z-axis after 90 degrees rotate along x-axis. - CreateConstrainedBillboardFact(new Vector3(0, 1, 0), new Vector3(0, 0, 1), - Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(180))); + CreateConstrainedBillboardFact( + Vector3.UnitY, + Vector3.UnitZ, + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(180)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(180))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2362,8 +2530,11 @@ public void Matrix4x4CreateConstrainedBillboardTest05() public void Matrix4x4CreateConstrainedBillboardTest06() { // Place object at Down side of camera. result must be same as 0 degrees rotate along z-axis after 90 degrees rotate along x-axis. - CreateConstrainedBillboardFact(new Vector3(0, -1, 0), new Vector3(0, 0, 1), - Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(0))); + CreateConstrainedBillboardFact( + new Vector3(0, -1, 0), + Vector3.UnitZ, + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(0)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(0))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2372,8 +2543,11 @@ public void Matrix4x4CreateConstrainedBillboardTest06() public void Matrix4x4CreateConstrainedBillboardTest07() { // Place object at Right side of camera. result must be same as 90 degrees rotate along z-axis after 90 degrees rotate along x-axis. - CreateConstrainedBillboardFact(new Vector3(1, 0, 0), new Vector3(0, 0, 1), - Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f))); + CreateConstrainedBillboardFact( + Vector3.UnitX, + Vector3.UnitZ, + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2382,8 +2556,11 @@ public void Matrix4x4CreateConstrainedBillboardTest07() public void Matrix4x4CreateConstrainedBillboardTest08() { // Place object at Left side of camera. result must be same as -90 degrees rotate along z-axis after 90 degrees rotate along x-axis. - CreateConstrainedBillboardFact(new Vector3(-1, 0, 0), new Vector3(0, 0, 1), - Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f))); + CreateConstrainedBillboardFact( + new Vector3(-1, 0, 0), + Vector3.UnitZ, + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2392,8 +2569,11 @@ public void Matrix4x4CreateConstrainedBillboardTest08() public void Matrix4x4CreateConstrainedBillboardTest09() { // Place object at Up side of camera. result must be same as -90 degrees rotate along x-axis after 90 degrees rotate along z-axis. - CreateConstrainedBillboardFact(new Vector3(0, 1, 0), new Vector3(-1, 0, 0), - Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f))); + CreateConstrainedBillboardFact( + Vector3.UnitY, + new Vector3(-1, 0, 0), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2402,8 +2582,11 @@ public void Matrix4x4CreateConstrainedBillboardTest09() public void Matrix4x4CreateConstrainedBillboardTest10() { // Place object at Down side of camera. result must be same as 90 degrees rotate along x-axis after 90 degrees rotate along z-axis. - CreateConstrainedBillboardFact(new Vector3(0, -1, 0), new Vector3(-1, 0, 0), - Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f))); + CreateConstrainedBillboardFact( + new Vector3(0, -1, 0), + new Vector3(-1, 0, 0), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2412,7 +2595,10 @@ public void Matrix4x4CreateConstrainedBillboardTest10() public void Matrix4x4CreateConstrainedBillboardTest11() { // Place object at Forward side of camera. result must be same as 180 degrees rotate along x-axis after 90 degrees rotate along z-axis. - CreateConstrainedBillboardFact(new Vector3(0, 0, -1), new Vector3(-1, 0, 0), + CreateConstrainedBillboardFact( + new Vector3(0, 0, -1), + new Vector3(-1, 0, 0), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(180.0f)), Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(180.0f))); } @@ -2422,7 +2608,10 @@ public void Matrix4x4CreateConstrainedBillboardTest11() public void Matrix4x4CreateConstrainedBillboardTest12() { // Place object at Backward side of camera. result must be same as 0 degrees rotate along x-axis after 90 degrees rotate along z-axis. - CreateConstrainedBillboardFact(new Vector3(0, 0, 1), new Vector3(-1, 0, 0), + CreateConstrainedBillboardFact( + Vector3.UnitZ, + new Vector3(-1, 0, 0), + Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(0.0f)), Matrix4x4.CreateRotationZ(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationX(MathHelper.ToRadians(0.0f))); } @@ -2433,12 +2622,23 @@ public void Matrix4x4CreateConstrainedBillboardTooCloseTest1() { Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); Vector3 cameraPosition = objectPosition; - Vector3 cameraUpVector = new Vector3(0, 1, 0); + Vector3 cameraUpVector = Vector3.UnitY; // Doesn't pass camera face direction. CreateConstrainedBillboard uses new Vector3f(0, 0, -1) direction. Result must be same as 180 degrees rotate along y-axis. Matrix4x4 expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, cameraUpVector, new Vector3(0, 0, 1), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4 actualRH = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, cameraUpVector, Vector3.UnitZ, new Vector3(0, 0, -1)); + Assert.True(MathHelper.Equal(expected, actualRH), $"{nameof(Matrix4x4.CreateConstrainedBillboard)} did not return the expected value."); + + objectPosition = new Vector3(3.0f, 4.0f, -5.0f); + cameraPosition = objectPosition; + cameraUpVector = Vector3.UnitY; + + expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)) * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualLH = Matrix4x4.CreateConstrainedBillboardLeftHanded(objectPosition, cameraPosition, cameraUpVector, new Vector3(0, 0, -1), Vector3.UnitZ); + Assert.True(MathHelper.Equal(expected, actualLH), $"{nameof(Matrix4x4.CreateConstrainedBillboardLeftHanded)} did not return the expected value."); + + AssertEqual(actualRH, InverseHandedness(actualLH), DefaultVarianceMatrix); + AssertEqual(InverseHandedness(actualRH), actualLH, DefaultVarianceMatrix); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2448,28 +2648,60 @@ public void Matrix4x4CreateConstrainedBillboardTooCloseTest2() { Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); Vector3 cameraPosition = objectPosition; - Vector3 cameraUpVector = new Vector3(0, 1, 0); + Vector3 cameraUpVector = Vector3.UnitY; // Passes Vector3f.Right as camera face direction. Result must be same as -90 degrees rotate along y-axis. Matrix4x4 expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, cameraUpVector, new Vector3(1, 0, 0), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4 actualRH = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, cameraUpVector, Vector3.UnitX, new Vector3(0, 0, -1)); + Assert.True(MathHelper.Equal(expected, actualRH), $"{nameof(Matrix4x4.CreateConstrainedBillboard)} did not return the expected value."); + + objectPosition = new Vector3(3.0f, 4.0f, -5.0f); + cameraPosition = objectPosition; + cameraUpVector = Vector3.UnitY; + + expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualLH = Matrix4x4.CreateConstrainedBillboardLeftHanded(objectPosition, cameraPosition, cameraUpVector, Vector3.UnitX, Vector3.UnitZ); + Assert.True(MathHelper.Equal(expected, actualLH), $"{nameof(Matrix4x4.CreateConstrainedBillboardLeftHanded)} did not return the expected value."); + + AssertEqual(actualRH, InverseHandedness(actualLH), DefaultVarianceMatrix); + AssertEqual(InverseHandedness(actualRH), actualLH, DefaultVarianceMatrix); } - // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) - // Angle between rotateAxis and camera to object vector is too small. And use doesn't passed objectForwardVector parameter. - [Fact] - public void Matrix4x4CreateConstrainedBillboardAlongAxisTest1() + private static void Matrix4x4CreateConstrainedBillboardAlongAxisFact(Vector3 rotateAxis, Vector3 cameraForward, Vector3 objectForward, Matrix4x4 expectedRotationRightHanded, Matrix4x4 expectedRotationLeftHanded) { // Place camera at up side of object. Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); - Vector3 rotateAxis = new Vector3(0, 1, 0); Vector3 cameraPosition = objectPosition + rotateAxis * 10.0f; + Matrix4x4 expected = expectedRotationRightHanded * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualLH = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, cameraForward, objectForward); + Assert.True(MathHelper.Equal(expected, actualLH), $"{nameof(Matrix4x4.CreateConstrainedBillboard)} did not return the expected value."); + + rotateAxis = InverseHandedness(rotateAxis); + cameraForward = InverseHandedness(cameraForward); + objectForward = InverseHandedness(objectForward); + + objectPosition = new Vector3(3.0f, 4.0f, -5.0f); + cameraPosition = objectPosition + rotateAxis * 10.0f; + + expected = expectedRotationLeftHanded * Matrix4x4.CreateTranslation(objectPosition); + Matrix4x4 actualRH = Matrix4x4.CreateConstrainedBillboardLeftHanded(objectPosition, cameraPosition, rotateAxis, cameraForward, objectForward); + Assert.True(MathHelper.Equal(expected, actualRH), $"{nameof(Matrix4x4.CreateConstrainedBillboardLeftHanded)} did not return the expected value."); + + AssertEqual(actualRH, InverseHandedness(actualLH), DefaultVarianceMatrix); + AssertEqual(InverseHandedness(actualRH), actualLH, DefaultVarianceMatrix); + } + + // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) + // Angle between rotateAxis and camera to object vector is too small. And use doesn't passed objectForwardVector parameter. + [Fact] + public void Matrix4x4CreateConstrainedBillboardAlongAxisTest1() + { // In this case, CreateConstrainedBillboard picks new Vector3f(0, 0, -1) as object forward vector. - Matrix4x4 expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4CreateConstrainedBillboardAlongAxisFact( + Vector3.UnitY, new Vector3(0, 0, -1), new Vector3(0, 0, -1), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2477,15 +2709,11 @@ public void Matrix4x4CreateConstrainedBillboardAlongAxisTest1() [Fact] public void Matrix4x4CreateConstrainedBillboardAlongAxisTest2() { - // Place camera at up side of object. - Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); - Vector3 rotateAxis = new Vector3(0, 0, -1); - Vector3 cameraPosition = objectPosition + rotateAxis * 10.0f; - // In this case, CreateConstrainedBillboard picks new Vector3f(1, 0, 0) as object forward vector. - Matrix4x4 expected = Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4CreateConstrainedBillboardAlongAxisFact( + new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector3(0, 0, -1), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2493,15 +2721,11 @@ public void Matrix4x4CreateConstrainedBillboardAlongAxisTest2() [Fact] public void Matrix4x4CreateConstrainedBillboardAlongAxisTest3() { - // Place camera at up side of object. - Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); - Vector3 rotateAxis = new Vector3(0, 1, 0); - Vector3 cameraPosition = objectPosition + rotateAxis * 10.0f; - // User passes correct objectForwardVector. - Matrix4x4 expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4CreateConstrainedBillboardAlongAxisFact( + Vector3.UnitY, new Vector3(0, 0, -1), new Vector3(0, 0, -1), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2509,15 +2733,11 @@ public void Matrix4x4CreateConstrainedBillboardAlongAxisTest3() [Fact] public void Matrix4x4CreateConstrainedBillboardAlongAxisTest4() { - // Place camera at up side of object. - Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); - Vector3 rotateAxis = new Vector3(0, 1, 0); - Vector3 cameraPosition = objectPosition + rotateAxis * 10.0f; - // User passes correct objectForwardVector. - Matrix4x4 expected = Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 1, 0)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4CreateConstrainedBillboardAlongAxisFact( + Vector3.UnitY, new Vector3(0, 0, -1), Vector3.UnitY, + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f)), + Matrix4x4.CreateRotationY(MathHelper.ToRadians(180.0f))); } // A test for CreateConstrainedBillboard (Vector3f, Vector3f, Vector3f, Vector3f?) @@ -2525,15 +2745,11 @@ public void Matrix4x4CreateConstrainedBillboardAlongAxisTest4() [Fact] public void Matrix4x4CreateConstrainedBillboardAlongAxisTest5() { - // Place camera at up side of object. - Vector3 objectPosition = new Vector3(3.0f, 4.0f, 5.0f); - Vector3 rotateAxis = new Vector3(0, 0, -1); - Vector3 cameraPosition = objectPosition + rotateAxis * 10.0f; - // In this case, CreateConstrainedBillboard picks Vector3f.Right as object forward vector. - Matrix4x4 expected = Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateTranslation(objectPosition); - Matrix4x4 actual = Matrix4x4.CreateConstrainedBillboard(objectPosition, cameraPosition, rotateAxis, new Vector3(0, 0, -1), new Vector3(0, 0, -1)); - Assert.True(MathHelper.Equal(expected, actual), "Matrix4x4.CreateConstrainedBillboard did not return the expected value."); + Matrix4x4CreateConstrainedBillboardAlongAxisFact( + new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector3(0, 0, -1), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(-90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f)), + Matrix4x4.CreateRotationX(MathHelper.ToRadians(90.0f)) * Matrix4x4.CreateRotationZ(MathHelper.ToRadians(-90.0f))); } // A test for CreateScale (Vector3f) diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 61d304184b2865..064e2579bdca3c 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -2608,6 +2608,7 @@ + @@ -2640,6 +2641,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs index 33f5998a96248c..c73d407b1c7f5c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs @@ -3,10 +3,6 @@ namespace System.Diagnostics { - // This class uses high-resolution performance counter if the installed - // hardware supports it. Otherwise, the class will fall back to DateTime - // and uses ticks as a measurement. - [DebuggerDisplay("{DebuggerDisplay,nq}")] public partial class Stopwatch { @@ -14,21 +10,15 @@ public partial class Stopwatch private long _startTimeStamp; private bool _isRunning; - // "Frequency" stores the frequency of the high-resolution performance counter, - // if one exists. Otherwise it will store TicksPerSecond. - // The frequency cannot change while the system is running, - // so we only need to initialize it once. public static readonly long Frequency = QueryPerformanceFrequency(); public static readonly bool IsHighResolution = true; // performance-counter frequency, in counts per ticks. - // This can speed up conversion from high frequency performance-counter - // to ticks. + // This can speed up conversion to ticks. private static readonly double s_tickFrequency = (double)TimeSpan.TicksPerSecond / Frequency; public Stopwatch() { - Reset(); } public void Start() @@ -43,7 +33,7 @@ public void Start() public static Stopwatch StartNew() { - Stopwatch s = new Stopwatch(); + Stopwatch s = new(); s.Start(); return s; } @@ -53,29 +43,16 @@ public void Stop() // Calling stop on a stopped Stopwatch is a no-op. if (_isRunning) { - long endTimeStamp = GetTimestamp(); - long elapsedThisPeriod = endTimeStamp - _startTimeStamp; - _elapsed += elapsedThisPeriod; + _elapsed += GetTimestamp() - _startTimeStamp; _isRunning = false; - - if (_elapsed < 0) - { - // When measuring small time periods the Stopwatch.Elapsed* - // properties can return negative values. This is due to - // bugs in the basic input/output system (BIOS) or the hardware - // abstraction layer (HAL) on machines with variable-speed CPUs - // (e.g. Intel SpeedStep). - - _elapsed = 0; - } } } public void Reset() { _elapsed = 0; - _isRunning = false; _startTimeStamp = 0; + _isRunning = false; } // Convenience method for replacing {sw.Reset(); sw.Start();} with a single sw.Restart() @@ -94,32 +71,30 @@ public void Restart() /// public override string ToString() => Elapsed.ToString(); - public bool IsRunning - { - get { return _isRunning; } - } + public bool IsRunning => _isRunning; - public TimeSpan Elapsed - { - get { return new TimeSpan(GetElapsedDateTimeTicks()); } - } + public TimeSpan Elapsed => new(ElapsedTimeSpanTicks); - public long ElapsedMilliseconds - { - get { return GetElapsedDateTimeTicks() / TimeSpan.TicksPerMillisecond; } - } + public long ElapsedMilliseconds => ElapsedTimeSpanTicks / TimeSpan.TicksPerMillisecond; public long ElapsedTicks { - get { return GetRawElapsedTicks(); } - } + get + { + long timeElapsed = _elapsed; - public static long GetTimestamp() - { - Debug.Assert(IsHighResolution); - return QueryPerformanceCounter(); + // If the Stopwatch is running, add elapsed time since the Stopwatch is started last time. + if (_isRunning) + { + timeElapsed += GetTimestamp() - _startTimeStamp; + } + + return timeElapsed; + } } + public static long GetTimestamp() => QueryPerformanceCounter(); + /// Gets the elapsed time since the value retrieved using . /// The timestamp marking the beginning of the time period. /// A for the elapsed time between the starting timestamp and the time of this call. @@ -131,31 +106,9 @@ public static TimeSpan GetElapsedTime(long startingTimestamp) => /// The timestamp marking the end of the time period. /// A for the elapsed time between the starting and ending timestamps. public static TimeSpan GetElapsedTime(long startingTimestamp, long endingTimestamp) => - new TimeSpan((long)((endingTimestamp - startingTimestamp) * s_tickFrequency)); - - // Get the elapsed ticks. - private long GetRawElapsedTicks() - { - long timeElapsed = _elapsed; + new((long)((endingTimestamp - startingTimestamp) * s_tickFrequency)); - if (_isRunning) - { - // If the Stopwatch is running, add elapsed time since - // the Stopwatch is started last time. - long currentTimeStamp = GetTimestamp(); - long elapsedUntilNow = currentTimeStamp - _startTimeStamp; - timeElapsed += elapsedUntilNow; - } - return timeElapsed; - } - - // Get the elapsed ticks. - private long GetElapsedDateTimeTicks() - { - Debug.Assert(IsHighResolution); - // convert high resolution perf counter to DateTime ticks - return unchecked((long)(GetRawElapsedTicks() * s_tickFrequency)); - } + private long ElapsedTimeSpanTicks => (long)(ElapsedTicks * s_tickFrequency); private string DebuggerDisplay => $"{Elapsed} (IsRunning = {_isRunning})"; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Marvin.cs b/src/libraries/System.Private.CoreLib/src/System/Marvin.cs index 098ebb5260dc9d..31c1b696a68017 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Marvin.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Marvin.cs @@ -6,6 +6,12 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +#if SYSTEM_PRIVATE_CORELIB +using static System.Numerics.BitOperations; +#else +using System.Security.Cryptography; +#endif + namespace System { internal static partial class Marvin @@ -204,7 +210,7 @@ public static int ComputeHash32(ref byte data, uint count, uint p0, uint p1) else { partialResult |= (uint)Unsafe.ReadUnaligned(ref data); - partialResult = BitOperations.RotateLeft(partialResult, 16); + partialResult = RotateLeft(partialResult, 16); } } @@ -221,16 +227,16 @@ private static void Block(ref uint rp0, ref uint rp1) uint p1 = rp1; p1 ^= p0; - p0 = BitOperations.RotateLeft(p0, 20); + p0 = RotateLeft(p0, 20); p0 += p1; - p1 = BitOperations.RotateLeft(p1, 9); + p1 = RotateLeft(p1, 9); p1 ^= p0; - p0 = BitOperations.RotateLeft(p0, 27); + p0 = RotateLeft(p0, 27); p0 += p1; - p1 = BitOperations.RotateLeft(p1, 19); + p1 = RotateLeft(p1, 19); rp0 = p0; rp1 = p1; @@ -241,8 +247,29 @@ private static void Block(ref uint rp0, ref uint rp1) private static unsafe ulong GenerateSeed() { ulong seed; +#if SYSTEM_PRIVATE_CORELIB Interop.GetRandomBytes((byte*)&seed, sizeof(ulong)); +#else + byte[] seedBytes = new byte[sizeof(ulong)]; + using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) + { + rng.GetBytes(seedBytes); + fixed (byte* b = seedBytes) + { + seed = *(ulong*)b; + } + } +#endif return seed; } + +#if !SYSTEM_PRIVATE_CORELIB + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static uint RotateLeft(uint value, int shift) + { + // This is expected to be optimized into a single rol (or ror with negated shift value) instruction + return (value << shift) | (value >> (32 - shift)); + } +#endif } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs index 889311ca073028..5ca3cfeb40cc6b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs @@ -214,8 +214,12 @@ public Vector3 Translation [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Impl CreateBillboard(in Vector3 objectPosition, in Vector3 cameraPosition, in Vector3 cameraUpVector, in Vector3 cameraForwardVector) { + // In a right-handed coordinate system, the object's positive z-axis is in the opposite direction as its forward vector, + // and spherical billboards by construction always face the camera. Vector3 axisZ = objectPosition - cameraPosition; + // When object and camera position are approximately the same, the object should just face the + // same direction as the camera is facing. if (axisZ.LengthSquared() < BillboardEpsilon) { axisZ = -cameraForwardVector; @@ -232,7 +236,38 @@ public static Impl CreateBillboard(in Vector3 objectPosition, in Vector3 cameraP result.X = axisX.AsVector4(); result.Y = axisY.AsVector4(); - result.Z = axisZ.AsVector4();; + result.Z = axisZ.AsVector4(); + result.W = Vector4.Create(objectPosition, 1); + + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Impl CreateBillboardLeftHanded(in Vector3 objectPosition, in Vector3 cameraPosition, in Vector3 cameraUpVector, in Vector3 cameraForwardVector) + { + // In a left-handed coordinate system, the object's positive z-axis is in the same direction as its forward vector, + // and spherical billboards by construction always face the camera. + Vector3 axisZ = cameraPosition - objectPosition; + + // When object and camera position are approximately the same, the object should just face the + // same direction as the camera is facing. + if (axisZ.LengthSquared() < BillboardEpsilon) + { + axisZ = cameraForwardVector; + } + else + { + axisZ = Vector3.Normalize(axisZ); + } + + Vector3 axisX = Vector3.Normalize(Vector3.Cross(cameraUpVector, axisZ)); + Vector3 axisY = Vector3.Cross(axisZ, axisX); + + Impl result; + + result.X = axisX.AsVector4(); + result.Y = axisY.AsVector4(); + result.Z = axisZ.AsVector4(); result.W = Vector4.Create(objectPosition, 1); return result; @@ -241,9 +276,12 @@ public static Impl CreateBillboard(in Vector3 objectPosition, in Vector3 cameraP [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Impl CreateConstrainedBillboard(in Vector3 objectPosition, in Vector3 cameraPosition, in Vector3 rotateAxis, in Vector3 cameraForwardVector, in Vector3 objectForwardVector) { - // Treat the case when object and camera positions are too close. + // First find the Z-axis of the spherical/unconstrained rotation. We call this faceDir and in a right-handed coordinate system + // it will be in the opposite direction as from the object to the camera. Vector3 faceDir = objectPosition - cameraPosition; + // When object and camera position are approximately the same this indicates that the object should also just face the + // same direction as the camera is facing. if (faceDir.LengthSquared() < BillboardEpsilon) { faceDir = -cameraForwardVector; @@ -255,18 +293,30 @@ public static Impl CreateConstrainedBillboard(in Vector3 objectPosition, in Vect Vector3 axisY = rotateAxis; - // Treat the case when angle between faceDir and rotateAxis is too close to 0. float dot = Vector3.Dot(axisY, faceDir); + // Generally the approximation for small angles is cos theta = 1 - theta^2 / 2, + // but it seems that here we are using cos theta = 1 - theta. Letting theta be the angle + // between the rotate axis and the faceDir, + // + // dot = cos theta ~ 1 - theta > 1 - .1 * pi/180 = 1 - (.1 degree) => theta < .1 degree + // + // So this condition checks if the faceDir is approximately the same as the rotate axis + // by checking if the angle between them is less than .1 degree. if (float.Abs(dot) > BillboardMinAngle) { + // If the faceDir is approximately the same as the rotate axis, then fallback to using object forward vector + // as the faceDir. faceDir = objectForwardVector; - // Make sure passed values are useful for compute. dot = Vector3.Dot(axisY, faceDir); + // Similar to before, check if the faceDir is still is approximately the rotate axis. + // If so, then use either -UnitZ or UnitX as the fallback faceDir. if (float.Abs(dot) > BillboardMinAngle) { + // |axisY.Z| = |dot(axisY, -UnitZ)|, so this is checking if the rotate axis is approximately the same as -UnitZ. + // If is, then use UnitX as the fallback. faceDir = (float.Abs(axisY.Z) > BillboardMinAngle) ? Vector3.UnitX : Vector3.Create(0, 0, -1); } } @@ -284,6 +334,66 @@ public static Impl CreateConstrainedBillboard(in Vector3 objectPosition, in Vect return result; } + public static Impl CreateConstrainedBillboardLeftHanded(in Vector3 objectPosition, in Vector3 cameraPosition, in Vector3 rotateAxis, in Vector3 cameraForwardVector, in Vector3 objectForwardVector) + { + // First find the Z-axis of the spherical/unconstrained rotation. We call this faceDir and in a left-handed coordinate system + // it will be in the same direction as from the object to the camera. + Vector3 faceDir = cameraPosition - objectPosition; + + // When object and camera position are approximately the same this indicates that the object should also just face the + // same direction as the camera is facing. + if (faceDir.LengthSquared() < BillboardEpsilon) + { + faceDir = cameraForwardVector; + } + else + { + faceDir = Vector3.Normalize(faceDir); + } + + Vector3 axisY = rotateAxis; + + float dot = Vector3.Dot(axisY, faceDir); + + // Generally the approximation for small angles is cos theta = 1 - theta^2 / 2, + // but it seems that here we are using cos theta = 1 - theta. Letting theta be the angle + // between the rotate axis and the faceDir, + // + // dot = cos theta ~ 1 - theta > 1 - .1 * pi/180 = 1 - (.1 degree) => theta < .1 degree + // + // So this condition checks if the faceDir is approximately the same as the rotate axis + // by checking if the angle between them is less than .1 degree. + if (float.Abs(dot) > BillboardMinAngle) + { + // If the faceDir is approximately the same as the rotate axis, then fallback to using object forward vector + // as the faceDir. + faceDir = -objectForwardVector; + + dot = Vector3.Dot(axisY, faceDir); + + // Similar to before, check if the faceDir is still is approximately the rotate axis. + // If so, then use either -UnitZ or -UnitX as the fallback faceDir. + if (float.Abs(dot) > BillboardMinAngle) + { + // |axisY.Z| = |dot(axisY, -UnitZ)|, so this is checking if the rotate axis is approximately the same as -UnitZ. + // If is, then use -UnitX as the fallback. + faceDir = (float.Abs(axisY.Z) > BillboardMinAngle) ? Vector3.Create(-1, 0, 0) : Vector3.Create(0, 0, -1); + } + } + + Vector3 axisX = Vector3.Normalize(Vector3.Cross(axisY, faceDir)); + Vector3 axisZ = Vector3.Normalize(Vector3.Cross(axisX, axisY)); + + Impl result; + + result.X = axisX.AsVector4(); + result.Y = axisY.AsVector4(); + result.Z = axisZ.AsVector4(); + result.W = Vector4.Create(objectPosition, 1); + + return result; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Impl CreateFromAxisAngle(in Vector3 axis, float angle) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs index 22774a5b3a10cc..7e92e304ef9c2b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs @@ -224,7 +224,7 @@ public Vector3 Translation public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2) => (value1.AsImpl() + value2.AsImpl()).AsM4x4(); - /// Creates a spherical billboard that rotates around a specified object position. + /// Creates a right-handed spherical billboard matrix that rotates around a specified object position. /// The position of the object that the billboard will rotate around. /// The position of the camera. /// The up vector of the camera. @@ -233,7 +233,16 @@ public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2) public static Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector) => Impl.CreateBillboard(in objectPosition, in cameraPosition, in cameraUpVector, in cameraForwardVector).AsM4x4(); - /// Creates a cylindrical billboard that rotates around a specified axis. + /// Creates a left-handed spherical billboard matrix that rotates around a specified object position. + /// The position of the object that the billboard will rotate around. + /// The position of the camera. + /// The up vector of the camera. + /// The forward vector of the camera. + /// The created billboard. + public static Matrix4x4 CreateBillboardLeftHanded(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector) + => Impl.CreateBillboardLeftHanded(in objectPosition, in cameraPosition, in cameraUpVector, in cameraForwardVector).AsM4x4(); + + /// Creates a right-handed cylindrical billboard matrix that rotates around a specified axis. /// The position of the object that the billboard will rotate around. /// The position of the camera. /// The axis to rotate the billboard around. @@ -243,6 +252,16 @@ public static Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPo public static Matrix4x4 CreateConstrainedBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 rotateAxis, Vector3 cameraForwardVector, Vector3 objectForwardVector) => Impl.CreateConstrainedBillboard(in objectPosition, in cameraPosition, in rotateAxis, in cameraForwardVector, in objectForwardVector).AsM4x4(); + /// Creates a left-handed cylindrical billboard matrix that rotates around a specified axis. + /// The position of the object that the billboard will rotate around. + /// The position of the camera. + /// The axis to rotate the billboard around. + /// The forward vector of the camera. + /// The forward vector of the object. + /// The billboard matrix. + public static Matrix4x4 CreateConstrainedBillboardLeftHanded(Vector3 objectPosition, Vector3 cameraPosition, Vector3 rotateAxis, Vector3 cameraForwardVector, Vector3 objectForwardVector) + => Impl.CreateConstrainedBillboardLeftHanded(in objectPosition, in cameraPosition, in rotateAxis, in cameraForwardVector, in objectForwardVector).AsM4x4(); + /// Creates a matrix that rotates around an arbitrary vector. /// The axis to rotate around. /// The angle to rotate around , in radians. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx10v2.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx10v2.PlatformNotSupported.cs new file mode 100644 index 00000000000000..bea42e51167f55 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx10v2.PlatformNotSupported.cs @@ -0,0 +1,327 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; + +namespace System.Runtime.Intrinsics.X86 +{ + /// Provides access to X86 Avx10.2 hardware instructions via intrinsics. + [CLSCompliant(false)] + public abstract class Avx10v2 : Avx10v1 + { + internal Avx10v2() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { [Intrinsic] get { return false; } } + + /// + /// VMINMAXPD xmm1{k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 MinMax(Vector128 left, Vector128 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// VMINMAXPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {sae}, imm8 + /// + public static Vector256 MinMax(Vector256 left, Vector256 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// VMINMAXPS xmm1{k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 MinMax(Vector128 left, Vector128 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// VMINMAXPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {sae}, imm8 + /// + public static Vector256 MinMax(Vector256 left, Vector256 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// VMINMAXSD xmm1{k1}{z}, xmm2, xmm3/m64 {sae}, imm8 + /// + public static Vector128 MinMaxScalar(Vector128 left, Vector128 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// VMINMAXSS xmm1{k1}{z}, xmm2, xmm3/m32 {sae}, imm8 + /// + public static Vector128 MinMaxScalar(Vector128 left, Vector128 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// VADDPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Add(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VADDPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Add(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VDIVPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Divide(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VDIVPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Divide(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IBS xmm1{k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IBS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IBS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IUBS xmm1{k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IUBS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IUBS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTTPS2IBS xmm1{k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTTPS2IBS ymm1{k1}{z}, ymm2/m256/m32bcst {sae} + /// + public static Vector256 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTTPS2IUBS xmm1{k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTTPS2IUBS ymm1{k1}{z}, ymm2/m256/m32bcst {sae} + /// + public static Vector256 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// VMOVD xmm1, xmm2/m32 + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// VMOVW xmm1, xmm2/m16 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTDQ2PS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToVector256Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPD2DQ xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128Int32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPD2PS xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPD2QQ ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 ConvertToVector256Int64(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPD2UDQ xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128UInt32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPD2UQQ ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 ConvertToVector256UInt64(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2DQ ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToVector256Int32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2QQ ymm1{k1}{z}, xmm2/m128/m32bcst {er} + /// + public static Vector256 ConvertToVector256Int64(Vector128 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2UDQ ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToVector256UInt32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2UQQ ymm1{k1}{z}, xmm2/m128/m32bcst {er} + /// + public static Vector256 ConvertToVector256UInt64(Vector128 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTQQ2PS xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTQQ2PD ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 ConvertToVector256Double(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTUDQ2PS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToVector256Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTUQQ2PS xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTUQQ2PD ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 ConvertToVector256Double(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VMULPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Multiply(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VMULPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Multiply(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VSCALEFPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Scale(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VSCALEFPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Scale(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VSQRTPD ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 Sqrt(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VSQRTPS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 Sqrt(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VSUBPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Subtract(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VSUBPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Subtract(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// Provides access to the x86 AVX10.2 hardware instructions, that are only available to 64-bit processes, via intrinsics. + public new abstract class X64 : Avx10v1.X64 + { + internal X64() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { [Intrinsic] get { return false; } } + + } + + /// Provides access to the x86 AVX10.2/512 hardware instructions via intrinsics. + public new abstract class V512 : Avx10v1.V512 + { + internal V512() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { [Intrinsic] get { return false; } } + + /// + /// VMINMAXPD zmm1{k1}{z}, zmm2, zmm3/m512/m64bcst {sae}, imm8 + /// + public static Vector512 MinMax(Vector512 left, Vector512 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// VMINMAXPS zmm1{k1}{z}, zmm2, zmm3/m512/m32bcst {sae}, imm8 + /// + public static Vector512 MinMax(Vector512 left, Vector512 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IBS zmm1{k1}{z}, zmm2/m512/m32bcst {er} + /// + public static Vector512 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IBS zmm1{k1}{z}, zmm2/m512/m32bcst {er} + /// + public static Vector512 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector512 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IUBS zmm1{k1}{z}, zmm2/m512/m32bcst {er} + /// + public static Vector512 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTPS2IUBS zmm1{k1}{z}, zmm2/m512/m32bcst {er} + /// + public static Vector512 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector512 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTTPS2IUBS zmm1{k1}{z}, zmm2/m512/m32bcst {sae} + /// + public static Vector512 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// VCVTTPS2IUBS zmm1{k1}{z}, zmm2/m512/m32bcst {sae} + /// + public static Vector512 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// VMPSADBW zmm1{k1}{z}, zmm2, zmm3/m512, imm8 + /// + public static Vector512 MultipleSumAbsoluteDifferences(Vector512 left, Vector512 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + + /// Provides access to the x86 AVX10.1/512 hardware instructions, that are only available to 64-bit processes, via intrinsics. + [Intrinsic] + public new abstract class X64 : Avx10v1.V512.X64 + { + internal X64() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { [Intrinsic] get { return false; } } + } + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx10v2.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx10v2.cs new file mode 100644 index 00000000000000..5c9cba0625fd5c --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx10v2.cs @@ -0,0 +1,327 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace System.Runtime.Intrinsics.X86 +{ + /// Provides access to X86 AVX10.2 hardware instructions via intrinsics + [Intrinsic] + [CLSCompliant(false)] + public abstract class Avx10v2 : Avx10v1 + { + internal Avx10v2() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + + /// + /// VMINMAXPD xmm1{k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 MinMax(Vector128 left, Vector128 right, [ConstantExpected] byte control) => MinMax(left, right, control); + + /// + /// VMINMAXPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {sae}, imm8 + /// + public static Vector256 MinMax(Vector256 left, Vector256 right, [ConstantExpected] byte control) => MinMax(left, right, control); + + /// + /// VMINMAXPS xmm1{k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 MinMax(Vector128 left, Vector128 right, [ConstantExpected] byte control) => MinMax(left, right, control); + + /// + /// VMINMAXPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {sae}, imm8 + /// + public static Vector256 MinMax(Vector256 left, Vector256 right, [ConstantExpected] byte control) => MinMax(left, right, control); + + /// + /// VMINMAXSD xmm1{k1}{z}, xmm2, xmm3/m64 {sae}, imm8 + /// + public static Vector128 MinMaxScalar(Vector128 left, Vector128 right, [ConstantExpected] byte control) => MinMaxScalar(left, right, control); + + /// + /// VMINMAXSS xmm1{k1}{z}, xmm2, xmm3/m32 {sae}, imm8 + /// + public static Vector128 MinMaxScalar(Vector128 left, Vector128 right, [ConstantExpected] byte control) => MinMaxScalar(left, right, control); + + /// + /// VCVTPS2IBS xmm1{k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector128 value) => ConvertToSByteWithSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTPS2IBS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector256 value) => ConvertToSByteWithSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTPS2IBS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToSByteWithSaturationAndZeroExtendToInt32(value, mode); + + /// + /// VCVTPS2IUBS xmm1{k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector128 value) => ConvertToByteWithSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTPS2IUBS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector256 value) => ConvertToByteWithSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTPS2IUBS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToByteWithSaturationAndZeroExtendToInt32(value, mode); + + /// + /// VCVTTPS2IBS xmm1{k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(Vector128 value) => ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTTPS2IBS ymm1{k1}{z}, ymm2/m256/m32bcst {sae} + /// + public static Vector256 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(Vector256 value) => ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTTPS2IUBS xmm1{k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(Vector128 value) => ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTTPS2IUBS ymm1{k1}{z}, ymm2/m256/m32bcst {sae} + /// + public static Vector256 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(Vector256 value) => ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(value); + + /// + /// VMOVD xmm1, xmm2/m32 + /// + public static Vector128 ConvertToVector128UInt32(Vector128 value) => ConvertToVector128UInt32(value); + + /// + /// VMOVW xmm1, xmm2/m16 + /// + public static Vector128 ConvertToVector128UInt16(Vector128 value) => ConvertToVector128UInt16(value); + + /// + /// VADDPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Add(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Add(left, right, mode); + + /// + /// VADDPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Add(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Add(left, right, mode); + + /// + /// VDIVPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Divide(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Divide(left, right, mode); + + /// + /// VDIVPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Divide(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Divide(left, right, mode); + + /// + /// VCVTDQ2PS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToVector256Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256Single(value, mode); + + /// + /// VCVTPD2DQ xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128Int32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector128Int32(value, mode); + + /// + /// VCVTPD2PS xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector128Single(value, mode); + + /// + /// VCVTPD2QQ ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 ConvertToVector256Int64(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256Int64(value, mode); + + /// + /// VCVTPD2UDQ xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128UInt32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector128UInt32(value, mode); + + /// + /// VCVTPD2UQQ ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 ConvertToVector256UInt64(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256UInt64(value, mode); + + /// + /// VCVTPS2DQ ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToVector256Int32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256Int32(value, mode); + + /// + /// VCVTPS2QQ ymm1{k1}{z}, xmm2/m128/m32bcst {er} + /// + public static Vector256 ConvertToVector256Int64(Vector128 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256Int64(value, mode); + + /// + /// VCVTPS2UDQ ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToVector256UInt32(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256UInt32(value, mode); + + /// + /// VCVTPS2UQQ ymm1{k1}{z}, xmm2/m128/m32bcst {er} + /// + public static Vector256 ConvertToVector256UInt64(Vector128 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256UInt64(value, mode); + + /// + /// VCVTQQ2PS xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector128Single(value, mode); + + /// + /// VCVTQQ2PD ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 ConvertToVector256Double(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256Double(value, mode); + + /// + /// VCVTUDQ2PS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 ConvertToVector256Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256Single(value, mode); + + /// + /// VCVTUQQ2PS xmm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector128 ConvertToVector128Single(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector128Single(value, mode); + + /// + /// VCVTUQQ2PD ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 ConvertToVector256Double(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToVector256Double(value, mode); + + /// + /// VMULPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Multiply(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Multiply(left, right, mode); + + /// + /// VMULPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Multiply(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Multiply(left, right, mode); + + /// + /// VSCALEFPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Scale(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Scale(left, right, mode); + + /// + /// VSCALEFPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Scale(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Scale(left, right, mode); + + /// + /// VSQRTPD ymm1{k1}{z}, ymm2/m256/m64bcst {er} + /// + public static Vector256 Sqrt(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Sqrt(value, mode); + + /// + /// VSQRTPS ymm1{k1}{z}, ymm2/m256/m32bcst {er} + /// + public static Vector256 Sqrt(Vector256 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Sqrt(value, mode); + + /// + /// VSUBPD ymm1{k1}{z}, ymm2, ymm3/m256/m64bcst {er} + /// + public static Vector256 Subtract(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Subtract(left, right, mode); + + /// + /// VSUBPS ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst {er} + /// + public static Vector256 Subtract(Vector256 left, Vector256 right, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => Subtract(left, right, mode); + + /// Provides access to the x86 AVX10.2 hardware instructions, that are only available to 64-bit processes, via intrinsics. + [Intrinsic] + public new abstract class X64 : Avx10v1.X64 + { + internal X64() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + } + + /// Provides access to the x86 AVX10.2/512 hardware instructions via intrinsics. + [Intrinsic] + public new abstract class V512 : Avx10v1.V512 + { + internal V512() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + + /// + /// VMINMAXPD zmm1{k1}{z}, zmm2, zmm3/m512/m64bcst {sae}, imm8 + /// + public static Vector512 MinMax(Vector512 left, Vector512 right, [ConstantExpected] byte control) => MinMax(left, right, control); + + /// + /// VMINMAXPS zmm1{k1}{z}, zmm2, zmm3/m512/m32bcst {sae}, imm8 + /// + public static Vector512 MinMax(Vector512 left, Vector512 right, [ConstantExpected] byte control) => MinMax(left, right, control); + + /// + /// VCVTPS2IBS zmm1{k1}{z}, zmm2/m512/m32bcst {er} + /// + public static Vector512 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector512 value) => ConvertToSByteWithSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTPS2IBS zmm1{k1}{z}, zmm2/m512/m32bcst {er} + /// + public static Vector512 ConvertToSByteWithSaturationAndZeroExtendToInt32(Vector512 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToSByteWithSaturationAndZeroExtendToInt32(value, mode); + + /// + /// VCVTPS2IUBS zmm1{k1}{z}, zmm2/m512/m32bcst {er} + /// + public static Vector512 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector512 value) => ConvertToByteWithSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTPS2IUBS zmm1{k1}{z}, zmm2/m512/m32bcst {er} + /// + public static Vector512 ConvertToByteWithSaturationAndZeroExtendToInt32(Vector512 value, [ConstantExpected(Max = FloatRoundingMode.ToZero)] FloatRoundingMode mode) => ConvertToByteWithSaturationAndZeroExtendToInt32(value, mode); + + /// + /// VCVTTPS2IBS zmm1{k1}{z}, zmm2/m512/m32bcst {sae} + /// + public static Vector512 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(Vector512 value) => ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(value); + + /// + /// VCVTTPS2IUBS zmm1{k1}{z}, zmm2/m512/m32bcst {sae} + /// + public static Vector512 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(Vector512 value) => ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(value); + + /// + /// VMPSADBW zmm1{k1}{z}, zmm2, zmm3/m512, imm8 + /// + public static Vector512 MultipleSumAbsoluteDifferences(Vector512 left, Vector512 right, [ConstantExpected] byte mask) => MultipleSumAbsoluteDifferences(left, right, mask); + + /// Provides access to the x86 AVX10.2/512 hardware instructions, that are only available to 64-bit processes, via intrinsics. + [Intrinsic] + public new abstract class X64 : Avx10v1.V512.X64 + { + internal X64() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + } + } + } +} diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 1da0bf8ed49588..59a245ff13b587 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -7174,6 +7174,83 @@ internal X64() { } } } + [System.CLSCompliantAttribute(false)] + public abstract partial class Avx10v2 : System.Runtime.Intrinsics.X86.Avx10v1 + { + internal Avx10v2() { } + public static new bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector128 MinMax(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 MinMax(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 MinMax(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 MinMax(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 MinMaxScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [ConstantExpected] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 MinMaxScalar(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [ConstantExpected] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Add(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Add(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Divide(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Divide(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToSByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToSByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToSByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt16(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Single(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Int32(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Single(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int64(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128UInt32(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt64(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int32(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Int64(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt32(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256UInt64(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Single(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Double(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Single(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Single(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToVector256Double(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Multiply(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Multiply(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Scale(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Scale(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Sqrt(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Sqrt(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Subtract(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector256 Subtract(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + + public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx10v1.X64 + { + internal X64() { } + public static new bool IsSupported { get { throw null; } } + } + public new abstract partial class V512 : System.Runtime.Intrinsics.X86.Avx10v1.V512 + { + internal V512() { } + public new static bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector512 MinMax(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 MinMax(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToSByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToSByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToByteWithSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpected(Max = System.Runtime.Intrinsics.X86.FloatRoundingMode.ToZero)] FloatRoundingMode mode) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 MultipleSumAbsoluteDifferences(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [ConstantExpected] byte mask) { throw null; } + public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx10v1.V512.X64 + { + internal X64() { } + public static new bool IsSupported { get { throw null; } } + } + } + } + [System.CLSCompliantAttribute(false)] public abstract partial class Avx512BW : System.Runtime.Intrinsics.X86.Avx512F { diff --git a/src/libraries/System.Security.Cryptography/tests/AsnEncodedDataTests.cs b/src/libraries/System.Security.Cryptography/tests/AsnEncodedDataTests.cs index cf9423739cd69d..a53d994649f4dc 100644 --- a/src/libraries/System.Security.Cryptography/tests/AsnEncodedDataTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/AsnEncodedDataTests.cs @@ -112,11 +112,13 @@ public static void TestSubjectAlternativeName_Unix() string s = asnData.Format(false); bool isOpenSsl3 = PlatformDetection.IsOpenSsl3; + bool isOpenSsl3_4 = PlatformDetection.IsOpenSsl3_4; string expected = string.Join( ", ", // Choice[0]: OtherName - isOpenSsl3 ? "othername: UPN::subjectupn1@example.org" : "othername:", + isOpenSsl3_4 ? "othername: UPN:subjectupn1@example.org" : + isOpenSsl3 ? "othername: UPN::subjectupn1@example.org" : "othername:", // Choice[1]: Rfc822Name (EmailAddress) "email:sanemail1@example.org", // Choice[2]: DnsName diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs index de1d0b55bf2f62..5587a21a70c95a 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs @@ -932,8 +932,7 @@ public static void ChainErrorsAtMultipleLayers() } [Fact] - [SkipOnPlatform(TestPlatforms.Android, "Chain building on Android fails with an empty subject")] - public static void ChainWithEmptySubject() + public static void ChainWithEmptySubjectAndCritialSan() { using (var cert = new X509Certificate2(TestData.EmptySubjectCertificate)) using (var issuer = new X509Certificate2(TestData.EmptySubjectIssuerCertificate)) diff --git a/src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs b/src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs index be2e2dd13a29be..8495e1d72a05a9 100644 --- a/src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs +++ b/src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs @@ -4,6 +4,7 @@ #nullable enable using System; +using System.Linq; using System.IO; using System.Collections.Generic; using System.Text.RegularExpressions; @@ -119,6 +120,8 @@ public async Task SpawnBrowserAsync( Playwright = await Microsoft.Playwright.Playwright.CreateAsync(); // codespaces: ignore certificate error -> Microsoft.Playwright.PlaywrightException : net::ERR_CERT_AUTHORITY_INVALID string[] chromeArgs = new[] { $"--explicitly-allowed-ports={url.Port}", "--ignore-certificate-errors", $"--lang={locale}" }; + if (headless) + chromeArgs = chromeArgs.Append("--headless").ToArray(); _testOutput.WriteLine($"Launching chrome ('{s_chromePath.Value}') via playwright with args = {string.Join(',', chromeArgs)}"); int attempt = 0; @@ -128,7 +131,6 @@ public async Task SpawnBrowserAsync( { Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { ExecutablePath = s_chromePath.Value, - Headless = headless, Args = chromeArgs, Timeout = timeout }); @@ -184,7 +186,7 @@ public async Task RunAsync( IPage page = await context.NewPageAsync(); - page.Console += (_, msg) => + page.Console += (_, msg) => { string message = msg.Text; Match payloadMatch = s_payloadRegex.Match(message); diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index 60eb2f2c9e8227..257209027df4ce 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -1733,6 +1733,217 @@ ("SimpleTernOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "FusedMultiplySubtractNegated", ["RoundingMode"] = "ToZero", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["FixedInput3"] = "0.75"}), }; +(string templateFileName, Dictionary templateData)[] Avx10v2Inputs = new [] +{ + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToSByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((int)(sbyte)Math.Clamp(Math.Round(firstOp[0]), sbyte.MinValue, sbyte.MaxValue)& 0x000000ff)", ["ValidateRemainingResults"] = "result[i] != ((int)(sbyte)Math.Clamp(Math.Round(firstOp[i]), sbyte.MinValue, sbyte.MaxValue) & 0x000000ff)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((int)(byte)Math.Clamp(Math.Round(firstOp[0]), byte.MinValue, byte.MaxValue)& 0x000000ff)", ["ValidateRemainingResults"] = "result[i] != ((int)(byte)Math.Clamp(Math.Round(firstOp[i]), byte.MinValue, byte.MaxValue) & 0x000000ff)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32",["RetVectorType"] = "Vector128",["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((int)(sbyte)Math.Clamp(firstOp[0], sbyte.MinValue, sbyte.MaxValue)& 0x000000ff)", ["ValidateRemainingResults"] = "result[i] != ((int)(sbyte)Math.Clamp(firstOp[i], sbyte.MinValue, sbyte.MaxValue) & 0x000000ff)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32",["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((int)(byte)Math.Clamp(firstOp[0], byte.MinValue, byte.MaxValue)& 0x000000ff)", ["ValidateRemainingResults"] = "result[i] != ((int)(byte)Math.Clamp(firstOp[i], byte.MinValue, byte.MaxValue) & 0x000000ff)"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToSByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "0.65", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToSByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "0.65", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToSByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "0.65", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "27.35", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "27.35", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "27.35", ["LargestVectorSize"] = "32"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "0", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "2", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "2", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "3", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "0", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "2", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "2", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "3", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "4", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Min(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Min(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "4", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Min(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Min(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "6", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "6", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "7", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "7", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "4", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Min(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Min(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "4", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Min(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Min(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "6", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "6", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "7", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "7", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "8", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "8", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "9", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "9", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "10", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "10", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "11", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "8", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "8", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "9", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "9", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "10", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "10", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "11", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "12", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "12", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "13", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "13", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "14", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "14", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "15", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Imm"] = "15", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "12", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "12", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "13", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "13", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "14", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "14", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "15", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMax", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Imm"] = "15", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Min(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Min(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "2", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "2", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "MinMaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Add", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Add", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Add", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Add", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Add", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Add", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Int32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Int32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Int32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Single", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Single", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Single", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Single", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Single", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128Single", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128UInt32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128UInt32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector128UInt32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Double", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Double", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Double", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Double", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Double", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Double", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "10", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Int64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Single", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Single", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Single", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Single", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Single", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256Single", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "ConvertToVector256UInt64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Multiply", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Multiply", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Multiply", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Multiply", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Multiply", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Multiply", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Divide", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Divide", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Divide", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Divide", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Divide", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Divide", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Scale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Scale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Scale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Scale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Scale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Scale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "BitConverter.DoubleToUInt64Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "BitConverter.SingleToUInt32Bits", ["FixedInput"] = "29.37", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "DoubleToUInt64Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), + ("SimpleBinOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2", ["LoadIsa"] = "Avx10v1", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "SingleToUInt32Bits", ["FixedInput1"] = "0.05", ["FixedInput2"] = "0.45", ["LargestVectorSize"] = "32"}), +}; + +(string templateFileName, Dictionary templateData)[] Avx10v2_V512Inputs = new [] +{ + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToSByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((int)(sbyte)Math.Clamp(Math.Round(firstOp[0]), sbyte.MinValue, sbyte.MaxValue)& 0x000000ff)", ["ValidateRemainingResults"] = "result[i] != ((int)(sbyte)Math.Clamp(Math.Round(firstOp[i]), sbyte.MinValue, sbyte.MaxValue) & 0x000000ff)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((int)(byte)Math.Clamp(Math.Round(firstOp[0]), byte.MinValue, byte.MaxValue)& 0x000000ff)", ["ValidateRemainingResults"] = "result[i] != ((int)(byte)Math.Clamp(Math.Round(firstOp[i]), byte.MinValue, byte.MaxValue) & 0x000000ff)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToSByteWithTruncatedSaturationAndZeroExtendToInt32",["RetVectorType"] = "Vector512",["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((int)(sbyte)Math.Clamp(firstOp[0], sbyte.MinValue, sbyte.MaxValue)& 0x000000ff)", ["ValidateRemainingResults"] = "result[i] != ((int)(sbyte)Math.Clamp(firstOp[i], sbyte.MinValue, sbyte.MaxValue) & 0x000000ff)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToByteWithTruncatedSaturationAndZeroExtendToInt32",["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((int)(byte)Math.Clamp(firstOp[0], byte.MinValue, byte.MaxValue)& 0x000000ff)", ["ValidateRemainingResults"] = "result[i] != ((int)(byte)Math.Clamp(firstOp[i], byte.MinValue, byte.MaxValue) & 0x000000ff)"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToSByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "0.65", ["LargestVectorSize"] = "64"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToSByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "0.65", ["LargestVectorSize"] = "64"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToSByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "0.65", ["LargestVectorSize"] = "64"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToNegativeInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "27.35", ["LargestVectorSize"] = "64"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToPositiveInfinity", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "27.35", ["LargestVectorSize"] = "64"}), + ("SimpleUnaryOpEmbRounding.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "ConvertToByteWithSaturationAndZeroExtendToInt32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["RoundingMode"] = "ToZero", ["CastingMethod"] = "(ulong)", ["FixedInput"] = "27.35", ["LargestVectorSize"] = "64"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MultipleSumAbsoluteDifferences", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Byte", ["Imm"] = "0", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != (Math.Abs(left[0]-right[0])+Math.Abs(left[1]-right[1])+Math.Abs(left[2]-right[2])+Math.Abs(left[3]-right[3]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(left[(i&7)+(i>7?16:0)+(i>15?16:0)+(i>23?16:0)]-right[0+(i>7?16:0)+(i>15?16:0)+(i>23?16:0)])+Math.Abs(left[(i&7)+1+(i>7?16:0)+(i>15?16:0)+(i>23?16:0)]-right[1+(i>7?16:0)+(i>15?16:0)+(i>23?16:0)])+Math.Abs(left[(i&7)+2+(i>7?16:0)+(i>15?16:0)+(i>23?16:0)]-right[2+(i>7?16:0)+(i>15?16:0)+(i>23?16:0)])+Math.Abs(left[(i&7)+3+(i>7?16:0)+(i>15?16:0)+(i>23?16:0)]-right[3+(i>7?16:0)+(i>15?16:0)+(i>23?16:0)])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "0", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "2", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "3", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "0", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "2", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "3", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != (left[0] / Math.Abs(left[0])) * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != (left[i] / Math.Abs(left[i])) * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "4", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Min(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Min(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "6", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "7", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "4", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Min(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Min(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "6", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "7", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != ((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0])", ["ValidateRemainingResults"] = "result[i] != ((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "8", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "9", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "10", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "11", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "8", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "9", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "10", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "11", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != Math.Abs(((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != Math.Abs(((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "12", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "13", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "14", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Imm"] = "15", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "12", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Min(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Min(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "13", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (Math.Max(left[0], right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (Math.Max(left[i], right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "14", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) < Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) < Math.Abs(right[i])) ? left[i] : right[i]))"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx10v2.V512", ["LoadIsa"] = "Avx10v1.V512", ["Method"] = "MinMax", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Imm"] = "15", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != -1.0 * (((Math.Abs(left[0]) > Math.Abs(right[0])) ? left[0] : right[0]))", ["ValidateRemainingResults"] = "result[i] != -1.0 * (((Math.Abs(left[i]) > Math.Abs(right[i])) ? left[i] : right[i]))"}), +}; + (string templateFileName, Dictionary templateData)[] Avx512F_ScalarUpperInputs = new [] { ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "GetExponentScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.GetExponent(right[0])", ["ValidateRemainingResults"] = "result[i] != left[i]"}), @@ -3667,6 +3878,9 @@ bool isImmTemplate(string name) ProcessInputs("Gfni", GfniInputs); ProcessInputs("Gfni.V256", GfniV256Inputs); ProcessInputs("Gfni.V512", GfniV512Inputs); +ProcessInputs("Avx10v2", Avx10v2Inputs); +ProcessInputs("Avx10v2_V512", Avx10v2_V512Inputs); + void ProcessInputs(string groupName, (string templateFileName, Dictionary templateData)[] inputs) { @@ -3709,6 +3923,8 @@ void ProcessInput(StreamWriter testListFile, string groupName, (string templateF { testName += $".{input.templateData["Imm"]}"; suffix += $"{input.templateData["Imm"]}"; + testName += $".{input.templateData["LargestVectorSize"]}"; + suffix += $"{input.templateData["LargestVectorSize"]}"; } if (input.templateFileName == "InsertLoadTest.template") diff --git a/src/tests/JIT/HardwareIntrinsics/HardwareIntrinsics_X86_Avx10v2_r.csproj b/src/tests/JIT/HardwareIntrinsics/HardwareIntrinsics_X86_Avx10v2_r.csproj new file mode 100644 index 00000000000000..d7c337cd05a767 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/HardwareIntrinsics_X86_Avx10v2_r.csproj @@ -0,0 +1,20 @@ + + + 2 + + true + true + + + + true + true + true + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/HardwareIntrinsics_X86_Avx10v2_ro.csproj b/src/tests/JIT/HardwareIntrinsics/HardwareIntrinsics_X86_Avx10v2_ro.csproj new file mode 100644 index 00000000000000..d578ded3c8aef7 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/HardwareIntrinsics_X86_Avx10v2_ro.csproj @@ -0,0 +1,20 @@ + + + 2 + + true + true + + + + true + true + true + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmBinOpTest.template b/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmBinOpTest.template index 2848cd4da81de3..5f837e9f3896fd 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmBinOpTest.template +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmBinOpTest.template @@ -20,9 +20,9 @@ namespace JIT.HardwareIntrinsics.X86 public static partial class Program { [Fact] - public static void {Method}{RetBaseType}{Imm}() + public static void {Method}{LargestVectorSize}{RetBaseType}{Imm}() { - var test = new ImmBinaryOpTest__{Method}{RetBaseType}{Imm}(); + var test = new ImmBinaryOpTest__{Method}{LargestVectorSize}{RetBaseType}{Imm}(); if (test.IsSupported) { @@ -66,7 +66,7 @@ namespace JIT.HardwareIntrinsics.X86 } } - public sealed unsafe class ImmBinaryOpTest__{Method}{RetBaseType}{Imm} + public sealed unsafe class ImmBinaryOpTest__{Method}{LargestVectorSize}{RetBaseType}{Imm} { private struct TestStruct { @@ -85,7 +85,7 @@ namespace JIT.HardwareIntrinsics.X86 return testStruct; } - public void RunStructFldScenario(ImmBinaryOpTest__{Method}{RetBaseType}{Imm} testClass) + public void RunStructFldScenario(ImmBinaryOpTest__{Method}{LargestVectorSize}{RetBaseType}{Imm} testClass) { var result = {Isa}.{Method}(_fld1, _fld2, {Imm}); @@ -108,7 +108,7 @@ namespace JIT.HardwareIntrinsics.X86 private SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}> _dataTable; - public ImmBinaryOpTest__{Method}{RetBaseType}{Imm}() + public ImmBinaryOpTest__{Method}{LargestVectorSize}{RetBaseType}{Imm}() { Succeeded = true; @@ -293,7 +293,7 @@ namespace JIT.HardwareIntrinsics.X86 if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>.{Imm}, {Op2VectorType}<{Op2BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}.{LargestVectorSize}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>.{Imm}, {Op2VectorType}<{Op2BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleBinOpEmbRounding.template b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleBinOpEmbRounding.template index 3b6ab6a4de20ba..f0dd9a7e4db87f 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleBinOpEmbRounding.template +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleBinOpEmbRounding.template @@ -278,7 +278,7 @@ namespace JIT.HardwareIntrinsics.X86 for (int i = 0; i < result.Length; i++) { - ulong[] answerTable = binaryEmbRoundingAnswerTable[("{RetBaseType}", "{Method}", "{RoundingMode}")]; + ulong[] answerTable = binaryEmbRoundingAnswerTable[("{Isa}", "{RetBaseType}", "{Method}", "{RoundingMode}")]; if (BitConverter.{CastingMethod}(result[i]) != answerTable[i]) { @@ -305,80 +305,149 @@ namespace JIT.HardwareIntrinsics.X86 } } - private static Dictionary<(string, string, string), ulong[]> binaryEmbRoundingAnswerTable = new Dictionary<(string, string, string), ulong[]> + private static Dictionary<(string, string, string, string), ulong[]> binaryEmbRoundingAnswerTable = new Dictionary<(string, string, string, string), ulong[]> { - {("Double", "ConvertScalarToVector128Double", "ToNegativeInfinity"), new ulong[] {0x402e000000000000, 0x3ff0000000000000}}, - {("Single", "ConvertScalarToVector128Single", "ToNegativeInfinity"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, - {("Double", "ConvertScalarToVector128Double", "ToPositiveInfinity"), new ulong[] {0x402e000000000000, 0x3ff0000000000000}}, - {("Single", "ConvertScalarToVector128Single", "ToPositiveInfinity"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, - {("Double", "ConvertScalarToVector128Double", "ToZero"), new ulong[] {0x402e000000000000, 0x3ff0000000000000}}, - {("Single", "ConvertScalarToVector128Single", "ToZero"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, - {("Double", "AddScalar", "ToNegativeInfinity"), new ulong[] {0x3fe0000000000000, 0x3fa999999999999a}}, - {("Single", "AddScalar", "ToNegativeInfinity"), new ulong[] {0x3effffff, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "AddScalar", "ToPositiveInfinity"), new ulong[] {0x3fe0000000000001, 0x3fa999999999999a}}, - {("Single", "AddScalar", "ToPositiveInfinity"), new ulong[] {0x3f000000, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "AddScalar", "ToZero"), new ulong[] {0x3fe0000000000000, 0x3fa999999999999a}}, - {("Single", "AddScalar", "ToZero"), new ulong[] {0x3effffff, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "DivideScalar", "ToNegativeInfinity"), new ulong[] {0x3fbc71c71c71c71c, 0x3fa999999999999a}}, - {("Single", "DivideScalar", "ToNegativeInfinity"), new ulong[] {0x3de38e39, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "DivideScalar", "ToPositiveInfinity"), new ulong[] {0x3fbc71c71c71c71d, 0x3fa999999999999a}}, - {("Single", "DivideScalar", "ToPositiveInfinity"), new ulong[] {0x3de38e3a, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "DivideScalar", "ToZero"), new ulong[] {0x3fbc71c71c71c71c, 0x3fa999999999999a}}, - {("Single", "DivideScalar", "ToZero"), new ulong[] {0x3de38e39, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "MultiplyScalar", "ToNegativeInfinity"), new ulong[] {0x3f970a3d70a3d70a, 0x3fa999999999999a}}, - {("Single", "MultiplyScalar", "ToNegativeInfinity"), new ulong[] {0x3cb851eb, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "MultiplyScalar", "ToPositiveInfinity"), new ulong[] {0x3f970a3d70a3d70b, 0x3fa999999999999a}}, - {("Single", "MultiplyScalar", "ToPositiveInfinity"), new ulong[] {0x3cb851ec, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "MultiplyScalar", "ToZero"), new ulong[] {0x3f970a3d70a3d70a, 0x3fa999999999999a}}, - {("Single", "MultiplyScalar", "ToZero"), new ulong[] {0x3cb851eb, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "SubtractScalar", "ToNegativeInfinity"), new ulong[] {0xbfd999999999999a, 0x3fa999999999999a}}, - {("Single", "SubtractScalar", "ToNegativeInfinity"), new ulong[] {0xbecccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "SubtractScalar", "ToPositiveInfinity"), new ulong[] {0xbfd9999999999999, 0x3fa999999999999a}}, - {("Single", "SubtractScalar", "ToPositiveInfinity"), new ulong[] {0xbecccccc, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "SubtractScalar", "ToZero"), new ulong[] {0xbfd9999999999999, 0x3fa999999999999a}}, - {("Single", "SubtractScalar", "ToZero"), new ulong[] {0xbecccccc, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "SqrtScalar", "ToNegativeInfinity"), new ulong[] {0x3fe5775c544ff262, 0x3fa999999999999a}}, - {("Single", "SqrtScalar", "ToNegativeInfinity"), new ulong[] {0x3f2bbae2, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "SqrtScalar", "ToPositiveInfinity"), new ulong[] {0x3fe5775c544ff263, 0x3fa999999999999a}}, - {("Single", "SqrtScalar", "ToPositiveInfinity"), new ulong[] {0x3f2bbae3, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "SqrtScalar", "ToZero"), new ulong[] {0x3fe5775c544ff262, 0x3fa999999999999a}}, - {("Single", "SqrtScalar", "ToZero"), new ulong[] {0x3f2bbae2, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "Add", "ToNegativeInfinity"), new ulong[] {0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000}}, - {("Single", "Add", "ToNegativeInfinity"), new ulong[] {0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff}}, - {("Double", "Add", "ToPositiveInfinity"), new ulong[] {0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001}}, - {("Single", "Add", "ToPositiveInfinity"), new ulong[] {0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000}}, - {("Double", "Add", "ToZero"), new ulong[] {0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000}}, - {("Single", "Add", "ToZero"), new ulong[] {0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff}}, - {("Double", "Divide", "ToNegativeInfinity"), new ulong[] {0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c}}, - {("Single", "Divide", "ToNegativeInfinity"), new ulong[] {0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39}}, - {("Double", "Divide", "ToPositiveInfinity"), new ulong[] {0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d}}, - {("Single", "Divide", "ToPositiveInfinity"), new ulong[] {0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a}}, - {("Double", "Divide", "ToZero"), new ulong[] {0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c}}, - {("Single", "Divide", "ToZero"), new ulong[] {0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39}}, - {("Double", "Multiply", "ToNegativeInfinity"), new ulong[] {0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a}}, - {("Single", "Multiply", "ToNegativeInfinity"), new ulong[] {0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb}}, - {("Double", "Multiply", "ToPositiveInfinity"), new ulong[] {0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b}}, - {("Single", "Multiply", "ToPositiveInfinity"), new ulong[] {0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec}}, - {("Double", "Multiply", "ToZero"), new ulong[] {0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a}}, - {("Single", "Multiply", "ToZero"), new ulong[] {0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb}}, - {("Double", "Subtract", "ToNegativeInfinity"), new ulong[] {0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a}}, - {("Single", "Subtract", "ToNegativeInfinity"), new ulong[] {0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd}}, - {("Double", "Subtract", "ToPositiveInfinity"), new ulong[] {0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999}}, - {("Single", "Subtract", "ToPositiveInfinity"), new ulong[] {0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc}}, - {("Double", "Subtract", "ToZero"), new ulong[] {0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999}}, - {("Single", "Subtract", "ToZero"), new ulong[] {0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc}}, - {("Double", "Scale", "ToNegativeInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, - {("Single", "Scale", "ToNegativeInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "Scale", "ToPositiveInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, - {("Single", "Scale", "ToPositiveInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "Scale", "ToZero"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, - {("Single", "Scale", "ToZero"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "ScaleScalar", "ToNegativeInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, - {("Single", "ScaleScalar", "ToNegativeInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "ScaleScalar", "ToPositiveInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, - {("Single", "ScaleScalar", "ToPositiveInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, - {("Double", "ScaleScalar", "ToZero"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, - {("Single", "ScaleScalar", "ToZero"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "ConvertScalarToVector128Double", "ToNegativeInfinity"), new ulong[] {0x402e000000000000, 0x3ff0000000000000}}, + {("Avx10v1", "Single", "ConvertScalarToVector128Single", "ToNegativeInfinity"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, + {("Avx512F", "Single", "ConvertScalarToVector128Single", "ToNegativeInfinity"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, + {("Avx10v1", "Double", "ConvertScalarToVector128Double", "ToPositiveInfinity"), new ulong[] {0x402e000000000000, 0x3ff0000000000000}}, + {("Avx10v1", "Single", "ConvertScalarToVector128Single", "ToPositiveInfinity"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, + {("Avx512F", "Single", "ConvertScalarToVector128Single", "ToPositiveInfinity"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, + {("Avx10v1", "Double", "ConvertScalarToVector128Double", "ToZero"), new ulong[] {0x402e000000000000, 0x3ff0000000000000}}, + {("Avx10v1", "Single", "ConvertScalarToVector128Single", "ToZero"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, + {("Avx512F", "Single", "ConvertScalarToVector128Single", "ToZero"), new ulong[] {0x41700000, 0x3f800000, 0x3f800000, 0x3f800000}}, + {("Avx10v1", "Double", "AddScalar", "ToNegativeInfinity"), new ulong[] {0x3fe0000000000000, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "AddScalar", "ToNegativeInfinity"), new ulong[] {0x3effffff, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "AddScalar", "ToPositiveInfinity"), new ulong[] {0x3fe0000000000001, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "AddScalar", "ToPositiveInfinity"), new ulong[] {0x3f000000, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "AddScalar", "ToZero"), new ulong[] {0x3fe0000000000000, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "AddScalar", "ToZero"), new ulong[] {0x3effffff, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "AddScalar", "ToNegativeInfinity"), new ulong[] {0x3fe0000000000000, 0x3fa999999999999a}}, + {("Avx512F", "Single", "AddScalar", "ToNegativeInfinity"), new ulong[] {0x3effffff, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "AddScalar", "ToPositiveInfinity"), new ulong[] {0x3fe0000000000001, 0x3fa999999999999a}}, + {("Avx512F", "Single", "AddScalar", "ToPositiveInfinity"), new ulong[] {0x3f000000, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "AddScalar", "ToZero"), new ulong[] {0x3fe0000000000000, 0x3fa999999999999a}}, + {("Avx512F", "Single", "AddScalar", "ToZero"), new ulong[] {0x3effffff, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "DivideScalar", "ToNegativeInfinity"), new ulong[] {0x3fbc71c71c71c71c, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "DivideScalar", "ToNegativeInfinity"), new ulong[] {0x3de38e39, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "DivideScalar", "ToPositiveInfinity"), new ulong[] {0x3fbc71c71c71c71d, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "DivideScalar", "ToPositiveInfinity"), new ulong[] {0x3de38e3a, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "DivideScalar", "ToZero"), new ulong[] {0x3fbc71c71c71c71c, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "DivideScalar", "ToZero"), new ulong[] {0x3de38e39, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "DivideScalar", "ToNegativeInfinity"), new ulong[] {0x3fbc71c71c71c71c, 0x3fa999999999999a}}, + {("Avx512F", "Single", "DivideScalar", "ToNegativeInfinity"), new ulong[] {0x3de38e39, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "DivideScalar", "ToPositiveInfinity"), new ulong[] {0x3fbc71c71c71c71d, 0x3fa999999999999a}}, + {("Avx512F", "Single", "DivideScalar", "ToPositiveInfinity"), new ulong[] {0x3de38e3a, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "DivideScalar", "ToZero"), new ulong[] {0x3fbc71c71c71c71c, 0x3fa999999999999a}}, + {("Avx512F", "Single", "DivideScalar", "ToZero"), new ulong[] {0x3de38e39, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "MultiplyScalar", "ToNegativeInfinity"), new ulong[] {0x3f970a3d70a3d70a, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "MultiplyScalar", "ToNegativeInfinity"), new ulong[] {0x3cb851eb, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "MultiplyScalar", "ToPositiveInfinity"), new ulong[] {0x3f970a3d70a3d70b, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "MultiplyScalar", "ToPositiveInfinity"), new ulong[] {0x3cb851ec, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "MultiplyScalar", "ToZero"), new ulong[] {0x3f970a3d70a3d70a, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "MultiplyScalar", "ToZero"), new ulong[] {0x3cb851eb, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "MultiplyScalar", "ToNegativeInfinity"), new ulong[] {0x3f970a3d70a3d70a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "MultiplyScalar", "ToNegativeInfinity"), new ulong[] {0x3cb851eb, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "MultiplyScalar", "ToPositiveInfinity"), new ulong[] {0x3f970a3d70a3d70b, 0x3fa999999999999a}}, + {("Avx512F", "Single", "MultiplyScalar", "ToPositiveInfinity"), new ulong[] {0x3cb851ec, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "MultiplyScalar", "ToZero"), new ulong[] {0x3f970a3d70a3d70a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "MultiplyScalar", "ToZero"), new ulong[] {0x3cb851eb, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "SubtractScalar", "ToNegativeInfinity"), new ulong[] {0xbfd999999999999a, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "SubtractScalar", "ToNegativeInfinity"), new ulong[] {0xbecccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "SubtractScalar", "ToPositiveInfinity"), new ulong[] {0xbfd9999999999999, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "SubtractScalar", "ToPositiveInfinity"), new ulong[] {0xbecccccc, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "SubtractScalar", "ToZero"), new ulong[] {0xbfd9999999999999, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "SubtractScalar", "ToZero"), new ulong[] {0xbecccccc, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "SubtractScalar", "ToNegativeInfinity"), new ulong[] {0xbfd999999999999a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "SubtractScalar", "ToNegativeInfinity"), new ulong[] {0xbecccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "SubtractScalar", "ToPositiveInfinity"), new ulong[] {0xbfd9999999999999, 0x3fa999999999999a}}, + {("Avx512F", "Single", "SubtractScalar", "ToPositiveInfinity"), new ulong[] {0xbecccccc, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "SubtractScalar", "ToZero"), new ulong[] {0xbfd9999999999999, 0x3fa999999999999a}}, + {("Avx512F", "Single", "SubtractScalar", "ToZero"), new ulong[] {0xbecccccc, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "SqrtScalar", "ToNegativeInfinity"), new ulong[] {0x3fe5775c544ff262, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "SqrtScalar", "ToNegativeInfinity"), new ulong[] {0x3f2bbae2, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "SqrtScalar", "ToPositiveInfinity"), new ulong[] {0x3fe5775c544ff263, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "SqrtScalar", "ToPositiveInfinity"), new ulong[] {0x3f2bbae3, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "SqrtScalar", "ToZero"), new ulong[] {0x3fe5775c544ff262, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "SqrtScalar", "ToZero"), new ulong[] {0x3f2bbae2, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "SqrtScalar", "ToNegativeInfinity"), new ulong[] {0x3fe5775c544ff262, 0x3fa999999999999a}}, + {("Avx512F", "Single", "SqrtScalar", "ToNegativeInfinity"), new ulong[] {0x3f2bbae2, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "SqrtScalar", "ToPositiveInfinity"), new ulong[] {0x3fe5775c544ff263, 0x3fa999999999999a}}, + {("Avx512F", "Single", "SqrtScalar", "ToPositiveInfinity"), new ulong[] {0x3f2bbae3, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "SqrtScalar", "ToZero"), new ulong[] {0x3fe5775c544ff262, 0x3fa999999999999a}}, + {("Avx512F", "Single", "SqrtScalar", "ToZero"), new ulong[] {0x3f2bbae2, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "Add", "ToNegativeInfinity"), new ulong[] {0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000}}, + {("Avx512F", "Single", "Add", "ToNegativeInfinity"), new ulong[] {0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff}}, + {("Avx512F", "Double", "Add", "ToPositiveInfinity"), new ulong[] {0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001}}, + {("Avx512F", "Single", "Add", "ToPositiveInfinity"), new ulong[] {0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000}}, + {("Avx512F", "Double", "Add", "ToZero"), new ulong[] {0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000}}, + {("Avx512F", "Single", "Add", "ToZero"), new ulong[] {0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff}}, + {("Avx512F", "Double", "Divide", "ToNegativeInfinity"), new ulong[] {0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c}}, + {("Avx512F", "Single", "Divide", "ToNegativeInfinity"), new ulong[] {0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39}}, + {("Avx512F", "Double", "Divide", "ToPositiveInfinity"), new ulong[] {0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d}}, + {("Avx512F", "Single", "Divide", "ToPositiveInfinity"), new ulong[] {0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a}}, + {("Avx512F", "Double", "Divide", "ToZero"), new ulong[] {0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c}}, + {("Avx512F", "Single", "Divide", "ToZero"), new ulong[] {0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39}}, + {("Avx512F", "Double", "Multiply", "ToNegativeInfinity"), new ulong[] {0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a}}, + {("Avx512F", "Single", "Multiply", "ToNegativeInfinity"), new ulong[] {0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb}}, + {("Avx512F", "Double", "Multiply", "ToPositiveInfinity"), new ulong[] {0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b}}, + {("Avx512F", "Single", "Multiply", "ToPositiveInfinity"), new ulong[] {0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec}}, + {("Avx512F", "Double", "Multiply", "ToZero"), new ulong[] {0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a}}, + {("Avx512F", "Single", "Multiply", "ToZero"), new ulong[] {0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb}}, + {("Avx512F", "Double", "Subtract", "ToNegativeInfinity"), new ulong[] {0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a}}, + {("Avx512F", "Single", "Subtract", "ToNegativeInfinity"), new ulong[] {0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd}}, + {("Avx512F", "Double", "Subtract", "ToPositiveInfinity"), new ulong[] {0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999}}, + {("Avx512F", "Single", "Subtract", "ToPositiveInfinity"), new ulong[] {0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc}}, + {("Avx512F", "Double", "Subtract", "ToZero"), new ulong[] {0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999}}, + {("Avx512F", "Single", "Subtract", "ToZero"), new ulong[] {0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc}}, + {("Avx512F", "Double", "Scale", "ToNegativeInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "Scale", "ToNegativeInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "Scale", "ToPositiveInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "Scale", "ToPositiveInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "Scale", "ToZero"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "Scale", "ToZero"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "ScaleScalar", "ToNegativeInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "ScaleScalar", "ToNegativeInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "ScaleScalar", "ToPositiveInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "ScaleScalar", "ToPositiveInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v1", "Double", "ScaleScalar", "ToZero"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx10v1", "Single", "ScaleScalar", "ToZero"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "ScaleScalar", "ToNegativeInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "ScaleScalar", "ToNegativeInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "ScaleScalar", "ToPositiveInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "ScaleScalar", "ToPositiveInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx512F", "Double", "ScaleScalar", "ToZero"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx512F", "Single", "ScaleScalar", "ToZero"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v2", "Double", "Subtract", "ToNegativeInfinity"), new ulong[] {0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a, 0xbfd999999999999a}}, + {("Avx10v2", "Single", "Subtract", "ToNegativeInfinity"), new ulong[] {0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd, 0xbecccccd}}, + {("Avx10v2", "Double", "Subtract", "ToPositiveInfinity"), new ulong[] {0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999}}, + {("Avx10v2", "Single", "Subtract", "ToPositiveInfinity"), new ulong[] {0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc}}, + {("Avx10v2", "Double", "Subtract", "ToZero"), new ulong[] {0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999, 0xbfd9999999999999}}, + {("Avx10v2", "Single", "Subtract", "ToZero"), new ulong[] {0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc, 0xbecccccc}}, + {("Avx10v2", "Double", "Add", "ToNegativeInfinity"), new ulong[] {0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000}}, + {("Avx10v2", "Single", "Add", "ToNegativeInfinity"), new ulong[] {0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff}}, + {("Avx10v2", "Double", "Add", "ToPositiveInfinity"), new ulong[] {0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001, 0x3fe0000000000001}}, + {("Avx10v2", "Single", "Add", "ToPositiveInfinity"), new ulong[] {0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000}}, + {("Avx10v2", "Double", "Add", "ToZero"), new ulong[] {0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000, 0x3fe0000000000000}}, + {("Avx10v2", "Single", "Add", "ToZero"), new ulong[] {0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff, 0x3effffff}}, + {("Avx10v2", "Double", "Divide", "ToNegativeInfinity"), new ulong[] {0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c}}, + {("Avx10v2", "Single", "Divide", "ToNegativeInfinity"), new ulong[] {0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39}}, + {("Avx10v2", "Double", "Divide", "ToPositiveInfinity"), new ulong[] {0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d, 0x3fbc71c71c71c71d}}, + {("Avx10v2", "Single", "Divide", "ToPositiveInfinity"), new ulong[] {0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a, 0x3de38e3a}}, + {("Avx10v2", "Double", "Divide", "ToZero"), new ulong[] {0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c, 0x3fbc71c71c71c71c}}, + {("Avx10v2", "Single", "Divide", "ToZero"), new ulong[] {0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39, 0x3de38e39}}, + {("Avx10v2", "Double", "Multiply", "ToNegativeInfinity"), new ulong[] {0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a}}, + {("Avx10v2", "Single", "Multiply", "ToNegativeInfinity"), new ulong[] {0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb}}, + {("Avx10v2", "Double", "Multiply", "ToPositiveInfinity"), new ulong[] {0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b, 0x3f970a3d70a3d70b}}, + {("Avx10v2", "Single", "Multiply", "ToPositiveInfinity"), new ulong[] {0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec, 0x3cb851ec}}, + {("Avx10v2", "Double", "Multiply", "ToZero"), new ulong[] {0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a, 0x3f970a3d70a3d70a}}, + {("Avx10v2", "Single", "Multiply", "ToZero"), new ulong[] {0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb, 0x3cb851eb}}, + {("Avx10v2", "Double", "Scale", "ToNegativeInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx10v2", "Single", "Scale", "ToNegativeInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v2", "Double", "Scale", "ToPositiveInfinity"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx10v2", "Single", "Scale", "ToPositiveInfinity"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, + {("Avx10v2", "Double", "Scale", "ToZero"), new ulong[] {0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a, 0x3fa999999999999a}}, + {("Avx10v2", "Single", "Scale", "ToZero"), new ulong[] {0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd, 0x3d4ccccd}}, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleUnaryOpEmbRounding.template b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleUnaryOpEmbRounding.template index be35aafde3fb87..5dc9793a6290d8 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleUnaryOpEmbRounding.template +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SimpleUnaryOpEmbRounding.template @@ -264,6 +264,7 @@ namespace JIT.HardwareIntrinsics.X86 if ({CastingMethod}(result[i]) != answerTable[i]) { + Console.WriteLine("Failed on index: " + i + " with value: " + result[i] + " and expected: " + answerTable[i] + {CastingMethod}(result[i])); succeeded = false; Console.WriteLine("Avx512 {Method} Embedded rounding failed on {RetBaseType} with {RoundingMode}:"); foreach (var item in result) @@ -360,6 +361,66 @@ namespace JIT.HardwareIntrinsics.X86 {("Avx10v1.V512", "Single", "UInt64", "ConvertToVector512UInt64", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d}}, {("Avx10v1.V512", "Single", "UInt64", "ConvertToVector512UInt64", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}}, {("Avx10v1.V512", "Single", "UInt64", "ConvertToVector512UInt64", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Double", "Double", "Sqrt", "ToNegativeInfinity"), new ulong[] {0x4015ad79b34092ec, 0x4015ad79b34092ec, 0x4015ad79b34092ec, 0x4015ad79b34092ec}}, + {("Avx10v2", "Single", "Single", "Sqrt", "ToNegativeInfinity"), new ulong[] {0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd}}, + {("Avx10v2", "Double", "Double", "Sqrt", "ToPositiveInfinity"), new ulong[] {0x4015ad79b34092ed, 0x4015ad79b34092ed, 0x4015ad79b34092ed, 0x4015ad79b34092ed}}, + {("Avx10v2", "Single", "Single", "Sqrt", "ToPositiveInfinity"), new ulong[] {0x40ad6bce, 0x40ad6bce, 0x40ad6bce, 0x40ad6bce, 0x40ad6bce, 0x40ad6bce, 0x40ad6bce, 0x40ad6bce}}, + {("Avx10v2", "Double", "Double", "Sqrt", "ToZero"), new ulong[] {0x4015ad79b34092ec, 0x4015ad79b34092ec, 0x4015ad79b34092ec, 0x4015ad79b34092ec}}, + {("Avx10v2", "Single", "Single", "Sqrt", "ToZero"), new ulong[] {0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd, 0x40ad6bcd}}, + {("Avx10v2", "Double", "Int32", "ConvertToVector128Int32", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Double", "Int32", "ConvertToVector128Int32", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e}}, + {("Avx10v2", "Double", "Int32", "ConvertToVector128Int32", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Int64", "Single", "ConvertToVector128Single", "ToNegativeInfinity"), new ulong[] {0x41200000, 0x41200000, 0x41200000, 0x41200000}}, + {("Avx10v2", "Int64", "Single", "ConvertToVector128Single", "ToPositiveInfinity"), new ulong[] {0x41200000, 0x41200000, 0x41200000, 0x41200000}}, + {("Avx10v2", "Int64", "Single", "ConvertToVector128Single", "ToZero"), new ulong[] {0x41200000, 0x41200000, 0x41200000, 0x41200000}}, + {("Avx10v2", "UInt64", "Single", "ConvertToVector128Single", "ToNegativeInfinity"), new ulong[] {0x41200000, 0x41200000, 0x41200000, 0x41200000}}, + {("Avx10v2", "UInt64", "Single", "ConvertToVector128Single", "ToPositiveInfinity"), new ulong[] {0x41200000, 0x41200000, 0x41200000, 0x41200000}}, + {("Avx10v2", "UInt64", "Single", "ConvertToVector128Single", "ToZero"), new ulong[] {0x41200000, 0x41200000, 0x41200000, 0x41200000}}, + {("Avx10v2", "Double", "UInt32", "ConvertToVector128UInt32", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Double", "UInt32", "ConvertToVector128UInt32", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e}}, + {("Avx10v2", "Double", "UInt32", "ConvertToVector128UInt32", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Int64", "Double", "ConvertToVector256Double", "ToNegativeInfinity"), new ulong[] {0x4024000000000000, 0x4024000000000000, 0x4024000000000000, 0x4024000000000000}}, + {("Avx10v2", "Int64", "Double", "ConvertToVector256Double", "ToPositiveInfinity"), new ulong[] {0x4024000000000000, 0x4024000000000000, 0x4024000000000000, 0x4024000000000000}}, + {("Avx10v2", "Int64", "Double", "ConvertToVector256Double", "ToZero"), new ulong[] {0x4024000000000000, 0x4024000000000000, 0x4024000000000000, 0x4024000000000000}}, + {("Avx10v2", "UInt64", "Double", "ConvertToVector256Double", "ToNegativeInfinity"), new ulong[] {0x4024000000000000, 0x4024000000000000, 0x4024000000000000, 0x4024000000000000}}, + {("Avx10v2", "UInt64", "Double", "ConvertToVector256Double", "ToPositiveInfinity"), new ulong[] {0x4024000000000000, 0x4024000000000000, 0x4024000000000000, 0x4024000000000000}}, + {("Avx10v2", "UInt64", "Double", "ConvertToVector256Double", "ToZero"), new ulong[] {0x4024000000000000, 0x4024000000000000, 0x4024000000000000, 0x4024000000000000}}, + {("Avx10v2", "Single", "Int32", "ConvertToVector256Int32", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Single", "Int32", "ConvertToVector256Int32", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}}, + {("Avx10v2", "Single", "Int32", "ConvertToVector256Int32", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Double", "Int64", "ConvertToVector256Int64", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Double", "Int64", "ConvertToVector256Int64", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e}}, + {("Avx10v2", "Double", "Int64", "ConvertToVector256Int64", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Single", "Int64", "ConvertToVector256Int64", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Single", "Int64", "ConvertToVector256Int64", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e}}, + {("Avx10v2", "Single", "Int64", "ConvertToVector256Int64", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "UInt32", "Single", "ConvertToVector256Single", "ToNegativeInfinity"), new ulong[] {0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000}}, + {("Avx10v2", "UInt32", "Single", "ConvertToVector256Single", "ToPositiveInfinity"), new ulong[] {0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000}}, + {("Avx10v2", "UInt32", "Single", "ConvertToVector256Single", "ToZero"), new ulong[] {0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000}}, + {("Avx10v2", "Int32", "Single", "ConvertToVector256Single", "ToNegativeInfinity"), new ulong[] {0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000}}, + {("Avx10v2", "Int32", "Single", "ConvertToVector256Single", "ToPositiveInfinity"), new ulong[] {0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000}}, + {("Avx10v2", "Int32", "Single", "ConvertToVector256Single", "ToZero"), new ulong[] {0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000, 0x41e80000}}, + {("Avx10v2", "Single", "UInt32", "ConvertToVector256UInt32", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Single", "UInt32", "ConvertToVector256UInt32", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}}, + {("Avx10v2", "Single", "UInt32", "ConvertToVector256UInt32", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Double", "UInt64", "ConvertToVector256UInt64", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Double", "UInt64", "ConvertToVector256UInt64", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e}}, + {("Avx10v2", "Double", "UInt64", "ConvertToVector256UInt64", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Single", "UInt64", "ConvertToVector256UInt64", "ToNegativeInfinity"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Single", "UInt64", "ConvertToVector256UInt64", "ToPositiveInfinity"), new ulong[] {0x1e, 0x1e, 0x1e, 0x1e}}, + {("Avx10v2", "Single", "UInt64", "ConvertToVector256UInt64", "ToZero"), new ulong[] {0x1d, 0x1d, 0x1d, 0x1d}}, + {("Avx10v2", "Single", "Int32", "ConvertToSByteWithSaturationAndZeroExtendToInt32", "ToNegativeInfinity"), new ulong[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {("Avx10v2", "Single", "Int32", "ConvertToSByteWithSaturationAndZeroExtendToInt32", "ToPositiveInfinity"), new ulong[] {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}}, + {("Avx10v2", "Single", "Int32", "ConvertToSByteWithSaturationAndZeroExtendToInt32", "ToZero"), new ulong[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {("Avx10v2", "Single", "Int32", "ConvertToByteWithSaturationAndZeroExtendToInt32", "ToNegativeInfinity"), new ulong[] {0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b}}, + {("Avx10v2", "Single", "Int32", "ConvertToByteWithSaturationAndZeroExtendToInt32", "ToPositiveInfinity"), new ulong[] {0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c}}, + {("Avx10v2", "Single", "Int32", "ConvertToByteWithSaturationAndZeroExtendToInt32", "ToZero"), new ulong[] {0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b}}, + {("Avx10v2.V512", "Single", "Int32", "ConvertToSByteWithSaturationAndZeroExtendToInt32", "ToNegativeInfinity"), new ulong[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {("Avx10v2.V512", "Single", "Int32", "ConvertToSByteWithSaturationAndZeroExtendToInt32", "ToPositiveInfinity"), new ulong[] {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}}, + {("Avx10v2.V512", "Single", "Int32", "ConvertToSByteWithSaturationAndZeroExtendToInt32", "ToZero"), new ulong[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {("Avx10v2.V512", "Single", "Int32", "ConvertToByteWithSaturationAndZeroExtendToInt32", "ToNegativeInfinity"), new ulong[] {0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b}}, + {("Avx10v2.V512", "Single", "Int32", "ConvertToByteWithSaturationAndZeroExtendToInt32", "ToPositiveInfinity"), new ulong[] {0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c}}, + {("Avx10v2.V512", "Single", "Int32", "ConvertToByteWithSaturationAndZeroExtendToInt32", "ToZero"), new ulong[] {0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b}}, }; } } diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2SampleTest.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2SampleTest.cs new file mode 100644 index 00000000000000..15bc0c4b844d6a --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2SampleTest.cs @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; +using Xunit; + +/* How to run this test? +1. Compile the runtime repo using --> PS D:\Git_repos\runtime> .\build.cmd -subset clr -rc debug +2. Run the following command to setup the test repo --> PS D:\Git_repos\runtime\src\tests> .\build.cmd x64 Debug generatelayoutonly +3. Compile the JIT/HardwareIntrinsics test suite using --> PS D:\Git_repos\runtime\src\tests> .\build.cmd x64 Debug tree JIT/HardwareIntrinsics +4. Use the following variables to run / debug the Avx10 test + { + "name": "(Windows) Launch", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/artifacts/tests/coreclr/windows.x64.Debug/Tests/Core_Root/corerun.exe", + "args": [ + "D:/Git_repos/runtime/artifacts/tests/coreclr/windows.x64.Debug/JIT/HardwareIntrinsics/HardwareIntrinsics_X86_Avx10_r/HardwareIntrinsics_X86_Avx10_r.dll" + ], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [ + {"name": "DOTNET_TieredCompilation", "value": "0"}, + {"name": "DOTNET_JitForceEvexEncoding", "value": "1"}, + {"name": "DOTNET_JitStressEvexEncoding", "value": "1"}, + {"name": "DOTNET_ENABLEINCOMPLETEISACLASS", "value": "1"}, + {"name": "DOTNET_JitDisasm", "value": "getAbs128"}, + {"name": "DOTNET_ReadyToRun", "value": "0"}, + ], + "console": "integratedTerminal", + "symbolSearchPath": "C:/Users/kmodi/Documents/Git_repos/runtime/artifacts/tests/coreclr/windows.x64.Debug/Tests/Core_Root/PDB" + } +5. You can capture the disasm for getAbs128 if running with env variables above. +*/ +namespace IntelHardwareIntrinsicTest._Avx10v2 +{ + public partial class Program + { + const float EPS = Single.Epsilon * 5; + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static Vector128 getAbs128(Vector128 val) + { + return Avx10v2.Abs(val); + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static Vector256 getAbs256(Vector256 val) + { + return Avx10v2.Abs(val); + } + + [Fact] + public static unsafe void Avx10v2SampleTest () + { + Console.WriteLine("Test executed"); + if (Avx10v2.IsSupported) + { + Console.WriteLine("Avx10v2 supported"); + Vector128 val = Vector128.Create(-5); + Vector128 absVal = getAbs128(val); + Vector128 left = Vector128.Create(11.0); + Vector128 right = Vector128.Create(-12.0); + Vector128 firstOp = Vector128.Create(0.65f); + Vector256 secondOp = Vector256.Create(27.35f); + // Console.WriteLine("widen to int is " + Avx10v2.ConvertToByteWithSaturationAndWidenToInt32(secondOp, FloatRoundingMode.ToNegativeInfinity)); + // Console.WriteLine("widen to int is " + Avx10v2.ConvertToByteWithSaturationAndWidenToInt32(secondOp, FloatRoundingMode.ToPositiveInfinity)); + // Console.WriteLine("widen to int is " + Avx10v2.ConvertToByteWithSaturationAndWidenToInt32(secondOp, FloatRoundingMode.ToZero)); + // Console.WriteLine("Scalar conversion " + (int)(sbyte)Math.Clamp(Math.Round(0.65f), sbyte.MinValue, sbyte.MaxValue)); + // Console.WriteLine("widen to uint is " + Avx10v2.ConvertToByteWithSaturationAndWidenToInt32(firstOp)); + // Console.WriteLine("widen to int is " + Avx10v2.ConvertToSByteWithSaturationAndWidenToInt32(secondOp)); + // Console.WriteLine("widen to uint is " + Avx10v2.ConvertToByteWithSaturationAndWidenToInt32(secondOp)); + // Console.WriteLine("widen trunc to int is " + Avx10v2.ConvertToByteWithTruncationSaturationAndWidenToInt32(firstOp)); + // Console.WriteLine("widen trunc to uint is " + Avx10v2.ConvertToSByteWithTruncationSaturationAndWidenToInt32(firstOp)); + // Console.WriteLine("widen trunc to int is " + Avx10v2.ConvertToByteWithTruncationSaturationAndWidenToInt32(secondOp)); + // Console.WriteLine("widen trunc to uint is " + Avx10v2.ConvertToSByteWithTruncationSaturationAndWidenToInt32(secondOp)); + // Console.WriteLine("MinMax is " + Avx10v2.MinMax(left, right, 0x00)); + // Console.WriteLine("MinMax is " + Avx10v2.MinMax(left, right, 0x04)); + } + else { + Console.WriteLine("Avx10v2 not supported"); + } + if (Avx10v2.V512.IsSupported) + { + Console.WriteLine("Avx10v2_V512 supported"); + Vector256 val = Vector256.Create(-5); + Vector256 absVal = getAbs256(val); + } + else { + Console.WriteLine("Avx10v2_V512 not supported"); + } + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_handwritten_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_handwritten_r.csproj new file mode 100644 index 00000000000000..e2d9e7ce0ed4f7 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_handwritten_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx10v2_handwritten_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_handwritten_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_handwritten_ro.csproj new file mode 100644 index 00000000000000..1e36f1736d9594 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_handwritten_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx10v2_handwritten_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_r.csproj new file mode 100644 index 00000000000000..e5742bbc88d50a --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx10v2_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_ro.csproj new file mode 100644 index 00000000000000..f1717b0d99b83a --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Avx10v2_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx10v2_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Program.Avx10v2.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Program.Avx10v2.cs new file mode 100644 index 00000000000000..c39f73b1a1d2ac --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2/Program.Avx10v2.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.X86._Avx10v2 +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512SampleTest.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512SampleTest.cs new file mode 100644 index 00000000000000..9de72da43f4f7b --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512SampleTest.cs @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; +using Xunit; + +/* How to run this test? +1. Compile the runtime repo using --> PS D:\Git_repos\runtime> .\build.cmd -subset clr -rc debug +2. Run the following command to setup the test repo --> PS D:\Git_repos\runtime\src\tests> .\build.cmd x64 Debug generatelayoutonly +3. Compile the JIT/HardwareIntrinsics test suite using --> PS D:\Git_repos\runtime\src\tests> .\build.cmd x64 Debug tree JIT/HardwareIntrinsics +4. Use the following variables to run / debug the Avx10 test + { + "name": "(Windows) Launch", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/artifacts/tests/coreclr/windows.x64.Debug/Tests/Core_Root/corerun.exe", + "args": [ + "D:/Git_repos/runtime/artifacts/tests/coreclr/windows.x64.Debug/JIT/HardwareIntrinsics/HardwareIntrinsics_X86_Avx10_r/HardwareIntrinsics_X86_Avx10_r.dll" + ], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [ + {"name": "DOTNET_TieredCompilation", "value": "0"}, + {"name": "DOTNET_JitForceEvexEncoding", "value": "1"}, + {"name": "DOTNET_JitStressEvexEncoding", "value": "1"}, + {"name": "DOTNET_ENABLEINCOMPLETEISACLASS", "value": "1"}, + {"name": "DOTNET_JitDisasm", "value": "getAbs128"}, + {"name": "DOTNET_ReadyToRun", "value": "0"}, + ], + "console": "integratedTerminal", + "symbolSearchPath": "C:/Users/kmodi/Documents/Git_repos/runtime/artifacts/tests/coreclr/windows.x64.Debug/Tests/Core_Root/PDB" + } +5. You can capture the disasm for getAbs128 if running with env variables above. +*/ +namespace IntelHardwareIntrinsicTest._Avx10v2_V512 +{ + public partial class Program + { + const float EPS = Single.Epsilon * 5; + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static Vector128 getAbs128(Vector128 val) + { + return Avx10v2.Abs(val); + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static Vector256 getAbs256(Vector256 val) + { + return Avx10v2.Abs(val); + } + + [Fact] + public static unsafe void Avx10v2_V512SampleTest () + { + Console.WriteLine("Test executed for Avx10v2_V512"); + if (Avx10v2.IsSupported) + { + Console.WriteLine("Avx10v2 supported"); + Vector128 val = Vector128.Create(-5); + Vector128 absVal = getAbs128(val); + Vector128 left = Vector128.Create(11.0); + Vector128 right = Vector128.Create(-12.0); + Vector128 firstOp = Vector128.Create(0.65f); + Vector512 secondOp = Vector512.Create(27.35f); + // Console.WriteLine("widen to int is " + Avx10v2.V512.ConvertToByteWithSaturationAndWidenToInt32(secondOp, FloatRoundingMode.ToNegativeInfinity)); + // Console.WriteLine("widen to int is " + Avx10v2.V512.ConvertToByteWithSaturationAndWidenToInt32(secondOp, FloatRoundingMode.ToPositiveInfinity)); + // Console.WriteLine("widen to int is " + Avx10v2.V512.ConvertToByteWithSaturationAndWidenToInt32(secondOp, FloatRoundingMode.ToZero)); + // Console.WriteLine("Scalar conversion " + (int)(sbyte)Math.Clamp(Math.Round(0.65f), sbyte.MinValue, sbyte.MaxValue)); + // Console.WriteLine("widen to uint is " + Avx10v2.ConvertToByteWithSaturationAndWidenToInt32(firstOp)); + // Console.WriteLine("widen to int is " + Avx10v2.ConvertToSByteWithSaturationAndWidenToInt32(secondOp)); + // Console.WriteLine("widen to uint is " + Avx10v2.ConvertToByteWithSaturationAndWidenToInt32(secondOp)); + // Console.WriteLine("widen trunc to int is " + Avx10v2.ConvertToByteWithTruncationSaturationAndWidenToInt32(firstOp)); + // Console.WriteLine("widen trunc to uint is " + Avx10v2.ConvertToSByteWithTruncationSaturationAndWidenToInt32(firstOp)); + // Console.WriteLine("widen trunc to int is " + Avx10v2.ConvertToByteWithTruncationSaturationAndWidenToInt32(secondOp)); + // Console.WriteLine("widen trunc to uint is " + Avx10v2.ConvertToSByteWithTruncationSaturationAndWidenToInt32(secondOp)); + // Console.WriteLine("MinMax is " + Avx10v2.MinMax(left, right, 0x00)); + // Console.WriteLine("MinMax is " + Avx10v2.MinMax(left, right, 0x04)); + } + else { + Console.WriteLine("Avx10v2 not supported"); + } + if (Avx10v2.V512.IsSupported) + { + Console.WriteLine("Avx10v2_V512 supported"); + Vector256 val = Vector256.Create(-5); + Vector256 absVal = getAbs256(val); + } + else { + Console.WriteLine("Avx10v2_V512 not supported"); + } + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_handwritten_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_handwritten_r.csproj new file mode 100644 index 00000000000000..10f835816be477 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_handwritten_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx10v2_V512_handwritten_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_handwritten_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_handwritten_ro.csproj new file mode 100644 index 00000000000000..f8528d7f995218 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_handwritten_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx10v2_V512_handwritten_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_r.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_r.csproj new file mode 100644 index 00000000000000..22d6dd83525047 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_r.csproj @@ -0,0 +1,14 @@ + + + X86_Avx10v2_V512_r + true + + + Embedded + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_ro.csproj b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_ro.csproj new file mode 100644 index 00000000000000..437c0ab0c383af --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Avx10v2_V512_ro.csproj @@ -0,0 +1,14 @@ + + + X86_Avx10v2_V512_ro + true + + + Embedded + True + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Program.Avx10v2_V512.cs b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Program.Avx10v2_V512.cs new file mode 100644 index 00000000000000..811f0f66c9205d --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Avx10v2_V512/Program.Avx10v2_V512.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.X86._Avx10v2_V512 +{ + public static partial class Program + { + static Program() + { + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Directory.Build.props b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Directory.Build.props new file mode 100644 index 00000000000000..e3e1bac79c32c5 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Directory.Build.props @@ -0,0 +1,10 @@ + + + + + + + true + + + diff --git a/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Directory.Build.targets b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Directory.Build.targets new file mode 100644 index 00000000000000..5b046968c0461a --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/X86_Avx10v2/Directory.Build.targets @@ -0,0 +1,32 @@ + + + + + + + $(IntermediateOutputPath)$(MSBuildProjectName)/gen/ + $(GeneratedHWIntrinsicTestDirectory)GeneratedHWIntrinsicTestList.txt + + + + + + + + + + + + + + + + + diff --git a/src/tests/JIT/opt/InstructionCombining/BitwiseClearShift.cs b/src/tests/JIT/opt/InstructionCombining/BitwiseClearShift.cs new file mode 100644 index 00000000000000..d34be3ae3a78b0 --- /dev/null +++ b/src/tests/JIT/opt/InstructionCombining/BitwiseClearShift.cs @@ -0,0 +1,217 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +namespace TestBitwiseClearShift +{ + public class Program + { + [MethodImpl(MethodImplOptions.NoInlining)] + [Fact] + public static int CheckBitwiseClearShift() + { + bool fail = false; + + if (!Bic(0xFFFFFFFF, 0x12345678, 0xEDCBA987)) + { + fail = true; + } + + if (!BicLSL(0xFFFFFFFF, 0x12345678, 0xDCBA987F)) + { + fail = true; + } + + if (!BicLSR(0xFFFFFFFF, 0x12345678, 0xFFFEDCBA)) + { + fail = true; + } + + if (!BicASR(0xFFFF, 0x8765, 0xFEF1)) + { + fail = true; + } + + if (!BicLargeShift(0xFEFEFEFE, 1, 0xFEFCFEFE)) + { + fail = true; + } + + if (!BicLargeShift64Bit(0xFEFEFEFEFEFEFE, 0xFEDCBA98765432, 0xFEFEFEFEF01234)) + { + fail = true; + } + + if (Bics(0xFFFFFFFF, 0x100) != 1) + { + fail = true; + } + + if (BicsLSL(0xFFFFFFFF, 1) != 1) + { + fail = true; + } + + if (BicsLSR(0xFFFFFFFF, 0x87654321) != 1) + { + fail = true; + } + + if (BicsASR(0xFFFF, 0x8F6E) != 1) + { + fail = true; + } + + if (BicsLargeShift(0xFFFFFFFF, 0x87654321) != 1) + { + fail = true; + } + + if (BicsLargeShift64Bit(0xFFFFFFFFFFFFFFFF, 0xFEDCBA9876543210) != 1) + { + fail = true; + } + + if (fail) + { + return 101; + } + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool Bic(uint a, uint b, uint c) + { + //ARM64-FULL-LINE: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + if ((a & ~b) == c) + { + return true; + } + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool BicLSL(uint a, uint b, uint c) + { + //ARM64-FULL-LINE: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, LSL #4 + if ((a & ~(b<<4)) == c) + { + return true; + } + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool BicLSR(uint a, uint b, uint c) + { + //ARM64-FULL-LINE: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, LSR #12 + if ((a & ~(b>>12)) == c) + { + return true; + } + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool BicASR(int a, int b, int c) + { + //ARM64-FULL-LINE: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ASR #7 + if ((a & ~(b>>7)) == c) + { + return true; + } + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool BicLargeShift(uint a, uint b, uint c) + { + //ARM64-FULL-LINE: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, LSL #17 + if ((a & ~(b<<145)) == c) + { + return true; + } + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool BicLargeShift64Bit(long a, long b, long c) + { + //ARM64-FULL-LINE: bic {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, ASR #36 + if ((a & ~(b>>292)) == c) + { + return true; + } + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int Bics(uint a, uint b) + { + //ARM64-FULL-LINE: bics {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + if ((a & ~b) == 0) + { + return -1; + } + return 1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int BicsLSL(uint a, uint b) + { + //ARM64-FULL-LINE: bics {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, LSL #31 + if ((a & ~(b<<31)) == 0) + { + return -1; + } + return 1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int BicsLSR(uint a, uint b) + { + //ARM64-FULL-LINE: bics {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, LSR #20 + if ((a & ~(b>>20)) == 0) + { + return -1; + } + return 1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int BicsASR(int a, int b) + { + //ARM64-FULL-LINE: bics {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ASR #9 + if ((a & ~(b>>9)) == 0) + { + return -1; + } + return 1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int BicsLargeShift(uint a, uint b) + { + //ARM64-FULL-LINE: bics {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, LSR #3 + if ((a & ~(b>>99)) == 0) + { + return -1; + } + return 1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int BicsLargeShift64Bit(ulong a, ulong b) + { + //ARM64-FULL-LINE: bics {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, LSL #51 + if ((a & ~(b<<179)) == 0) + { + return -1; + } + return 1; + } + } +} diff --git a/src/tests/JIT/opt/InstructionCombining/BitwiseClearShift.csproj b/src/tests/JIT/opt/InstructionCombining/BitwiseClearShift.csproj new file mode 100644 index 00000000000000..fa7abf5d8a8d0b --- /dev/null +++ b/src/tests/JIT/opt/InstructionCombining/BitwiseClearShift.csproj @@ -0,0 +1,17 @@ + + + + true + + + None + True + + + + true + + + + +