diff --git a/src/runtime/docs/workflow/requirements/macos-requirements.md b/src/runtime/docs/workflow/requirements/macos-requirements.md index 67e7840a64d..cd1aed4b8f1 100644 --- a/src/runtime/docs/workflow/requirements/macos-requirements.md +++ b/src/runtime/docs/workflow/requirements/macos-requirements.md @@ -18,7 +18,6 @@ To build the runtime repo, you will also need to install the following dependenc - `CMake` 3.20 or newer - `icu4c` -- `openssl@1.1` or `openssl@3` - `pkg-config` - `python3` - `ninja` (This one is optional. It is an alternative tool to `make` for building native code) diff --git a/src/runtime/eng/native/build-commons.sh b/src/runtime/eng/native/build-commons.sh index 2bc1faf27e7..a3bdc2ac190 100755 --- a/src/runtime/eng/native/build-commons.sh +++ b/src/runtime/eng/native/build-commons.sh @@ -70,7 +70,7 @@ build_native() # Let users provide additional compiler/linker flags via EXTRA_CFLAGS/EXTRA_CXXFLAGS/EXTRA_LDFLAGS. # If users directly override CFLAG/CXXFLAGS/LDFLAGS, that may lead to some configure tests working incorrectly. # See https://github.com/dotnet/runtime/issues/35727 for more information. - # + # # These flags MUST be exported before gen-buildsys.sh runs or cmake will ignore them # export CFLAGS="${CFLAGS} ${EXTRA_CFLAGS}" @@ -547,6 +547,9 @@ elif [[ "$__TargetOS" == ios || "$__TargetOS" == iossimulator ]]; then elif [[ "$__TargetOS" == tvos || "$__TargetOS" == tvossimulator ]]; then # nothing to do here true +elif [[ "$__TargetOS" == osx || "$__TargetOS" == maccatalyst ]]; then + # nothing to do here + true elif [[ "$__TargetOS" == android ]]; then # nothing to do here true diff --git a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml index 417241706c4..fa627d38ddd 100644 --- a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml +++ b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml @@ -76,7 +76,7 @@ jobs: nameSuffix: AllSubsets_Mono isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAdditionalTimezoneChecks=true - timeoutInMinutes: 480 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml @@ -107,7 +107,7 @@ jobs: nameSuffix: AllSubsets_CoreCLR isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) - timeoutInMinutes: 480 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml diff --git a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml index b7b3774f0b5..6b8698f3bdc 100644 --- a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml +++ b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml @@ -111,7 +111,7 @@ jobs: nameSuffix: AllSubsets_Mono isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) - timeoutInMinutes: 180 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml diff --git a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml index 7f10d317464..82726e28094 100644 --- a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml +++ b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml @@ -42,7 +42,7 @@ jobs: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:IsManualOrRollingBuild=true /p:EnableAggressiveTrimming=false ${{ else }}: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:IsManualOrRollingBuild=true /p:EnableAggressiveTrimming=true - timeoutInMinutes: 480 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml @@ -81,7 +81,7 @@ jobs: testGroup: innerloop nameSuffix: AllSubsets_Mono_RuntimeTests buildArgs: -s mono+libs -c $(_BuildConfig) - timeoutInMinutes: 480 + timeoutInMinutes: 240 # extra steps, run tests extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml @@ -152,7 +152,7 @@ jobs: jobParameters: testGroup: innerloop nameSuffix: AllSubsets_NativeAOT_RuntimeTests - timeoutInMinutes: 480 + timeoutInMinutes: 240 buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig) # extra steps, run tests extraVariablesTemplates: diff --git a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml index 9f483dbbe75..03cc2d926a0 100644 --- a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml +++ b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml @@ -36,7 +36,7 @@ jobs: testGroup: innerloop nameSuffix: AllSubsets_Mono buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:RunAOTCompilation=true /p:MonoForceInterpreter=true - timeoutInMinutes: 180 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml @@ -119,7 +119,7 @@ jobs: jobParameters: testGroup: innerloop nameSuffix: AllSubsets_NativeAOT_RuntimeTests - timeoutInMinutes: 240 + timeoutInMinutes: 180 buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig) # extra steps, run tests extraVariablesTemplates: diff --git a/src/runtime/eng/pipelines/runtime.yml b/src/runtime/eng/pipelines/runtime.yml index 305bb899368..e213156d849 100644 --- a/src/runtime/eng/pipelines/runtime.yml +++ b/src/runtime/eng/pipelines/runtime.yml @@ -931,7 +931,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:EnableAdditionalTimezoneChecks=true - timeoutInMinutes: 480 + timeoutInMinutes: 120 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -961,7 +961,8 @@ extends: buildConfig: Release runtimeFlavor: coreclr platforms: - - android_x64 + # Tracking issue: https://github.com/dotnet/dnceng/issues/5909 + # - android_x64 - android_arm64 variables: # map dependencies variables to local variables @@ -973,7 +974,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_CoreCLR buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true - timeoutInMinutes: 480 + timeoutInMinutes: 120 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -1017,7 +1018,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:RunSmokeTestsOnly=true /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:EnableAggressiveTrimming=true - timeoutInMinutes: 480 + timeoutInMinutes: 120 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), diff --git a/src/runtime/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/runtime/src/coreclr/debug/daccess/dacdbiimpl.cpp index 80f3ca01758..a676f7f5fed 100644 --- a/src/runtime/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/runtime/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -4963,9 +4963,21 @@ void DacDbiInterfaceImpl::Hijack( // Setup context for hijack // T_CONTEXT ctx; +#if !defined(CROSS_COMPILE) && !defined(TARGET_WINDOWS) && (defined(DTCONTEXT_IS_AMD64) || defined(DTCONTEXT_IS_ARM64)) + // If the host or target is not Windows, then we can assume that the DT_CONTEXT + // is the same as the T_CONTEXT, except for the XSTATE registers. + static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT does not include the XSTATE registers"); +#else + // Since Dac + DBI are tightly coupled, context sizes should be the same. + static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size"); +#endif HRESULT hr = m_pTarget->GetThreadContext( dwThreadId, - CONTEXT_FULL, + CONTEXT_FULL | CONTEXT_FLOATING_POINT +#ifdef CONTEXT_EXTENDED_REGISTERS + | CONTEXT_EXTENDED_REGISTERS +#endif + , sizeof(DT_CONTEXT), (BYTE*) &ctx); IfFailThrow(hr); diff --git a/src/runtime/src/coreclr/debug/daccess/stdafx.h b/src/runtime/src/coreclr/debug/daccess/stdafx.h index bb7b7b2365d..bff6a4f6603 100644 --- a/src/runtime/src/coreclr/debug/daccess/stdafx.h +++ b/src/runtime/src/coreclr/debug/daccess/stdafx.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/src/runtime/src/coreclr/debug/di/process.cpp b/src/runtime/src/coreclr/debug/di/process.cpp index 28de989969e..132e8ab031d 100644 --- a/src/runtime/src/coreclr/debug/di/process.cpp +++ b/src/runtime/src/coreclr/debug/di/process.cpp @@ -5061,6 +5061,23 @@ void CordbProcess::RawDispatchEvent( case DB_IPCE_LOAD_MODULE: { + LOG((LF_CORDB, LL_INFO100, + "RCET::HRCE: load module (includes assembly loading) on thread %#x Asm:0x%08x AD:0x%08x \n", + dwVolatileThreadId, + VmPtrToCookie(pEvent->LoadModuleData.vmDomainAssembly), + VmPtrToCookie(pEvent->vmAppDomain))); + + _ASSERTE (pAppDomain != NULL); + + // Determine if this Assembly is cached. + CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->LoadModuleData.vmDomainAssembly); + _ASSERTE(pAssembly != NULL); // throws on error + + // If created, or have, an Assembly, notify callback. + { + PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); + hr = pCallback1->LoadAssembly(pAppDomain, pAssembly); + } _ASSERTE (pAppDomain != NULL); CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainAssembly); @@ -5375,29 +5392,6 @@ void CordbProcess::RawDispatchEvent( break; - case DB_IPCE_LOAD_ASSEMBLY: - { - LOG((LF_CORDB, LL_INFO100, - "RCET::HRCE: load assembly on thread %#x Asm:0x%08x AD:0x%08x \n", - dwVolatileThreadId, - VmPtrToCookie(pEvent->AssemblyData.vmDomainAssembly), - VmPtrToCookie(pEvent->vmAppDomain))); - - _ASSERTE (pAppDomain != NULL); - - // Determine if this Assembly is cached. - CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->AssemblyData.vmDomainAssembly); - _ASSERTE(pAssembly != NULL); // throws on error - - // If created, or have, an Assembly, notify callback. - { - PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - hr = pCallback1->LoadAssembly(pAppDomain, pAssembly); - } - } - - break; - case DB_IPCE_UNLOAD_ASSEMBLY: { LOG((LF_CORDB, LL_INFO100, "RCET::DRCE: unload assembly on thread %#x Asm:0x%x AD:0x%x\n", @@ -13281,9 +13275,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: hijack complete will restore context...\n")); DT_CONTEXT tempContext = { 0 }; #if defined(DT_CONTEXT_EXTENDED_REGISTERS) - tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS; + tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS; #else - tempContext.ContextFlags = DT_CONTEXT_FULL; + tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT; #endif HRESULT hr = pUnmanagedThread->GetThreadContext(&tempContext); _ASSERTE(SUCCEEDED(hr)); diff --git a/src/runtime/src/coreclr/debug/di/rsthread.cpp b/src/runtime/src/coreclr/debug/di/rsthread.cpp index 8b9ec41240e..07e591d15fb 100644 --- a/src/runtime/src/coreclr/debug/di/rsthread.cpp +++ b/src/runtime/src/coreclr/debug/di/rsthread.cpp @@ -3706,9 +3706,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() // to avoid getting incomplete information and corrupt the thread context DT_CONTEXT context; #if defined(DT_CONTEXT_EXTENDED_REGISTERS) - context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS; + context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS; #else - context.ContextFlags = DT_CONTEXT_FULL; + context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT; #endif BOOL succ = DbiGetThreadContext(m_handle, &context); _ASSERTE(succ); @@ -3719,9 +3719,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() LOG((LF_CORDB, LL_ERROR, "CUT::SFCHFS: DbiGetThreadContext error=0x%x\n", error)); } #if defined(DT_CONTEXT_EXTENDED_REGISTERS) - GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS; + GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS; #else - GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL; + GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT; #endif CORDbgCopyThreadContext(GetHijackCtx(), &context); LOG((LF_CORDB, LL_INFO10000, "CUT::SFCHFS: thread=0x%x Hijacking for sync. Original context is:\n", this)); diff --git a/src/runtime/src/coreclr/debug/ee/controller.cpp b/src/runtime/src/coreclr/debug/ee/controller.cpp index a7bed1a1001..f7dfde2ae67 100644 --- a/src/runtime/src/coreclr/debug/ee/controller.cpp +++ b/src/runtime/src/coreclr/debug/ee/controller.cpp @@ -67,9 +67,79 @@ bool DebuggerControllerPatch::IsSafeForStackTrace() } +#ifndef DACCESS_COMPILE #ifndef FEATURE_EMULATE_SINGLESTEP -// returns a pointer to the shared buffer. each call will AddRef() the object -// before returning it so callers only need to Release() when they're finished with it. + +// +// We have to have a whole separate function for this because you +// can't use __try in a function that requires object unwinding... +// + +LONG FilterAccessViolation2(LPEXCEPTION_POINTERS ep, PVOID pv) +{ + LIMITED_METHOD_CONTRACT; + + return (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} + +// This helper is required because the AVInRuntimeImplOkayHolder can not +// be directly placed inside the scope of a PAL_TRY +void _CopyInstructionBlockHelper(BYTE* to, const BYTE* from) +{ + AVInRuntimeImplOkayHolder AVOkay; + + // This function only copies the portion of the instruction that follows the + // breakpoint opcode, not the breakpoint itself + to += CORDbg_BREAK_INSTRUCTION_SIZE; + from += CORDbg_BREAK_INSTRUCTION_SIZE; + + // If an AV occurs because we walked off a valid page then we need + // to be certain that all bytes on the previous page were copied. + // We are certain that we copied enough bytes to contain the instruction + // because it must have fit within the valid page. + for (int i = 0; i < MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE; i++) + { + *to++ = *from++; + } + +} + +// WARNING: this function skips copying the first CORDbg_BREAK_INSTRUCTION_SIZE bytes by design +// See the comment at the callsite in DebuggerPatchSkip::DebuggerPatchSkip for more details on +// this +void DebuggerControllerPatch::CopyInstructionBlock(BYTE *to, const BYTE* from) +{ + // We wrap the memcpy in an exception handler to handle the + // extremely rare case where we're copying an instruction off the + // end of a method that is also at the end of a page, and the next + // page is unmapped. + struct Param + { + BYTE *to; + const BYTE* from; + } param; + param.to = to; + param.from = from; + PAL_TRY(Param *, pParam, ¶m) + { + _CopyInstructionBlockHelper(pParam->to, pParam->from); + } + PAL_EXCEPT_FILTER(FilterAccessViolation2) + { + // The whole point is that if we copy up the AV, then + // that's enough to execute, otherwise we would not have been + // able to execute the code anyway. So we just ignore the + // exception. + LOG((LF_CORDB, LL_INFO10000, + "DCP::CIP: AV copying instruction block ignored.\n")); + } + PAL_ENDTRY +} + + +// Creates a new shared patch bypass buffer +// AddRef() before returning it so callers need to Release() when they're finished with it. SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBuffer() { CONTRACTL @@ -79,27 +149,110 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu } CONTRACTL_END; - if (m_pSharedPatchBypassBuffer == NULL) + if (m_pSharedPatchBypassBuffer != NULL) { - void *pSharedPatchBypassBufferRX = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer)); + m_pSharedPatchBypassBuffer->AddRef(); + return m_pSharedPatchBypassBuffer; + } + + // NOTE: in order to correctly single-step RIP-relative writes on multiple threads we need to set up + // a shared buffer with the instruction and a buffer for the RIP-relative value so that all threads + // are working on the same copy. as the single-steps complete the modified data in the buffer is + // copied back to the real address to ensure proper execution of the program. + + SharedPatchBypassBuffer *pSharedPatchBypassBufferRX = (SharedPatchBypassBuffer*)g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer)); #if defined(HOST_OSX) && defined(HOST_ARM64) - ExecutableWriterHolder sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer)); - void *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW(); + ExecutableWriterHolder sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer)); + SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW(); #else // HOST_OSX && HOST_ARM64 - void *pSharedPatchBypassBufferRW = pSharedPatchBypassBufferRX; + SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = pSharedPatchBypassBufferRX; #endif // HOST_OSX && HOST_ARM64 - new (pSharedPatchBypassBufferRW) SharedPatchBypassBuffer(); - m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX; - - _ASSERTE(m_pSharedPatchBypassBuffer); - TRACE_ALLOC(m_pSharedPatchBypassBuffer); - } + new (pSharedPatchBypassBufferRW) SharedPatchBypassBuffer(); + m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX; + _ASSERTE(m_pSharedPatchBypassBuffer); + TRACE_ALLOC(m_pSharedPatchBypassBuffer); m_pSharedPatchBypassBuffer->AddRef(); + BYTE* patchBypassRW = pSharedPatchBypassBufferRW->PatchBypass; + BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass; + + LOG((LF_CORDB, LL_INFO10000, "DCP::CSPBB: Patch skip for opcode 0x%.4x at address %p buffer allocated at 0x%.8x\n", this->opcode, this->address, m_pSharedPatchBypassBuffer)); + + // CopyInstructionBlock copies all the code bytes except the breakpoint byte(s). + _ASSERTE( this->IsBound() ); + CopyInstructionBlock(patchBypassRW, (const BYTE *)this->address); + + // Technically, we could create a patch skipper for an inactive patch, but we rely on the opcode being + // set here. + _ASSERTE( this->IsActivated() ); + CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypassRW, this->opcode); + + LOG((LF_CORDB, LL_EVERYTHING, "DCP::CSPBB: SetInstruction was called\n")); + + // + // Look at instruction to get some attributes + // + InstructionAttribute instrAttrib = { 0 }; + NativeWalker::DecodeInstructionForPatchSkip(patchBypassRX, &instrAttrib); + +#if defined(TARGET_AMD64) + // The code below handles RIP-relative addressing on AMD64. The original implementation made the assumption that + // we are only using RIP-relative addressing to access read-only data (see VSW 246145 for more information). This + // has since been expanded to handle RIP-relative writes as well. + if (instrAttrib.m_dwOffsetToDisp != 0) + { + _ASSERTE(pSharedPatchBypassBufferRW != NULL); + _ASSERTE(instrAttrib.m_cbInstr != 0); + + // + // Populate the RIP-relative buffer with the current value if needed + // + + BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer; + + // Overwrite the *signed* displacement. + int dwOldDisp = *(int*)(&patchBypassRX[instrAttrib.m_dwOffsetToDisp]); + int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) - + (offsetof(SharedPatchBypassBuffer, PatchBypass) + instrAttrib.m_cbInstr); + *(int*)(&patchBypassRW[instrAttrib.m_dwOffsetToDisp]) = dwNewDisp; + + // This could be an LEA, which we'll just have to change into a MOV and copy the original address. + if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d)) + { + patchBypassRW[1] = 0x8b; // MOV reg, mem + _ASSERTE((int)sizeof(void*) <= SharedPatchBypassBuffer::cbBufferBypass); + *(void**)bufferBypassRW = (void*)(this->address + instrAttrib.m_cbInstr + dwOldDisp); + } + else + { + _ASSERTE(instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass); + // Copy the data into our buffer. + memcpy(bufferBypassRW, this->address + instrAttrib.m_cbInstr + dwOldDisp, instrAttrib.m_cOperandSize); + + if (instrAttrib.m_fIsWrite) + { + // save the actual destination address and size so when we TriggerSingleStep() we can update the value + pSharedPatchBypassBufferRW->RipTargetFixup = (UINT_PTR)(this->address + instrAttrib.m_cbInstr + dwOldDisp); + pSharedPatchBypassBufferRW->RipTargetFixupSize = instrAttrib.m_cOperandSize; + } + } + } + + #endif // TARGET_AMD64 + + m_pSharedPatchBypassBuffer->SetInstructionAttrib(instrAttrib); + + // Since we just created a new buffer of code, but the CPU caches code and may + // not be aware of our changes. This should force the CPU to dump any cached + // instructions it has in this region and load the new ones from memory + FlushInstructionCache(GetCurrentProcess(), patchBypassRW + CORDbg_BREAK_INSTRUCTION_SIZE, + MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE); + return m_pSharedPatchBypassBuffer; } #endif // !FEATURE_EMULATE_SINGLESTEP +#endif // !DACCESS_COMPILE // @todo - remove all this splicing trash // This Sort/Splice stuff just reorders the patches within a particular chain such @@ -4509,53 +4662,9 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread, // the single-step emulation itself. #ifndef FEATURE_EMULATE_SINGLESTEP - // NOTE: in order to correctly single-step RIP-relative writes on multiple threads we need to set up - // a shared buffer with the instruction and a buffer for the RIP-relative value so that all threads - // are working on the same copy. as the single-steps complete the modified data in the buffer is - // copied back to the real address to ensure proper execution of the program. - - // - // Create the shared instruction block. this will also create the shared RIP-relative buffer - // - + _ASSERTE(DebuggerController::HasLock()); m_pSharedPatchBypassBuffer = patch->GetOrCreateSharedPatchBypassBuffer(); -#if defined(HOST_OSX) && defined(HOST_ARM64) - ExecutableWriterHolder sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)m_pSharedPatchBypassBuffer, sizeof(SharedPatchBypassBuffer)); - SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW(); -#else // HOST_OSX && HOST_ARM64 - SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = m_pSharedPatchBypassBuffer; -#endif // HOST_OSX && HOST_ARM64 - - BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass; - BYTE* patchBypassRW = pSharedPatchBypassBufferRW->PatchBypass; - LOG((LF_CORDB, LL_INFO10000, "DPS::DPS: Patch skip for opcode 0x%.4x at address %p buffer allocated at 0x%.8x\n", patch->opcode, patch->address, m_pSharedPatchBypassBuffer)); - - // Copy the instruction block over to the patch skip - // WARNING: there used to be an issue here because CopyInstructionBlock copied the breakpoint from the - // jitted code stream into the patch buffer. Further below CORDbgSetInstruction would correct the - // first instruction. This buffer is shared by all threads so if another thread executed the buffer - // between this thread's execution of CopyInstructionBlock and CORDbgSetInstruction the wrong - // code would be executed. The bug has been fixed by changing CopyInstructionBlock to only copy - // the code bytes after the breakpoint. - // You might be tempted to stop copying the code at all, however that wouldn't work well with rejit. - // If we skip a breakpoint that is sitting at the beginning of a method, then the profiler rejits that - // method causing a jump-stamp to be placed, then we skip the breakpoint again, we need to make sure - // the 2nd skip executes the new jump-stamp code and not the original method prologue code. Copying - // the code every time ensures that we have the most up-to-date version of the code in the buffer. - _ASSERTE( patch->IsBound() ); - CopyInstructionBlock(patchBypassRW, (const BYTE *)patch->address); - - // Technically, we could create a patch skipper for an inactive patch, but we rely on the opcode being - // set here. - _ASSERTE( patch->IsActivated() ); - CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypassRW, patch->opcode); - - LOG((LF_CORDB, LL_EVERYTHING, "SetInstruction was called\n")); - // - // Look at instruction to get some attributes - // - - NativeWalker::DecodeInstructionForPatchSkip(patchBypassRX, &(m_instrAttrib)); + m_instrAttrib = m_pSharedPatchBypassBuffer->GetInstructionAttrib(); #ifdef OUT_OF_PROCESS_SETTHREADCONTEXT if (g_pDebugInterface->IsOutOfProcessSetContextEnabled() && m_instrAttrib.m_fIsCall) @@ -4564,51 +4673,6 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread, } #endif -#if defined(TARGET_AMD64) - - // The code below handles RIP-relative addressing on AMD64. The original implementation made the assumption that - // we are only using RIP-relative addressing to access read-only data (see VSW 246145 for more information). This - // has since been expanded to handle RIP-relative writes as well. - if (m_instrAttrib.m_dwOffsetToDisp != 0 && !IsInPlaceSingleStep()) - { - _ASSERTE(m_instrAttrib.m_cbInstr != 0); - - // - // Populate the RIP-relative buffer with the current value if needed - // - - BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer; - - // Overwrite the *signed* displacement. - int dwOldDisp = *(int*)(&patchBypassRX[m_instrAttrib.m_dwOffsetToDisp]); - int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) - - (offsetof(SharedPatchBypassBuffer, PatchBypass) + m_instrAttrib.m_cbInstr); - *(int*)(&patchBypassRW[m_instrAttrib.m_dwOffsetToDisp]) = dwNewDisp; - - // This could be an LEA, which we'll just have to change into a MOV and copy the original address. - if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d)) - { - patchBypassRW[1] = 0x8b; // MOV reg, mem - _ASSERTE((int)sizeof(void*) <= SharedPatchBypassBuffer::cbBufferBypass); - *(void**)bufferBypassRW = (void*)(patch->address + m_instrAttrib.m_cbInstr + dwOldDisp); - } - else - { - _ASSERTE(m_instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass); - // Copy the data into our buffer. - memcpy(bufferBypassRW, patch->address + m_instrAttrib.m_cbInstr + dwOldDisp, m_instrAttrib.m_cOperandSize); - - if (m_instrAttrib.m_fIsWrite) - { - // save the actual destination address and size so when we TriggerSingleStep() we can update the value - pSharedPatchBypassBufferRW->RipTargetFixup = (UINT_PTR)(patch->address + m_instrAttrib.m_cbInstr + dwOldDisp); - pSharedPatchBypassBufferRW->RipTargetFixupSize = m_instrAttrib.m_cOperandSize; - } - } - } - -#endif // TARGET_AMD64 - #endif // !FEATURE_EMULATE_SINGLESTEP // Signals our thread that the debugger will be manipulating the context @@ -4672,7 +4736,9 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread, #else // FEATURE_EMULATE_SINGLESTEP #ifdef TARGET_ARM64 - patchBypassRX = NativeWalker::SetupOrSimulateInstructionForPatchSkip(context, m_pSharedPatchBypassBuffer, (const BYTE *)patch->address, patch->opcode); + BYTE* patchBypassRX = NativeWalker::SetupOrSimulateInstructionForPatchSkip(context, m_pSharedPatchBypassBuffer, (const BYTE *)patch->address, patch->opcode); +#else + BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass; #endif //TARGET_ARM64 if (!IsInPlaceSingleStep()) @@ -4742,80 +4808,6 @@ void DebuggerPatchSkip::DebuggerDetachClean() #endif // !FEATURE_EMULATE_SINGLESTEP } - -// -// We have to have a whole separate function for this because you -// can't use __try in a function that requires object unwinding... -// - -LONG FilterAccessViolation2(LPEXCEPTION_POINTERS ep, PVOID pv) -{ - LIMITED_METHOD_CONTRACT; - - return (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; -} - -// This helper is required because the AVInRuntimeImplOkayHolder can not -// be directly placed inside the scope of a PAL_TRY -void _CopyInstructionBlockHelper(BYTE* to, const BYTE* from) -{ - AVInRuntimeImplOkayHolder AVOkay; - - // This function only copies the portion of the instruction that follows the - // breakpoint opcode, not the breakpoint itself - to += CORDbg_BREAK_INSTRUCTION_SIZE; - from += CORDbg_BREAK_INSTRUCTION_SIZE; - - // If an AV occurs because we walked off a valid page then we need - // to be certain that all bytes on the previous page were copied. - // We are certain that we copied enough bytes to contain the instruction - // because it must have fit within the valid page. - for (int i = 0; i < MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE; i++) - { - *to++ = *from++; - } - -} - -// WARNING: this function skips copying the first CORDbg_BREAK_INSTRUCTION_SIZE bytes by design -// See the comment at the callsite in DebuggerPatchSkip::DebuggerPatchSkip for more details on -// this -void DebuggerPatchSkip::CopyInstructionBlock(BYTE *to, const BYTE* from) -{ - // We wrap the memcpy in an exception handler to handle the - // extremely rare case where we're copying an instruction off the - // end of a method that is also at the end of a page, and the next - // page is unmapped. - struct Param - { - BYTE *to; - const BYTE* from; - } param; - param.to = to; - param.from = from; - PAL_TRY(Param *, pParam, ¶m) - { - _CopyInstructionBlockHelper(pParam->to, pParam->from); - } - PAL_EXCEPT_FILTER(FilterAccessViolation2) - { - // The whole point is that if we copy up the AV, then - // that's enough to execute, otherwise we would not have been - // able to execute the code anyway. So we just ignore the - // exception. - LOG((LF_CORDB, LL_INFO10000, - "DPS::DPS: AV copying instruction block ignored.\n")); - } - PAL_ENDTRY - - // We just created a new buffer of code, but the CPU caches code and may - // not be aware of our changes. This should force the CPU to dump any cached - // instructions it has in this region and load the new ones from memory - FlushInstructionCache(GetCurrentProcess(), to + CORDbg_BREAK_INSTRUCTION_SIZE, - MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE); -} - TP_RESULT DebuggerPatchSkip::TriggerPatch(DebuggerControllerPatch *patch, Thread *thread, TRIGGER_WHY tyWhy) diff --git a/src/runtime/src/coreclr/debug/ee/controller.h b/src/runtime/src/coreclr/debug/ee/controller.h index b02cd2802d9..32138edc36a 100644 --- a/src/runtime/src/coreclr/debug/ee/controller.h +++ b/src/runtime/src/coreclr/debug/ee/controller.h @@ -312,7 +312,11 @@ class SharedPatchBypassBuffer UINT_PTR RipTargetFixup; #endif + const InstructionAttribute& GetInstructionAttrib() { return m_instrAttrib; } + void SetInstructionAttrib(const InstructionAttribute& instrAttrib) { m_instrAttrib = instrAttrib; } + private: + InstructionAttribute m_instrAttrib; // info about the instruction being skipped over const static DWORD SentinelValue = 0xffffffff; LONG m_refCount; }; @@ -550,10 +554,13 @@ struct DebuggerControllerPatch // Is this patch at a position at which it's safe to take a stack? bool IsSafeForStackTrace(); +#ifndef DACCESS_COMPILE #ifndef FEATURE_EMULATE_SINGLESTEP // gets a pointer to the shared buffer SharedPatchBypassBuffer* GetOrCreateSharedPatchBypassBuffer(); + void CopyInstructionBlock(BYTE *to, const BYTE* from); + // entry point for general initialization when the controller is being created void Initialize() { @@ -567,6 +574,7 @@ struct DebuggerControllerPatch m_pSharedPatchBypassBuffer->Release(); } #endif // !FEATURE_EMULATE_SINGLESTEP +#endif // !DACCESS_COMPILE void LogInstance() { @@ -1515,8 +1523,6 @@ class DebuggerPatchSkip : public DebuggerController virtual DEBUGGER_CONTROLLER_TYPE GetDCType(void) { return DEBUGGER_CONTROLLER_PATCH_SKIP; } - void CopyInstructionBlock(BYTE *to, const BYTE* from); - void DecodeInstruction(CORDB_ADDRESS_TYPE *code); void DebuggerDetachClean(); diff --git a/src/runtime/src/coreclr/debug/ee/debugger.cpp b/src/runtime/src/coreclr/debug/ee/debugger.cpp index 9a935112a09..7d7c4e9b96b 100644 --- a/src/runtime/src/coreclr/debug/ee/debugger.cpp +++ b/src/runtime/src/coreclr/debug/ee/debugger.cpp @@ -9250,62 +9250,6 @@ void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain) } - -// -// LoadAssembly is called when a new Assembly gets loaded. -// -void Debugger::LoadAssembly(DomainAssembly * pDomainAssembly) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT; - } - CONTRACTL_END; - - if (CORDBUnrecoverableError(this)) - return; - - LOG((LF_CORDB, LL_INFO100, "D::LA: Load Assembly Asy:0x%p AD:0x%p which:%s\n", - pDomainAssembly, AppDomain::GetCurrentDomain(), pDomainAssembly->GetAssembly()->GetDebugName() )); - - if (!CORDebuggerAttached()) - { - return; - } - - Thread *pThread = g_pEEInterface->GetThread(); - SENDIPCEVENT_BEGIN(this, pThread) - - - if (CORDebuggerAttached()) - { - // Send a load assembly event to the Right Side. - DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer(); - InitIPCEvent(ipce, - DB_IPCE_LOAD_ASSEMBLY, - pThread); - - ipce->AssemblyData.vmDomainAssembly.SetRawPtr(pDomainAssembly); - - m_pRCThread->SendIPCEvent(); - } - else - { - LOG((LF_CORDB,LL_INFO1000, "D::LA: Skipping SendIPCEvent because RS detached.")); - } - - // Stop all Runtime threads - if (CORDebuggerAttached()) - { - TrapAllRuntimeThreads(); - } - - SENDIPCEVENT_END; -} - - - // // UnloadAssembly is called when a Runtime thread unloads an assembly. // diff --git a/src/runtime/src/coreclr/debug/ee/debugger.h b/src/runtime/src/coreclr/debug/ee/debugger.h index 15915b00d72..79ba57770b2 100644 --- a/src/runtime/src/coreclr/debug/ee/debugger.h +++ b/src/runtime/src/coreclr/debug/ee/debugger.h @@ -2623,9 +2623,6 @@ class Debugger : public DebugInterface void SendCreateAppDomainEvent(AppDomain * pAppDomain); - // Notify the debugger that an assembly has been loaded - void LoadAssembly(DomainAssembly * pDomainAssembly); - // Notify the debugger that an assembly has been unloaded void UnloadAssembly(DomainAssembly * pDomainAssembly); diff --git a/src/runtime/src/coreclr/debug/ee/walker.h b/src/runtime/src/coreclr/debug/ee/walker.h index 63bd4cfa2fd..4dcae6d75ed 100644 --- a/src/runtime/src/coreclr/debug/ee/walker.h +++ b/src/runtime/src/coreclr/debug/ee/walker.h @@ -62,6 +62,8 @@ struct InstructionAttribute } }; +#ifndef DACCESS_COMPILE + /* ------------------------------------------------------------------------- * * Classes * ------------------------------------------------------------------------- */ @@ -280,4 +282,6 @@ class NativeWalker : public Walker }; #endif +#endif // DACCESS_COMPILE + #endif // WALKER_H_ diff --git a/src/runtime/src/coreclr/debug/inc/dbgtargetcontext.h b/src/runtime/src/coreclr/debug/inc/dbgtargetcontext.h index ea374cf8b6d..606e4954b35 100644 --- a/src/runtime/src/coreclr/debug/inc/dbgtargetcontext.h +++ b/src/runtime/src/coreclr/debug/inc/dbgtargetcontext.h @@ -474,7 +474,7 @@ typedef DECLSPEC_ALIGN(16) struct { #if !defined(CROSS_COMPILE) && !defined(TARGET_WINDOWS) -static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT must not include the SVE registers on AMD64"); +static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT must not include the SVE registers on ARM64"); #else static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size on ARM64"); #endif diff --git a/src/runtime/src/coreclr/inc/corinfo.h b/src/runtime/src/coreclr/inc/corinfo.h index 313d67a11ec..ff0420c7995 100644 --- a/src/runtime/src/coreclr/inc/corinfo.h +++ b/src/runtime/src/coreclr/inc/corinfo.h @@ -3139,12 +3139,6 @@ class ICorDynamicInfo : public ICorStaticInfo CORINFO_CONST_LOOKUP * pResult ) = 0; - // get the synchronization handle that is passed to monXstatic function - virtual void* getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection = NULL - ) = 0; - // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*). // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used. virtual CorInfoHelpFunc getLazyStringLiteralHelper( diff --git a/src/runtime/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/runtime/src/coreclr/inc/icorjitinfoimpl_generated.h index ee74e9c984f..472ada1cdd6 100644 --- a/src/runtime/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/runtime/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -550,10 +550,6 @@ void getFunctionFixedEntryPoint( bool isUnsafeFunctionPointer, CORINFO_CONST_LOOKUP* pResult) override; -void* getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) override; - CorInfoHelpFunc getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) override; diff --git a/src/runtime/src/coreclr/inc/jiteeversionguid.h b/src/runtime/src/coreclr/inc/jiteeversionguid.h index 79b7eda125f..7043a7fa2f5 100644 --- a/src/runtime/src/coreclr/inc/jiteeversionguid.h +++ b/src/runtime/src/coreclr/inc/jiteeversionguid.h @@ -37,11 +37,11 @@ #include -constexpr GUID JITEEVersionIdentifier = { /* 952f0344-7651-46af-8ef3-a34539af5c4a */ - 0x952f0344, - 0x7651, - 0x46af, - {0x8e, 0xf3, 0xa3, 0x45, 0x39, 0xaf, 0x5c, 0x4a} +constexpr GUID JITEEVersionIdentifier = { /* d24a67e0-9e57-4c9e-ad31-5785df2526f2 */ + 0xd24a67e0, + 0x9e57, + 0x4c9e, + {0xad, 0x31, 0x57, 0x85, 0xdf, 0x25, 0x26, 0xf2} }; #endif // JIT_EE_VERSIONING_GUID_H diff --git a/src/runtime/src/coreclr/interpreter/compiler.cpp b/src/runtime/src/coreclr/interpreter/compiler.cpp index cb585f78268..51dce8717e4 100644 --- a/src/runtime/src/coreclr/interpreter/compiler.cpp +++ b/src/runtime/src/coreclr/interpreter/compiler.cpp @@ -2157,32 +2157,34 @@ int32_t InterpCompiler::GetMethodDataItemIndex(CORINFO_METHOD_HANDLE mHandle) return GetDataItemIndex((void*)mHandle); } -int32_t InterpCompiler::GetDataItemIndexForHelperFtn(CorInfoHelpFunc ftn) +int32_t InterpCompiler::GetDataForHelperFtn(CorInfoHelpFunc ftn) { // Interpreter-TODO: Find an existing data item index for this helper if possible and reuse it CORINFO_CONST_LOOKUP ftnLookup; m_compHnd->getHelperFtn(ftn, &ftnLookup); - void* addr = ftnLookup.addr; - if (ftnLookup.accessType == IAT_VALUE) - { - // We can't use the 1 bit to mark indirect addresses because it is used for real code on arm32 (the thumb bit) - // So instead, we mark direct addresses with a 1 and then on the other end we will clear the 1 and re-set it as needed for thumb - addr = (void*)((size_t)addr | INTERP_DIRECT_HELPER_TAG); - } - else if (ftnLookup.accessType == IAT_PPVALUE) - NO_WAY("IAT_PPVALUE helpers not implemented in interpreter"); #ifdef DEBUG - if (!PointerInNameMap(addr)) + if (!PointerInNameMap(ftnLookup.addr)) { const char* name = CorInfoHelperToName(ftn); if (name) - AddPointerToNameMap(addr, name); + AddPointerToNameMap(ftnLookup.addr, name); } #endif - assert(ftnLookup.accessType == IAT_VALUE || ftnLookup.accessType == IAT_PVALUE); - return GetDataItemIndex(addr); + static_assert(sizeof(InterpHelperData) == sizeof(int32_t), "InterpHelperData must be the same size as an int32_t"); + + InterpHelperData result; + result.accessType = ftnLookup.accessType; + int32_t dataItemIndex = GetDataItemIndex(ftnLookup.addr); + result.addressDataItemIndex = dataItemIndex; + + if (((int32_t)result.addressDataItemIndex != dataItemIndex) || ((InfoAccessType)result.accessType != ftnLookup.accessType)) + NO_WAY("Over/underflow in GetDataForHelperFtn"); + + int32_t packed; + memcpy(&packed, &result, sizeof(result)); + return packed; } static int32_t GetLdindForType(InterpType interpType) @@ -2373,49 +2375,6 @@ bool InterpCompiler::EmitNamedIntrinsicCall(NamedIntrinsic ni, CORINFO_CLASS_HAN } } -bool InterpCompiler::EmitCallIntrinsics(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig) -{ - const char *className = NULL; - const char *namespaceName = NULL; - const char *methodName = m_compHnd->getMethodNameFromMetadata(method, &className, &namespaceName, NULL, 0); - - if (namespaceName && !strcmp(namespaceName, "System")) - { - if (className && !strcmp(className, "Environment")) - { - if (methodName && !strcmp(methodName, "FailFast")) - { - AddIns(INTOP_FAILFAST); // to be removed, not really an intrisic - m_pStackPointer--; - return true; - } - } - else if (className && !strcmp(className, "Object")) - { - // This is needed at this moment because we don't have support for interop - // with compiled code, but it might make sense in the future for this to remain - // in order to avoid redundant interp to jit transition. - if (methodName && !strcmp(methodName, ".ctor")) - { - AddIns(INTOP_NOP); - m_pStackPointer--; - return true; - } - } - else if (className && !strcmp(className, "GC")) - { - if (methodName && !strcmp(methodName, "Collect")) - { - AddIns(INTOP_GC_COLLECT); - // Not reducing the stack pointer because we expect the version with no arguments - return true; - } - } - } - - return false; -} - void InterpCompiler::ResolveToken(uint32_t token, CorInfoTokenKind tokenKind, CORINFO_RESOLVED_TOKEN *pResolvedToken) { pResolvedToken->tokenScope = m_compScopeHnd; @@ -2520,7 +2479,7 @@ void InterpCompiler::EmitPushHelperCall_2(const CorInfoHelpFunc ftn, const CORIN if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_CALL_HELPER_P_GS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, arg2); @@ -2529,7 +2488,7 @@ void InterpCompiler::EmitPushHelperCall_2(const CorInfoHelpFunc ftn, const CORIN else { AddIns(INTOP_CALL_HELPER_P_PS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(arg2); @@ -2547,7 +2506,7 @@ void InterpCompiler::EmitPushUnboxAny(const CORINFO_GENERICHANDLE_RESULT& arg1, if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_UNBOX_ANY_GENERIC); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_UNBOX); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_UNBOX); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, arg2); @@ -2556,7 +2515,7 @@ void InterpCompiler::EmitPushUnboxAny(const CORINFO_GENERICHANDLE_RESULT& arg1, else { AddIns(INTOP_UNBOX_ANY); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_UNBOX); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_UNBOX); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(arg2); @@ -2574,7 +2533,7 @@ void InterpCompiler::EmitPushUnboxAnyNullable(const CORINFO_GENERICHANDLE_RESULT if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_CALL_HELPER_V_AGS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_UNBOX_NULLABLE); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_UNBOX_NULLABLE); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, arg2); @@ -2583,7 +2542,7 @@ void InterpCompiler::EmitPushUnboxAnyNullable(const CORINFO_GENERICHANDLE_RESULT else { AddIns(INTOP_CALL_HELPER_V_APS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_UNBOX_NULLABLE); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_UNBOX_NULLABLE); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(arg2); @@ -2601,7 +2560,7 @@ void InterpCompiler::EmitPushHelperCall_Addr2(const CorInfoHelpFunc ftn, const C if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_CALL_HELPER_P_GA); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, arg2); @@ -2610,7 +2569,7 @@ void InterpCompiler::EmitPushHelperCall_Addr2(const CorInfoHelpFunc ftn, const C else { AddIns(INTOP_CALL_HELPER_P_PA); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(arg2); @@ -2628,7 +2587,7 @@ void InterpCompiler::EmitPushHelperCall(const CorInfoHelpFunc ftn, const CORINFO if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_CALL_HELPER_P_G); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(handleData.genericVar); @@ -2637,7 +2596,7 @@ void InterpCompiler::EmitPushHelperCall(const CorInfoHelpFunc ftn, const CORINFO else { AddIns(INTOP_CALL_HELPER_P_P); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetDVar(resultVar); @@ -2789,12 +2748,6 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re } } - if (EmitCallIntrinsics(callInfo.hMethod, callInfo.sig)) - { - m_ip += 5; - return; - } - if (callInfo.thisTransform != CORINFO_NO_THIS_TRANSFORM) { assert(pConstrainedToken != NULL); @@ -3027,6 +2980,10 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re } } m_pLastNewIns->data[0] = GetDataItemIndex(callInfo.hMethod); + + // Ensure that the dvar does not overlap with the svars; it is incorrect for it to overlap because + // the process of initializing the result may trample the args. + m_pVars[dVar].noCallArgs = true; } else if ((callInfo.classFlags & CORINFO_FLG_ARRAY) && newObj) { @@ -3326,7 +3283,7 @@ void InterpCompiler::EmitStaticFieldAddress(CORINFO_FIELD_INFO *pFieldInfo, CORI } // Call helper to obtain thread static base address AddIns(INTOP_CALL_HELPER_P_P); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(pFieldInfo->helper); + m_pLastNewIns->data[0] = GetDataForHelperFtn(pFieldInfo->helper); m_pLastNewIns->data[1] = GetDataItemIndex(helperArg); PushInterpType(InterpTypeByRef, NULL); m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); @@ -3521,7 +3478,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) if (!kind.needsRuntimeLookup) { AddIns(INTOP_CALL_HELPER_P_P); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_INITCLASS); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_INITCLASS); m_pLastNewIns->data[1] = GetDataItemIndex(m_classHnd); PushInterpType(InterpTypeI, NULL); m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); @@ -3533,7 +3490,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) { case CORINFO_LOOKUP_CLASSPARAM: AddIns(INTOP_CALL_HELPER_P_S); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_INITCLASS); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_INITCLASS); m_pLastNewIns->SetSVar(getParamArgIndex()); PushInterpType(InterpTypeI, NULL); m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); @@ -3550,7 +3507,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) m_pStackPointer--; AddIns(INTOP_CALL_HELPER_P_SP); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_INITINSTCLASS); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_INITINSTCLASS); m_pLastNewIns->data[1] = GetDataItemIndex(m_methodHnd); m_pLastNewIns->SetSVar(thisObjMethodTablePtrVar); PushInterpType(InterpTypeI, NULL); @@ -3561,7 +3518,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) case CORINFO_LOOKUP_METHODPARAM: { AddIns(INTOP_CALL_HELPER_P_PS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_INITINSTCLASS); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_INITINSTCLASS); m_pLastNewIns->data[1] = GetDataItemIndex(0); m_pLastNewIns->SetSVar(getParamArgIndex()); PushInterpType(InterpTypeI, NULL); @@ -5628,7 +5585,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) AddIns(INTOP_NEWARR_GENERIC); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(helpFunc); + m_pLastNewIns->data[0] = GetDataForHelperFtn(helpFunc); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, newArrLenVar); @@ -5638,7 +5595,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) { AddIns(INTOP_NEWARR); m_pLastNewIns->data[0] = GetDataItemIndex(arrayClsHnd); - m_pLastNewIns->data[1] = GetDataItemIndexForHelperFtn(helpFunc); + m_pLastNewIns->data[1] = GetDataForHelperFtn(helpFunc); m_pLastNewIns->SetSVar(newArrLenVar); m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); @@ -6308,21 +6265,28 @@ void InterpCompiler::PrintPointer(void* pointer) #endif } -void InterpCompiler::PrintHelperFtn(void* helperDirectOrIndirect) +void InterpCompiler::PrintHelperFtn(int32_t _data) { - void* helperAddr = helperDirectOrIndirect; - - if (((size_t)helperDirectOrIndirect) & INTERP_DIRECT_HELPER_TAG) - { - helperAddr = (void*)(((size_t)helperDirectOrIndirect) & ~INTERP_DIRECT_HELPER_TAG); - printf(" (direct)"); - } - else - { - printf(" (indirect)"); - } + InterpHelperData data; + memcpy(&data, &_data, sizeof(int32_t)); + void *helperAddr = GetDataItemAtIndex(data.addressDataItemIndex); PrintPointer(helperAddr); + + switch (data.accessType) { + case IAT_PVALUE: + printf("(indirect) "); + break; + case IAT_PPVALUE: + printf("(double-indirect) "); + break; + case IAT_VALUE: + printf("(direct) "); + break; + default: + printf("(corrupted) "); + break; + } } void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int32_t *pData, int32_t opcode) @@ -6369,7 +6333,7 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3 } case InterpOpGenericHelperFtn: { - PrintHelperFtn((void*)GetDataItemAtIndex(pData[0])); + PrintHelperFtn(pData[0]); InterpGenericLookup *pGenericLookup = (InterpGenericLookup*)GetAddrOfDataItemAtIndex(pData[1]); PrintInterpGenericLookup(pGenericLookup); break; @@ -6413,21 +6377,23 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3 } case InterpOpHelperFtnNoArgs: { - PrintHelperFtn((void*)GetDataItemAtIndex(pData[0])); + PrintHelperFtn(pData[0]); break; } case InterpOpHelperFtn: { - PrintHelperFtn((void*)GetDataItemAtIndex(pData[0])); - printf(", "); - PrintPointer((void*)GetDataItemAtIndex(pData[1])); + PrintHelperFtn(pData[0]); + if (GetDataLen(opcode) > 1) { + printf(", "); + PrintPointer((void*)GetDataItemAtIndex(pData[1])); + } break; } case InterpOpPointerHelperFtn: { PrintPointer((void*)GetDataItemAtIndex(pData[0])); printf(", "); - PrintHelperFtn((void*)GetDataItemAtIndex(pData[1])); + PrintHelperFtn(pData[1]); break; } case InterpOpPointerInt: diff --git a/src/runtime/src/coreclr/interpreter/compiler.h b/src/runtime/src/coreclr/interpreter/compiler.h index 1ea75c8db43..15d0050d074 100644 --- a/src/runtime/src/coreclr/interpreter/compiler.h +++ b/src/runtime/src/coreclr/interpreter/compiler.h @@ -527,7 +527,7 @@ class InterpCompiler void* GetDataItemAtIndex(int32_t index); void* GetAddrOfDataItemAtIndex(int32_t index); int32_t GetMethodDataItemIndex(CORINFO_METHOD_HANDLE mHandle); - int32_t GetDataItemIndexForHelperFtn(CorInfoHelpFunc ftn); + int32_t GetDataForHelperFtn(CorInfoHelpFunc ftn); void GenerateCode(CORINFO_METHOD_INFO* methodInfo); InterpBasicBlock* GenerateCodeForFinallyCallIslands(InterpBasicBlock *pNewBB, InterpBasicBlock *pPrevBB); @@ -697,7 +697,6 @@ class InterpCompiler void EmitCompareOp(int32_t opBase); void EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool readonly, bool tailcall, bool newObj, bool isCalli); bool EmitNamedIntrinsicCall(NamedIntrinsic ni, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig); - bool EmitCallIntrinsics(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig); void EmitLdind(InterpType type, CORINFO_CLASS_HANDLE clsHnd, int32_t offset); void EmitStind(InterpType type, CORINFO_CLASS_HANDLE clsHnd, int32_t offset, bool reverseSVarOrder); void EmitLdelem(int32_t opcode, InterpType type); @@ -745,7 +744,7 @@ class InterpCompiler void PrintBBCode(InterpBasicBlock *pBB); void PrintIns(InterpInst *ins); void PrintPointer(void* pointer); - void PrintHelperFtn(void* helperAddr); + void PrintHelperFtn(int32_t _data); void PrintInsData(InterpInst *ins, int32_t offset, const int32_t *pData, int32_t opcode); void PrintCompiledCode(); void PrintCompiledIns(const int32_t *ip, const int32_t *start); diff --git a/src/runtime/src/coreclr/interpreter/interpretershared.h b/src/runtime/src/coreclr/interpreter/interpretershared.h index 210bc1c1ad3..b4bb490237e 100644 --- a/src/runtime/src/coreclr/interpreter/interpretershared.h +++ b/src/runtime/src/coreclr/interpreter/interpretershared.h @@ -17,7 +17,10 @@ #define INTERP_STACK_SLOT_SIZE 8 // Alignment of each var offset on the interpreter stack #define INTERP_STACK_ALIGNMENT 16 // Alignment of interpreter stack at the start of a frame -#define INTERP_DIRECT_HELPER_TAG 1 // When a helper ftn's address is direct we tag it with this tag bit +struct InterpHelperData { + uint32_t addressDataItemIndex : 29; + uint32_t accessType : 3; +}; struct CallStubHeader; diff --git a/src/runtime/src/coreclr/interpreter/intops.def b/src/runtime/src/coreclr/interpreter/intops.def index 8de811f7b52..0e1d73769a4 100644 --- a/src/runtime/src/coreclr/interpreter/intops.def +++ b/src/runtime/src/coreclr/interpreter/intops.def @@ -400,8 +400,6 @@ OPDEF(INTOP_LEAVE_CATCH, "leavecatch", 2, 0, 0, InterpOpBranch) OPDEF(INTOP_LOAD_EXCEPTION, "load.exception", 2, 1, 0, InterpOpNoArgs) OPDEF(INTOP_THROW_PNSE, "throw.pnse", 1, 0, 0, InterpOpNoArgs) -OPDEF(INTOP_FAILFAST, "failfast", 1, 0, 0, InterpOpNoArgs) -OPDEF(INTOP_GC_COLLECT, "gc.collect", 1, 0, 0, InterpOpNoArgs) OPDEF(INTOP_LOAD_FRAMEVAR, "load.framevar", 2, 1, 0, InterpOpNoArgs) diff --git a/src/runtime/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/runtime/src/coreclr/jit/ICorJitInfo_names_generated.h index e8e089f0b1d..34972535019 100644 --- a/src/runtime/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/runtime/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -136,7 +136,6 @@ DEF_CLR_API(getAddrOfCaptureThreadGlobal) DEF_CLR_API(getHelperFtn) DEF_CLR_API(getFunctionEntryPoint) DEF_CLR_API(getFunctionFixedEntryPoint) -DEF_CLR_API(getMethodSync) DEF_CLR_API(getLazyStringLiteralHelper) DEF_CLR_API(embedModuleHandle) DEF_CLR_API(embedClassHandle) diff --git a/src/runtime/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/runtime/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index c2a8418e302..7ee76ced3f8 100644 --- a/src/runtime/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/runtime/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -1299,16 +1299,6 @@ void WrapICorJitInfo::getFunctionFixedEntryPoint( API_LEAVE(getFunctionFixedEntryPoint); } -void* WrapICorJitInfo::getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) -{ - API_ENTER(getMethodSync); - void* temp = wrapHnd->getMethodSync(ftn, ppIndirection); - API_LEAVE(getMethodSync); - return temp; -} - CorInfoHelpFunc WrapICorJitInfo::getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) { diff --git a/src/runtime/src/coreclr/jit/assertionprop.cpp b/src/runtime/src/coreclr/jit/assertionprop.cpp index 787897de5e1..ae68b1def58 100644 --- a/src/runtime/src/coreclr/jit/assertionprop.cpp +++ b/src/runtime/src/coreclr/jit/assertionprop.cpp @@ -5633,8 +5633,8 @@ bool Compiler::optCreateJumpTableImpliedAssertions(BasicBlock* switchBb) GenTree* switchTree = switchBb->lastStmt()->GetRootNode()->gtEffectiveVal(); assert(switchTree->OperIs(GT_SWITCH)); - // bbsCount is uint32_t, but it's unlikely to be more than INT32_MAX. - noway_assert(switchBb->GetSwitchTargets()->bbsCount <= INT32_MAX); + // Case count is uint32_t, but it's unlikely to be more than INT32_MAX. + noway_assert(switchBb->GetSwitchTargets()->GetCaseCount() <= INT32_MAX); ValueNum opVN = optConservativeNormalVN(switchTree->gtGetOp1()); if (opVN == ValueNumStore::NoVN) @@ -5652,9 +5652,9 @@ bool Compiler::optCreateJumpTableImpliedAssertions(BasicBlock* switchBb) int offset = 0; vnStore->PeelOffsetsI32(&opVN, &offset); - int jumpCount = static_cast(switchBb->GetSwitchTargets()->bbsCount); - FlowEdge** jumpTable = switchBb->GetSwitchTargets()->bbsDstTab; - bool hasDefault = switchBb->GetSwitchTargets()->bbsHasDefault; + int jumpCount = static_cast(switchBb->GetSwitchTargets()->GetCaseCount()); + FlowEdge** jumpTable = switchBb->GetSwitchTargets()->GetCases(); + bool hasDefault = switchBb->GetSwitchTargets()->HasDefaultCase(); for (int jmpTargetIdx = 0; jmpTargetIdx < jumpCount; jmpTargetIdx++) { @@ -5666,14 +5666,15 @@ bool Compiler::optCreateJumpTableImpliedAssertions(BasicBlock* switchBb) int value = jmpTargetIdx - offset; // We can only make "X == caseValue" assertions for blocks with a single edge from the switch. - BasicBlock* target = jumpTable[jmpTargetIdx]->getDestinationBlock(); + FlowEdge* const edge = jumpTable[jmpTargetIdx]; + BasicBlock* const target = edge->getDestinationBlock(); if (target->GetUniquePred(this) != switchBb) { // Target block is potentially reachable from multiple blocks (outside the switch). continue; } - if (fgGetPredForBlock(target, switchBb)->getDupCount() > 1) + if (edge->getDupCount() > 1) { // We have just one predecessor (BBJ_SWITCH), but there may be multiple edges (cases) per target. continue; diff --git a/src/runtime/src/coreclr/jit/async.cpp b/src/runtime/src/coreclr/jit/async.cpp index 7a26ab4b004..6dc06714054 100644 --- a/src/runtime/src/coreclr/jit/async.cpp +++ b/src/runtime/src/coreclr/jit/async.cpp @@ -290,12 +290,11 @@ BasicBlock* Compiler::InsertTryFinallyForContextRestore(BasicBlock* block, State block->SetTargetEdge(fgAddRefPred(callFinally, block)); callFinally->SetTargetEdge(fgAddRefPred(finallyRet, callFinally)); - BBehfDesc* ehfDesc = new (this, CMK_BasicBlock) BBehfDesc; - ehfDesc->bbeCount = 1; - ehfDesc->bbeSuccs = new (this, CMK_BasicBlock) FlowEdge* [1] { + FlowEdge** succs = new (this, CMK_BasicBlock) FlowEdge* [1] { fgAddRefPred(callFinallyRet, finallyRet) }; - ehfDesc->bbeSuccs[0]->setLikelihood(1.0); + succs[0]->setLikelihood(1.0); + BBJumpTable* ehfDesc = new (this, CMK_BasicBlock) BBJumpTable(succs, 1); finallyRet->SetEhfTargets(ehfDesc); callFinallyRet->SetTargetEdge(fgAddRefPred(goToTailBlock, callFinallyRet)); @@ -2288,18 +2287,26 @@ void AsyncTransformation::CreateResumptionSwitch() // Default case. TODO-CQ: Support bbsHasDefault = false before lowering. m_resumptionBBs.push_back(m_resumptionBBs[0]); - BBswtDesc* swtDesc = new (m_comp, CMK_BasicBlock) BBswtDesc; - swtDesc->bbsCount = (unsigned)m_resumptionBBs.size(); - swtDesc->bbsHasDefault = true; - swtDesc->bbsDstTab = new (m_comp, CMK_Async) FlowEdge*[m_resumptionBBs.size()]; + const size_t numCases = m_resumptionBBs.size(); + FlowEdge** const cases = new (m_comp, CMK_FlowEdge) FlowEdge*[numCases * 2]; + FlowEdge** const succs = cases + numCases; + unsigned numUniqueSuccs = 0; - weight_t stateLikelihood = 1.0 / m_resumptionBBs.size(); - for (size_t i = 0; i < m_resumptionBBs.size(); i++) + const weight_t stateLikelihood = 1.0 / m_resumptionBBs.size(); + for (size_t i = 0; i < numCases; i++) { - swtDesc->bbsDstTab[i] = m_comp->fgAddRefPred(m_resumptionBBs[i], switchBB); - swtDesc->bbsDstTab[i]->setLikelihood(stateLikelihood); + FlowEdge* const edge = m_comp->fgAddRefPred(m_resumptionBBs[i], switchBB); + edge->setLikelihood(stateLikelihood); + cases[i] = edge; + + if (edge->getDupCount() == 1) + { + succs[numUniqueSuccs++] = edge; + } } + BBswtDesc* const swtDesc = + new (m_comp, CMK_BasicBlock) BBswtDesc(cases, (unsigned)numCases, succs, numUniqueSuccs, true); switchBB->SetSwitch(swtDesc); } diff --git a/src/runtime/src/coreclr/jit/block.cpp b/src/runtime/src/coreclr/jit/block.cpp index 52f860ff736..a363e56c629 100644 --- a/src/runtime/src/coreclr/jit/block.cpp +++ b/src/runtime/src/coreclr/jit/block.cpp @@ -586,39 +586,10 @@ unsigned BasicBlock::dspPreds() const void BasicBlock::dspSuccs(Compiler* compiler) { bool first = true; - - // If this is a switch, we don't want to call `Succs(Compiler*)` because it will eventually call - // `GetSwitchDescMap()`, and that will have the side-effect of allocating the unique switch descriptor map - // and/or compute this switch block's unique succ set if it is not present. Debug output functions should - // never have an effect on codegen. We also don't want to assume the unique succ set is accurate, so we - // compute it ourselves here. - if (bbKind == BBJ_SWITCH) - { - // Create a set with all the successors. - unsigned bbNumMax = compiler->fgBBNumMax; - BitVecTraits bitVecTraits(bbNumMax + 1, compiler); - BitVec uniqueSuccBlocks(BitVecOps::MakeEmpty(&bitVecTraits)); - for (BasicBlock* const bTarget : SwitchTargets()) - { - BitVecOps::AddElemD(&bitVecTraits, uniqueSuccBlocks, bTarget->bbNum); - } - BitVecOps::Iter iter(&bitVecTraits, uniqueSuccBlocks); - unsigned bbNum = 0; - while (iter.NextElem(&bbNum)) - { - // Note that we will output switch successors in increasing numerical bbNum order, which is - // not related to their order in the bbSwtTargets->bbsDstTab table. - printf("%s" FMT_BB, first ? "" : ",", bbNum); - first = false; - } - } - else + for (const BasicBlock* const succ : Succs(compiler)) { - for (const BasicBlock* const succ : Succs(compiler)) - { - printf("%s" FMT_BB, first ? "" : ",", succ->bbNum); - first = false; - } + printf("%s" FMT_BB, first ? "" : ",", succ->bbNum); + first = false; } } @@ -672,12 +643,9 @@ void BasicBlock::dspKind() const } else { - const unsigned jumpCnt = bbEhfTargets->bbeCount; - FlowEdge** const jumpTab = bbEhfTargets->bbeSuccs; - - for (unsigned i = 0; i < jumpCnt; i++) + for (unsigned i = 0; i < bbEhfTargets->GetSuccCount(); i++) { - printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(jumpTab[i])); + printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(bbEhfTargets->GetSucc(i))); } } @@ -736,20 +704,20 @@ void BasicBlock::dspKind() const { printf(" ->"); - const unsigned jumpCnt = bbSwtTargets->bbsCount; - FlowEdge** const jumpTab = bbSwtTargets->bbsDstTab; + const unsigned jumpCnt = bbSwtTargets->GetCaseCount(); + FlowEdge** const jumpTab = bbSwtTargets->GetCases(); for (unsigned i = 0; i < jumpCnt; i++) { printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(jumpTab[i])); - const bool isDefault = bbSwtTargets->bbsHasDefault && (i == jumpCnt - 1); + const bool isDefault = bbSwtTargets->HasDefaultCase() && (i == jumpCnt - 1); if (isDefault) { printf("[def]"); } - const bool isDominant = bbSwtTargets->bbsHasDominantCase && (i == bbSwtTargets->bbsDominantCase); + const bool isDominant = bbSwtTargets->HasDominantCase() && (i == bbSwtTargets->GetDominantCase()); if (isDominant) { printf("[dom]"); @@ -1184,10 +1152,10 @@ unsigned BasicBlock::NumSucc() const return 0; } - return bbEhfTargets->bbeCount; + return bbEhfTargets->GetSuccCount(); case BBJ_SWITCH: - return bbSwtTargets->bbsCount; + return bbSwtTargets->GetCaseCount(); default: unreached(); @@ -1229,10 +1197,10 @@ FlowEdge* BasicBlock::GetSuccEdge(unsigned i) const } case BBJ_EHFINALLYRET: - return bbEhfTargets->bbeSuccs[i]; + return bbEhfTargets->GetSucc(i); case BBJ_SWITCH: - return bbSwtTargets->bbsDstTab[i]; + return bbSwtTargets->GetCase(i); default: unreached(); @@ -1288,7 +1256,7 @@ unsigned BasicBlock::NumSucc(Compiler* comp) return 0; } - return bbEhfTargets->bbeCount; + return bbEhfTargets->GetSuccCount(); case BBJ_CALLFINALLY: case BBJ_CALLFINALLYRET: @@ -1309,10 +1277,7 @@ unsigned BasicBlock::NumSucc(Compiler* comp) } case BBJ_SWITCH: - { - Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this); - return sd.numDistinctSuccs; - } + return bbSwtTargets->GetSuccCount(); default: unreached(); @@ -1343,8 +1308,7 @@ FlowEdge* BasicBlock::GetSuccEdge(unsigned i, Compiler* comp) case BBJ_EHFINALLYRET: assert(bbEhfTargets != nullptr); - assert(i < bbEhfTargets->bbeCount); - return bbEhfTargets->bbeSuccs[i]; + return bbEhfTargets->GetSucc(i); case BBJ_CALLFINALLY: case BBJ_CALLFINALLYRET: @@ -1366,11 +1330,7 @@ FlowEdge* BasicBlock::GetSuccEdge(unsigned i, Compiler* comp) } case BBJ_SWITCH: - { - Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this); - assert(i < sd.numDistinctSuccs); // Range check. - return sd.nonDuplicates[i]; - } + return bbSwtTargets->GetSucc(i); default: unreached(); @@ -1636,7 +1596,7 @@ BasicBlock* BasicBlock::New(Compiler* compiler, BBKinds kind) return block; } -BasicBlock* BasicBlock::New(Compiler* compiler, BBehfDesc* ehfTargets) +BasicBlock* BasicBlock::New(Compiler* compiler, BBJumpTable* ehfTargets) { BasicBlock* block = BasicBlock::New(compiler); block->SetEhf(ehfTargets); @@ -1758,21 +1718,6 @@ bool BasicBlock::hasEHBoundaryOut() const return KindIs(BBJ_EHFILTERRET, BBJ_EHFINALLYRET, BBJ_EHFAULTRET, BBJ_EHCATCHRET); } -//------------------------------------------------------------------------ -// BBswtDesc copy ctor: copy a switch descriptor, but don't set up the jump table -// -// Arguments: -// other - existing switch descriptor to copy (except for its jump table) -// -BBswtDesc::BBswtDesc(const BBswtDesc* other) - : bbsDstTab(nullptr) - , bbsCount(other->bbsCount) - , bbsDominantCase(other->bbsDominantCase) - , bbsHasDefault(other->bbsHasDefault) - , bbsHasDominantCase(other->bbsHasDominantCase) -{ -} - //------------------------------------------------------------------------ // BBswtDesc copy ctor: copy a switch descriptor // @@ -1781,38 +1726,33 @@ BBswtDesc::BBswtDesc(const BBswtDesc* other) // other - existing switch descriptor to copy // BBswtDesc::BBswtDesc(Compiler* comp, const BBswtDesc* other) - : bbsDstTab(nullptr) - , bbsCount(other->bbsCount) + : BBJumpTable(new(comp, CMK_FlowEdge) FlowEdge*[other->succCount + other->caseCount], other -> succCount) + , caseCount(other->caseCount) + , cases(succs + succCount) , bbsDominantCase(other->bbsDominantCase) , bbsHasDefault(other->bbsHasDefault) , bbsHasDominantCase(other->bbsHasDominantCase) { - // Allocate and fill in a new dst tab + // Fill in the new tables // - bbsDstTab = new (comp, CMK_FlowEdge) FlowEdge*[bbsCount]; - for (unsigned i = 0; i < bbsCount; i++) - { - bbsDstTab[i] = other->bbsDstTab[i]; - } + memcpy(succs, other->succs, sizeof(FlowEdge*) * succCount); + memcpy(cases, other->cases, sizeof(FlowEdge*) * caseCount); } //------------------------------------------------------------------------ -// BBehfDesc copy ctor: copy a EHFINALLYRET descriptor +// BBJumpTable copy ctor: copy a N-successor block descriptor // // Arguments: // comp - compiler instance // other - existing descriptor to copy // -BBehfDesc::BBehfDesc(Compiler* comp, const BBehfDesc* other) - : bbeCount(other->bbeCount) +BBJumpTable::BBJumpTable(Compiler* comp, const BBJumpTable* other) + : succs(new(comp, CMK_FlowEdge) FlowEdge*[other->succCount]) + , succCount(other->succCount) { - // Allocate and fill in a new dst tab + // Fill in the new jump table // - bbeSuccs = new (comp, CMK_FlowEdge) FlowEdge*[bbeCount]; - for (unsigned i = 0; i < bbeCount; i++) - { - bbeSuccs[i] = other->bbeSuccs[i]; - } + memcpy(succs, other->succs, sizeof(FlowEdge*) * succCount); } //------------------------------------------------------------------------ diff --git a/src/runtime/src/coreclr/jit/block.h b/src/runtime/src/coreclr/jit/block.h index c541fa5309c..e1ffa46cff0 100644 --- a/src/runtime/src/coreclr/jit/block.h +++ b/src/runtime/src/coreclr/jit/block.h @@ -107,7 +107,7 @@ struct BasicBlockList; struct FlowEdge; struct EHblkDsc; struct BBswtDesc; -struct BBehfDesc; +struct BBJumpTable; struct StackEntry { @@ -346,7 +346,7 @@ class BBArrayIterator } }; -// FlowEdgeArrayIterator: forward iterator for an array of FlowEdge*, such as the BBswtDesc->bbsDstTab. +// FlowEdgeArrayIterator: forward iterator for an array of FlowEdge*, such as BBJumpTable::succs. // It is an error (with assert) to yield a nullptr FlowEdge* in this array. // `m_edgeEntry` can be nullptr, but it only makes sense if both the begin and end of an iteration range are nullptr // (meaning, no actual iteration will happen). @@ -382,30 +382,16 @@ class FlowEdgeArrayIterator } }; -// BBSwitchTargetList: adapter class for forward iteration of switch targets, using range-based `for`, -// normally used via BasicBlock::SwitchTargets(), e.g.: -// for (BasicBlock* const target : block->SwitchTargets()) ... -// -class BBSwitchTargetList -{ - BBswtDesc* m_bbsDesc; - -public: - BBSwitchTargetList(BBswtDesc* bbsDesc); - BBArrayIterator begin() const; - BBArrayIterator end() const; -}; - -// BBEhfSuccList: adapter class for forward iteration of BBJ_EHFINALLYRET blocks, using range-based `for`, -// normally used via BasicBlock::EHFinallyRetSuccs(), e.g.: +// BBJumpTableList: adapter class for forward iteration of blocks with N successors, using range-based `for`, +// normally used via BasicBlock::EHFinallyRetSuccs() or BasicBlock::SwitchSuccs(), e.g.: // for (BasicBlock* const succ : block->EHFinallyRetSuccs()) ... // -class BBEhfSuccList +class BBJumpTableList { - BBehfDesc* m_bbeDesc; + BBJumpTable* m_bbJumpTable; public: - BBEhfSuccList(BBehfDesc* bbeDesc); + BBJumpTableList(BBJumpTable* bbJumpTable); BBArrayIterator begin() const; BBArrayIterator end() const; }; @@ -740,11 +726,11 @@ struct BasicBlock : private LIR::Range /* The following union describes the jump target(s) of this block */ union { - unsigned bbTargetOffs; // PC offset (temporary only) - FlowEdge* bbTargetEdge; // successor edge for block kinds with only one successor (BBJ_ALWAYS, etc) - FlowEdge* bbTrueEdge; // BBJ_COND successor edge when its condition is true (alias for bbTargetEdge) - BBswtDesc* bbSwtTargets; // switch descriptor - BBehfDesc* bbEhfTargets; // BBJ_EHFINALLYRET descriptor + unsigned bbTargetOffs; // PC offset (temporary only) + FlowEdge* bbTargetEdge; // successor edge for block kinds with only one successor (BBJ_ALWAYS, etc) + FlowEdge* bbTrueEdge; // BBJ_COND successor edge when its condition is true (alias for bbTargetEdge) + BBswtDesc* bbSwtTargets; // switch descriptor + BBJumpTable* bbEhfTargets; // BBJ_EHFINALLYRET descriptor }; // Successor edge of a BBJ_COND block if bbTrueEdge is not taken @@ -753,7 +739,7 @@ struct BasicBlock : private LIR::Range public: static BasicBlock* New(Compiler* compiler); static BasicBlock* New(Compiler* compiler, BBKinds kind); - static BasicBlock* New(Compiler* compiler, BBehfDesc* ehfTargets); + static BasicBlock* New(Compiler* compiler, BBJumpTable* ehfTargets); static BasicBlock* New(Compiler* compiler, BBswtDesc* swtTargets); static BasicBlock* New(Compiler* compiler, BBKinds kind, unsigned targetOffs); @@ -1029,19 +1015,19 @@ struct BasicBlock : private LIR::Range bbSwtTargets = swtTarget; } - BBehfDesc* GetEhfTargets() const + BBJumpTable* GetEhfTargets() const { assert(KindIs(BBJ_EHFINALLYRET)); return bbEhfTargets; } - void SetEhfTargets(BBehfDesc* ehfTarget) + void SetEhfTargets(BBJumpTable* ehfTarget) { assert(KindIs(BBJ_EHFINALLYRET)); bbEhfTargets = ehfTarget; } - void SetEhf(BBehfDesc* ehfTarget) + void SetEhf(BBJumpTable* ehfTarget) { assert(ehfTarget != nullptr); bbKind = BBJ_EHFINALLYRET; @@ -1405,23 +1391,24 @@ struct BasicBlock : private LIR::Range BasicBlock* GetSucc(unsigned i) const; BasicBlock* GetSucc(unsigned i, Compiler* comp); - // SwitchTargets: convenience method for enabling range-based `for` iteration over a switch block's targets, e.g.: - // for (BasicBlock* const bTarget : block->SwitchTargets()) ... + // SwitchSuccs: convenience method for enabling range-based `for` iteration over a switch block's unique successors, + // e.g.: + // for (BasicBlock* const bTarget : block->SwitchSuccs()) ... // - BBSwitchTargetList SwitchTargets() const + BBJumpTableList SwitchSuccs() const { assert(bbKind == BBJ_SWITCH); - return BBSwitchTargetList(bbSwtTargets); + return BBJumpTableList((BBJumpTable*)bbSwtTargets); } // EHFinallyRetSuccs: convenience method for enabling range-based `for` iteration over BBJ_EHFINALLYRET block // successors, e.g.: // for (BasicBlock* const succ : block->EHFinallyRetSuccs()) ... // - BBEhfSuccList EHFinallyRetSuccs() const + BBJumpTableList EHFinallyRetSuccs() const { assert(bbKind == BBJ_EHFINALLYRET); - return BBEhfSuccList(bbEhfTargets); + return BBJumpTableList(bbEhfTargets); } BasicBlock* GetUniquePred(Compiler* comp) const; @@ -2280,6 +2267,70 @@ class BasicBlockRangeList bool ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* count = nullptr); }; +// BBJumpTable -- descriptor blocks with N successors +// +struct BBJumpTable +{ +protected: + FlowEdge** succs; // array of unique `FlowEdge*` pointing to the block's successors + unsigned succCount; // Number of unique successors + +public: + BBJumpTable() + : succs(nullptr) + , succCount(0) + { + } + + BBJumpTable(FlowEdge** succs, unsigned succCount) + : succs(succs) + , succCount(succCount) + { + } + + BBJumpTable(Compiler* comp, const BBJumpTable* other); + + FlowEdge** GetSuccs() const + { + return succs; + } + + FlowEdge* GetSucc(unsigned index) const + { + assert(index < succCount); + assert(succs != nullptr); + return succs[index]; + } + + unsigned GetSuccCount() const + { + return succCount; + } + + void SetSuccs(FlowEdge** newSuccs, unsigned newSuccCount) + { + assert((newSuccs != nullptr) || (newSuccCount == 0)); + + succs = newSuccs; + succCount = newSuccCount; + } + + void RemoveSucc(unsigned index) + { + assert(index < succCount); + assert(succs != nullptr); + + // If succEdge is not the last entry, move everything after in the table down one slot. + if ((index + 1) < succCount) + { + memmove_s(succs + index, (succCount - index) * sizeof(FlowEdge*), succs + index + 1, + (succCount - index - 1) * sizeof(FlowEdge*)); + } + + succCount--; + } +}; + // BBswtDesc -- descriptor for a switch block // // Things to know: @@ -2289,11 +2340,20 @@ class BasicBlockRangeList // allows for a degenerate switch with zero cases. Normally, the optimizer will optimize degenerate // switches with just a default case to a BBJ_ALWAYS branch, and a switch with just two cases to a BBJ_COND. // However, in debuggable code, we might not do that, so bbsCount might be 1. +// 3. BBswtDesc makes no promises about the relative positions of the 'succs' and 'cases' arrays. +// Callers are responsible for allocating these arrays during BBswtDesc creation. +// A potential optimization is to allocate one array large enough for the two; +// this is safe, because BBswtDesc does not support adding new cases/successors. // -struct BBswtDesc +struct BBswtDesc : public BBJumpTable { - FlowEdge** bbsDstTab; // case label table address - unsigned bbsCount; // count of cases (includes 'default' if bbsHasDefault) +private: + // Inherited from BBJumpTable: + // FlowEdge** succs; // array of unique `FlowEdge*` pointing to the block's successors + // unsigned succCount; // Number of unique successors + + unsigned caseCount; // count of cases (includes 'default' if bbsHasDefault) + FlowEdge** cases; // array of non-unique FlowEdge* pointing to the switch cases // Case number of most likely case // (only known with PGO, only valid if bbsHasDominantCase is true) @@ -2302,86 +2362,114 @@ struct BBswtDesc bool bbsHasDefault; // true if last switch case is a default case bool bbsHasDominantCase; // true if switch has a dominant case - BBswtDesc() - : bbsHasDefault(true) +public: + BBswtDesc(FlowEdge** succs, unsigned succCount, FlowEdge** cases, unsigned caseCount, bool hasDefault) + : BBJumpTable(succs, succCount) + , caseCount(caseCount) + , cases(cases) + , bbsDominantCase(0) + , bbsHasDefault(hasDefault) , bbsHasDominantCase(false) { } - BBswtDesc(const BBswtDesc* other); + BBswtDesc(FlowEdge** succs, + unsigned succCount, + FlowEdge** cases, + unsigned caseCount, + bool hasDefault, + unsigned dominantCase) + : BBJumpTable(succs, succCount) + , caseCount(caseCount) + , cases(cases) + , bbsDominantCase(dominantCase) + , bbsHasDefault(hasDefault) + , bbsHasDominantCase(true) + { + } BBswtDesc(Compiler* comp, const BBswtDesc* other); - void removeDefault() + FlowEdge** GetCases() const { - assert(bbsHasDefault); - assert(bbsCount > 0); - bbsHasDefault = false; - bbsCount--; + assert((cases != nullptr) || (caseCount == 0)); + return cases; } - FlowEdge* getDefault() + FlowEdge* GetCase(unsigned index) const { - assert(bbsHasDefault); - assert(bbsCount > 0); - return bbsDstTab[bbsCount - 1]; + assert(index < caseCount); + return cases[index]; } -}; -// BBSwitchTargetList out-of-class-declaration implementations (here due to C++ ordering requirements). -// + unsigned GetCaseCount() const + { + return caseCount; + } -inline BBSwitchTargetList::BBSwitchTargetList(BBswtDesc* bbsDesc) - : m_bbsDesc(bbsDesc) -{ - assert(m_bbsDesc != nullptr); - assert(m_bbsDesc->bbsDstTab != nullptr); -} + void RemoveDefaultCase() + { + assert(bbsHasDefault); + assert(caseCount > 0); + bbsHasDefault = false; + caseCount--; + } -inline BBArrayIterator BBSwitchTargetList::begin() const -{ - return BBArrayIterator(m_bbsDesc->bbsDstTab); -} + bool HasDefaultCase() const + { + return bbsHasDefault; + } -inline BBArrayIterator BBSwitchTargetList::end() const -{ - return BBArrayIterator(m_bbsDesc->bbsDstTab + m_bbsDesc->bbsCount); -} + FlowEdge* GetDefaultCase() const + { + assert(bbsHasDefault); + assert(caseCount > 0); + return cases[caseCount - 1]; + } -// BBehfDesc -- descriptor for a BBJ_EHFINALLYRET block -// -struct BBehfDesc -{ - FlowEdge** bbeSuccs; // array of `FlowEdge*` pointing to BBJ_EHFINALLYRET block successors - unsigned bbeCount; // size of `bbeSuccs` array + void SetDominantCase(unsigned dominantCase) + { + assert(!bbsHasDominantCase); + bbsDominantCase = dominantCase; + bbsHasDominantCase = true; + } - BBehfDesc() - : bbeSuccs(nullptr) - , bbeCount(0) + void RemoveDominantCase() { + assert(bbsHasDominantCase); + bbsHasDominantCase = false; } - BBehfDesc(Compiler* comp, const BBehfDesc* other); + bool HasDominantCase() const + { + return bbsHasDominantCase; + } + + unsigned GetDominantCase() const + { + assert(bbsHasDominantCase); + return bbsDominantCase; + } }; -// BBEhfSuccList out-of-class-declaration implementations (here due to C++ ordering requirements). +// BBJumpTableList out-of-class-declaration implementations (here due to C++ ordering requirements). // -inline BBEhfSuccList::BBEhfSuccList(BBehfDesc* bbeDesc) - : m_bbeDesc(bbeDesc) +inline BBJumpTableList::BBJumpTableList(BBJumpTable* bbJumpTable) + : m_bbJumpTable(bbJumpTable) { - assert(m_bbeDesc != nullptr); - assert((m_bbeDesc->bbeSuccs != nullptr) || (m_bbeDesc->bbeCount == 0)); + assert(m_bbJumpTable != nullptr); + assert((m_bbJumpTable->GetSuccs() != nullptr) || (m_bbJumpTable->GetSuccCount() == 0)); } -inline BBArrayIterator BBEhfSuccList::begin() const +inline BBArrayIterator BBJumpTableList::begin() const { - return BBArrayIterator(m_bbeDesc->bbeSuccs); + return BBArrayIterator(m_bbJumpTable->GetSuccs()); } -inline BBArrayIterator BBEhfSuccList::end() const +inline BBArrayIterator BBJumpTableList::end() const { - return BBArrayIterator(m_bbeDesc->bbeSuccs + m_bbeDesc->bbeCount); + return BBArrayIterator(m_bbJumpTable->GetSuccs() + m_bbJumpTable->GetSuccCount()); } // SuccList out-of-class-declaration implementations @@ -2439,17 +2527,17 @@ inline BasicBlock::SuccList::SuccList(const BasicBlock* block) } else { - m_begin = block->GetEhfTargets()->bbeSuccs; - m_end = block->GetEhfTargets()->bbeSuccs + block->GetEhfTargets()->bbeCount; + m_begin = block->GetEhfTargets()->GetSuccs(); + m_end = block->GetEhfTargets()->GetSuccs() + block->GetEhfTargets()->GetSuccCount(); } break; case BBJ_SWITCH: // We don't use the m_succs in-line data for switches; use the existing jump table in the block. assert(block->bbSwtTargets != nullptr); - assert(block->bbSwtTargets->bbsDstTab != nullptr); - m_begin = block->bbSwtTargets->bbsDstTab; - m_end = block->bbSwtTargets->bbsDstTab + block->bbSwtTargets->bbsCount; + assert(block->bbSwtTargets->GetCases() != nullptr); + m_begin = block->bbSwtTargets->GetCases(); + m_end = block->bbSwtTargets->GetCases() + block->bbSwtTargets->GetCaseCount(); break; default: diff --git a/src/runtime/src/coreclr/jit/clrjit.natvis b/src/runtime/src/coreclr/jit/clrjit.natvis index 424bd4e3f2d..b38738ea9ed 100644 --- a/src/runtime/src/coreclr/jit/clrjit.natvis +++ b/src/runtime/src/coreclr/jit/clrjit.natvis @@ -22,8 +22,8 @@ Documentation for VS debugger format specifiers: https://learn.microsoft.com/vis BB{bbNum,d}->BB{bbTargetEdge->m_destBlock->bbNum,d}; {bbKind,en} BB{bbNum,d}-> (BB{bbTrueEdge->m_destBlock->bbNum,d}(T),BB{bbFalseEdge->m_destBlock->bbNum,d}(F)) ; {bbKind,en} - BB{bbNum,d}; {bbKind,en}; {bbSwtTargets->bbsCount} cases - BB{bbNum,d}; {bbKind,en}; {bbEhfTargets->bbeCount} succs + BB{bbNum,d}; {bbKind,en}; {bbSwtTargets->caseCount} cases + BB{bbNum,d}; {bbKind,en}; {bbEhfTargets->succCount} succs BB{bbNum,d}; {bbKind,en} diff --git a/src/runtime/src/coreclr/jit/codegenarm64test.cpp b/src/runtime/src/coreclr/jit/codegenarm64test.cpp index a66e626a6e2..aefe56ea0f0 100644 --- a/src/runtime/src/coreclr/jit/codegenarm64test.cpp +++ b/src/runtime/src/coreclr/jit/codegenarm64test.cpp @@ -7036,95 +7036,95 @@ void CodeGen::genArm64EmitterUnitTestsSve() // IF_SVE_FE_3A theEmitter->emitIns_R_R_R_I(INS_sve_smullb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, - INS_OPTS_SCALABLE_H); // SMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smullb, EA_SCALABLE, REG_V2, REG_V3, REG_V1, 1, - INS_OPTS_SCALABLE_H); // SMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smullt, EA_SCALABLE, REG_V4, REG_V5, REG_V2, 2, - INS_OPTS_SCALABLE_H); // SMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMULLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smullt, EA_SCALABLE, REG_V6, REG_V7, REG_V3, 3, - INS_OPTS_SCALABLE_H); // SMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMULLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umullb, EA_SCALABLE, REG_V8, REG_V9, REG_V4, 4, - INS_OPTS_SCALABLE_H); // UMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umullb, EA_SCALABLE, REG_V10, REG_V11, REG_V5, 5, - INS_OPTS_SCALABLE_H); // UMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umullt, EA_SCALABLE, REG_V12, REG_V13, REG_V6, 6, - INS_OPTS_SCALABLE_H); // UMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMULLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umullt, EA_SCALABLE, REG_V14, REG_V15, REG_V7, 7, - INS_OPTS_SCALABLE_H); // UMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMULLT .S, .H, .H[] // IF_SVE_FE_3B theEmitter->emitIns_R_R_R_I(INS_sve_smullb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, - INS_OPTS_SCALABLE_S); // SMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smullb, EA_SCALABLE, REG_V2, REG_V3, REG_V2, 1, - INS_OPTS_SCALABLE_S); // SMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smullt, EA_SCALABLE, REG_V4, REG_V5, REG_V4, 2, - INS_OPTS_SCALABLE_S); // SMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMULLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smullt, EA_SCALABLE, REG_V6, REG_V7, REG_V6, 3, - INS_OPTS_SCALABLE_S); // SMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMULLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umullb, EA_SCALABLE, REG_V8, REG_V9, REG_V8, 0, - INS_OPTS_SCALABLE_S); // UMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umullb, EA_SCALABLE, REG_V10, REG_V11, REG_V10, 1, - INS_OPTS_SCALABLE_S); // UMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umullt, EA_SCALABLE, REG_V12, REG_V13, REG_V12, 2, - INS_OPTS_SCALABLE_S); // UMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMULLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umullt, EA_SCALABLE, REG_V14, REG_V15, REG_V14, 3, - INS_OPTS_SCALABLE_S); // UMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMULLT .D, .S, .S[] // IF_SVE_FG_3A theEmitter->emitIns_R_R_R_I(INS_sve_smlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, - INS_OPTS_SCALABLE_H); // SMLALB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMLALB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smlalt, EA_SCALABLE, REG_V2, REG_V3, REG_V1, 1, - INS_OPTS_SCALABLE_H); // SMLALT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMLALT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smlslb, EA_SCALABLE, REG_V4, REG_V5, REG_V2, 2, - INS_OPTS_SCALABLE_H); // SMLSLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMLSLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smlslt, EA_SCALABLE, REG_V6, REG_V7, REG_V3, 3, - INS_OPTS_SCALABLE_H); // SMLSLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMLSLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umlalb, EA_SCALABLE, REG_V8, REG_V9, REG_V4, 4, - INS_OPTS_SCALABLE_H); // UMLALB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMLALB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umlalt, EA_SCALABLE, REG_V10, REG_V11, REG_V5, 5, - INS_OPTS_SCALABLE_H); // UMLALT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMLALT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umlslb, EA_SCALABLE, REG_V12, REG_V13, REG_V6, 6, - INS_OPTS_SCALABLE_H); // UMLSLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMLSLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umlslt, EA_SCALABLE, REG_V14, REG_V15, REG_V7, 7, - INS_OPTS_SCALABLE_H); // UMLSLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMLSLT .S, .H, .H[] // IF_SVE_FG_3B theEmitter->emitIns_R_R_R_I(INS_sve_smlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, - INS_OPTS_SCALABLE_S); // SMLALB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMLALB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smlalt, EA_SCALABLE, REG_V2, REG_V3, REG_V2, 1, - INS_OPTS_SCALABLE_S); // SMLALT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMLALT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smlslb, EA_SCALABLE, REG_V4, REG_V5, REG_V4, 2, - INS_OPTS_SCALABLE_S); // SMLSLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMLSLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smlslt, EA_SCALABLE, REG_V6, REG_V7, REG_V6, 3, - INS_OPTS_SCALABLE_S); // SMLSLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMLSLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umlalb, EA_SCALABLE, REG_V8, REG_V9, REG_V8, 0, - INS_OPTS_SCALABLE_S); // UMLALB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMLALB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umlalt, EA_SCALABLE, REG_V10, REG_V11, REG_V10, 1, - INS_OPTS_SCALABLE_S); // UMLALT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMLALT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umlslb, EA_SCALABLE, REG_V12, REG_V13, REG_V12, 2, - INS_OPTS_SCALABLE_S); // UMLSLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMLSLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umlslt, EA_SCALABLE, REG_V14, REG_V15, REG_V14, 3, - INS_OPTS_SCALABLE_S); // UMLSLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMLSLT .D, .S, .S[] // IF_SVE_FH_3A theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullb, EA_SCALABLE, REG_V0, REG_V2, REG_V1, 1, - INS_OPTS_SCALABLE_H); // SQDMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullb, EA_SCALABLE, REG_V4, REG_V6, REG_V3, 3, - INS_OPTS_SCALABLE_H); // SQDMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullt, EA_SCALABLE, REG_V8, REG_V10, REG_V5, 5, - INS_OPTS_SCALABLE_H); // SQDMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMULLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullt, EA_SCALABLE, REG_V12, REG_V14, REG_V7, 7, - INS_OPTS_SCALABLE_H); // SQDMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMULLT .S, .H, .H[] // IF_SVE_FH_3B theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullb, EA_SCALABLE, REG_V0, REG_V2, REG_V0, 0, - INS_OPTS_SCALABLE_S); // SQDMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullb, EA_SCALABLE, REG_V4, REG_V6, REG_V5, 1, - INS_OPTS_SCALABLE_S); // SQDMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullt, EA_SCALABLE, REG_V8, REG_V10, REG_V10, 2, - INS_OPTS_SCALABLE_S); // SQDMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMULLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullt, EA_SCALABLE, REG_V12, REG_V14, REG_V15, 3, - INS_OPTS_SCALABLE_S); // SQDMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMULLT .D, .S, .S[] // IF_SVE_FI_3A theEmitter->emitIns_R_R_R_I(INS_sve_sqdmulh, EA_SCALABLE, REG_V0, REG_V1, REG_V1, 1, @@ -7158,23 +7158,23 @@ void CodeGen::genArm64EmitterUnitTestsSve() // IF_SVE_FJ_3A theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V1, 1, - INS_OPTS_SCALABLE_H); // SQDMLALB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMLALB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlalt, EA_SCALABLE, REG_V2, REG_V3, REG_V3, 3, - INS_OPTS_SCALABLE_H); // SQDMLALT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMLALT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlslb, EA_SCALABLE, REG_V4, REG_V5, REG_V5, 5, - INS_OPTS_SCALABLE_H); // SQDMLSLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMLSLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlslt, EA_SCALABLE, REG_V6, REG_V0, REG_V7, 7, - INS_OPTS_SCALABLE_H); // SQDMLSLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMLSLT .S, .H, .H[] // IF_SVE_FJ_3B theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlalb, EA_SCALABLE, REG_V8, REG_V9, REG_V0, 0, - INS_OPTS_SCALABLE_S); // SQDMLALB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMLALB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlalt, EA_SCALABLE, REG_V10, REG_V11, REG_V5, 1, - INS_OPTS_SCALABLE_S); // SQDMLALT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMLALT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlslb, EA_SCALABLE, REG_V12, REG_V13, REG_V10, 2, - INS_OPTS_SCALABLE_S); // SQDMLSLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMLSLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlslt, EA_SCALABLE, REG_V14, REG_V15, REG_V15, 3, - INS_OPTS_SCALABLE_S); // SQDMLSLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMLSLT .D, .S, .S[] // IF_SVE_FF_3A theEmitter->emitIns_R_R_R_I(INS_sve_mla, EA_SCALABLE, REG_V0, REG_V1, REG_V1, 1, diff --git a/src/runtime/src/coreclr/jit/codegencommon.cpp b/src/runtime/src/coreclr/jit/codegencommon.cpp index 22ec0490991..3e2ba356790 100644 --- a/src/runtime/src/coreclr/jit/codegencommon.cpp +++ b/src/runtime/src/coreclr/jit/codegencommon.cpp @@ -485,7 +485,7 @@ void CodeGen::genMarkLabelsForCodegen() break; case BBJ_SWITCH: - for (BasicBlock* const bTarget : block->SwitchTargets()) + for (BasicBlock* const bTarget : block->SwitchSuccs()) { JITDUMP(" " FMT_BB " : switch target\n", bTarget->bbNum); bTarget->SetFlags(BBF_HAS_LABEL); @@ -5564,17 +5564,16 @@ unsigned CodeGen::genEmitJumpTable(GenTree* treeNode, bool relativeAddr) noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH)); assert(treeNode->OperIs(GT_JMPTABLE)); - emitter* emit = GetEmitter(); - const unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab; - const unsigned jmpTabBase = emit->emitBBTableDataGenBeg(jumpCount, relativeAddr); + emitter* emit = GetEmitter(); + const unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const jumpTable = compiler->compCurBB->GetSwitchTargets()->GetCases(); + const unsigned jmpTabBase = emit->emitBBTableDataGenBeg(jumpCount, relativeAddr); JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase); for (unsigned i = 0; i < jumpCount; i++) { - BasicBlock* target = (*jumpTable)->getDestinationBlock(); - jumpTable++; + BasicBlock* target = jumpTable[i]->getDestinationBlock(); noway_assert(target->HasFlag(BBF_HAS_LABEL)); JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum); diff --git a/src/runtime/src/coreclr/jit/compiler.h b/src/runtime/src/coreclr/jit/compiler.h index d30efd26a5e..70cca1ec6ca 100644 --- a/src/runtime/src/coreclr/jit/compiler.h +++ b/src/runtime/src/coreclr/jit/compiler.h @@ -6028,45 +6028,6 @@ class Compiler PhaseStatus fgInsertGCPolls(); BasicBlock* fgCreateGCPoll(GCPollType pollType, BasicBlock* block); -public: - // For many purposes, it is desirable to be able to enumerate the *distinct* targets of a switch statement, - // skipping duplicate targets. (E.g., in flow analyses that are only interested in the set of possible targets.) - // SwitchUniqueSuccSet contains the non-duplicated switch successor edges. - // Code that modifies the flowgraph (such as by renumbering blocks) must call Compiler::InvalidateUniqueSwitchSuccMap, - // and code that modifies the targets of a switch block must call Compiler::fgInvalidateSwitchDescMapEntry. - // If the unique targets of a switch block are needed later, they will be recomputed, ensuring they're up-to-date. - struct SwitchUniqueSuccSet - { - unsigned numDistinctSuccs; // Number of distinct targets of the switch. - FlowEdge** nonDuplicates; // Array of "numDistinctSuccs", containing all the distinct switch target - // successor edges. - }; - - typedef JitHashTable, SwitchUniqueSuccSet> BlockToSwitchDescMap; - -private: - // Maps BasicBlock*'s that end in switch statements to SwitchUniqueSuccSets that allow - // iteration over only the distinct successors. - BlockToSwitchDescMap* m_switchDescMap = nullptr; - -public: - BlockToSwitchDescMap* GetSwitchDescMap(bool createIfNull = true) - { - if ((m_switchDescMap == nullptr) && createIfNull) - { - m_switchDescMap = new (getAllocator()) BlockToSwitchDescMap(getAllocator()); - } - return m_switchDescMap; - } - - SwitchUniqueSuccSet GetDescriptorForSwitch(BasicBlock* switchBlk); - - bool GetDescriptorForSwitchIfAvailable(BasicBlock* switchBlk, SwitchUniqueSuccSet* res); - - void fgRemoveSuccFromSwitchDescMapEntry(BasicBlock* switchBlk, FlowEdge* edge); - - void fgInvalidateSwitchDescMapEntry(BasicBlock* switchBlk); - BasicBlock* fgFirstBlockOfHandler(BasicBlock* block); FlowEdge* fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred); diff --git a/src/runtime/src/coreclr/jit/compiler.hpp b/src/runtime/src/coreclr/jit/compiler.hpp index 38c092ebfa2..0261b272181 100644 --- a/src/runtime/src/coreclr/jit/compiler.hpp +++ b/src/runtime/src/coreclr/jit/compiler.hpp @@ -663,9 +663,9 @@ BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func, const bool // LEAVE into callfinally yet, and haven't added return successors. if (bbEhfTargets != nullptr) { - for (unsigned i = 0; i < bbEhfTargets->bbeCount; i++) + for (unsigned i = 0; i < bbEhfTargets->GetSuccCount(); i++) { - RETURN_ON_ABORT(func(bbEhfTargets->bbeSuccs[i]->getDestinationBlock())); + RETURN_ON_ABORT(func(bbEhfTargets->GetSucc(i)->getDestinationBlock())); } } @@ -711,10 +711,9 @@ BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func, const bool case BBJ_SWITCH: { - Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this); - for (unsigned i = 0; i < sd.numDistinctSuccs; i++) + for (unsigned i = 0; i < bbSwtTargets->GetSuccCount(); i++) { - RETURN_ON_ABORT(func(sd.nonDuplicates[i]->getDestinationBlock())); + RETURN_ON_ABORT(func(bbSwtTargets->GetSucc(i)->getDestinationBlock())); } return VisitEHSuccs(comp, func); @@ -750,9 +749,9 @@ BasicBlockVisit BasicBlock::VisitRegularSuccs(Compiler* comp, TFunc func) // LEAVE into callfinally yet, and haven't added return successors. if (bbEhfTargets != nullptr) { - for (unsigned i = 0; i < bbEhfTargets->bbeCount; i++) + for (unsigned i = 0; i < bbEhfTargets->GetSuccCount(); i++) { - RETURN_ON_ABORT(func(bbEhfTargets->bbeSuccs[i]->getDestinationBlock())); + RETURN_ON_ABORT(func(bbEhfTargets->GetSucc(i)->getDestinationBlock())); } } @@ -778,10 +777,9 @@ BasicBlockVisit BasicBlock::VisitRegularSuccs(Compiler* comp, TFunc func) case BBJ_SWITCH: { - Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this); - for (unsigned i = 0; i < sd.numDistinctSuccs; i++) + for (unsigned i = 0; i < bbSwtTargets->GetSuccCount(); i++) { - RETURN_ON_ABORT(func(sd.nonDuplicates[i]->getDestinationBlock())); + RETURN_ON_ABORT(func(bbSwtTargets->GetSucc(i)->getDestinationBlock())); } return BasicBlockVisit::Continue; diff --git a/src/runtime/src/coreclr/jit/emitarm64sve.cpp b/src/runtime/src/coreclr/jit/emitarm64sve.cpp index 9d0fe49fbc0..25f1817ae45 100644 --- a/src/runtime/src/coreclr/jit/emitarm64sve.cpp +++ b/src/runtime/src/coreclr/jit/emitarm64sve.cpp @@ -5436,7 +5436,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, assert(isVectorRegister(reg2)); // nnnnn assert(isLowVectorRegister(reg3)); // mmmm - if (opt == INS_OPTS_SCALABLE_H) + if (opt == INS_OPTS_SCALABLE_S) { assert((REG_V0 <= reg3) && (reg3 <= REG_V7)); // mmm assert(isValidUimm<3>(imm)); // ii i @@ -5444,7 +5444,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, } else { - assert(opt == INS_OPTS_SCALABLE_S); + assert(opt == INS_OPTS_SCALABLE_D); assert(isValidUimm<2>(imm)); // i i fmt = IF_SVE_FE_3B; } @@ -5463,7 +5463,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, assert(isVectorRegister(reg2)); // nnnnn assert(isLowVectorRegister(reg3)); // mmmm - if (opt == INS_OPTS_SCALABLE_H) + if (opt == INS_OPTS_SCALABLE_S) { assert((REG_V0 <= reg3) && (reg3 <= REG_V7)); // mmm assert(isValidUimm<3>(imm)); // ii i @@ -5471,7 +5471,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, } else { - assert(opt == INS_OPTS_SCALABLE_S); + assert(opt == INS_OPTS_SCALABLE_D); assert(isValidUimm<2>(imm)); // i i fmt = IF_SVE_FG_3B; } @@ -12999,7 +12999,7 @@ void emitter::emitInsSveSanityCheck(instrDesc* id) case IF_SVE_FG_3B: // ...........immmm ....i.nnnnnddddd -- SVE2 integer multiply-add long (indexed) case IF_SVE_FH_3B: // ...........immmm ....i.nnnnnddddd -- SVE2 saturating multiply (indexed) case IF_SVE_FJ_3B: // ...........immmm ....i.nnnnnddddd -- SVE2 saturating multiply-add (indexed) - assert(id->idInsOpt() == INS_OPTS_SCALABLE_S); + assert(id->idInsOpt() == INS_OPTS_SCALABLE_D); assert(isVectorRegister(id->idReg1())); // ddddd assert(isVectorRegister(id->idReg2())); // nnnnn assert(isLowVectorRegister(id->idReg3())); // mmmm diff --git a/src/runtime/src/coreclr/jit/fgbasic.cpp b/src/runtime/src/coreclr/jit/fgbasic.cpp index e6e11155230..4a8a1edb3f1 100644 --- a/src/runtime/src/coreclr/jit/fgbasic.cpp +++ b/src/runtime/src/coreclr/jit/fgbasic.cpp @@ -183,6 +183,12 @@ void Compiler::fgConvertBBToThrowBB(BasicBlock* block) // Update jump kind after the scrub. block->SetKindAndTargetEdge(BBJ_THROW); block->RemoveFlags(BBF_RETLESS_CALL); // no longer a BBJ_CALLFINALLY + + // Heuristic: Throw blocks without profile-derived weights are presumed to be rare. + if (!block->hasProfileWeight()) + { + block->bbSetRunRarely(); + } } /***************************************************************************** @@ -204,42 +210,15 @@ void Compiler::fgChangeSwitchBlock(BasicBlock* oldSwitchBlock, BasicBlock* newSw // Walk the switch's jump table, updating the predecessor for each branch. BBswtDesc* swtDesc = oldSwitchBlock->GetSwitchTargets(); - for (unsigned i = 0; i < swtDesc->bbsCount; i++) + for (unsigned i = 0; i < swtDesc->GetSuccCount(); i++) { - FlowEdge* succEdge = swtDesc->bbsDstTab[i]; - assert(succEdge != nullptr); + FlowEdge* succEdge = swtDesc->GetSucc(i); + assert(succEdge->getSourceBlock() == oldSwitchBlock); - if (succEdge->getSourceBlock() != oldSwitchBlock) - { - // swtDesc can have duplicate targets, so we may have updated this edge already - // - assert(succEdge->getSourceBlock() == newSwitchBlock); - assert(succEdge->getDupCount() > 1); - } - else - { - // Redirect edge's source block from oldSwitchBlock to newSwitchBlock, - // and keep successor block's pred list in order - // - fgReplacePred(succEdge, newSwitchBlock); - } - } - - if (m_switchDescMap != nullptr) - { - SwitchUniqueSuccSet uniqueSuccSet; - - // If already computed and cached the unique descriptors for the old block, let's - // update those for the new block. - if (m_switchDescMap->Lookup(oldSwitchBlock, &uniqueSuccSet)) - { - m_switchDescMap->Set(newSwitchBlock, uniqueSuccSet, BlockToSwitchDescMap::Overwrite); - } - else - { - fgInvalidateSwitchDescMapEntry(newSwitchBlock); - } - fgInvalidateSwitchDescMapEntry(oldSwitchBlock); + // Redirect edge's source block from oldSwitchBlock to newSwitchBlock, + // and keep successor block's pred list in order + // + fgReplacePred(succEdge, newSwitchBlock); } } @@ -259,11 +238,11 @@ void Compiler::fgChangeEhfBlock(BasicBlock* oldBlock, BasicBlock* newBlock) assert(oldBlock->KindIs(BBJ_EHFINALLYRET)); assert(fgPredsComputed); - BBehfDesc* ehfDesc = oldBlock->GetEhfTargets(); + BBJumpTable* ehfDesc = oldBlock->GetEhfTargets(); - for (unsigned i = 0; i < ehfDesc->bbeCount; i++) + for (unsigned i = 0; i < ehfDesc->GetSuccCount(); i++) { - FlowEdge* succEdge = ehfDesc->bbeSuccs[i]; + FlowEdge* succEdge = ehfDesc->GetSucc(i); fgReplacePred(succEdge, newBlock); } } @@ -288,9 +267,9 @@ void Compiler::fgReplaceEhfSuccessor(BasicBlock* block, BasicBlock* oldSucc, Bas assert(block->KindIs(BBJ_EHFINALLYRET)); assert(fgPredsComputed); - BBehfDesc* const ehfDesc = block->GetEhfTargets(); - const unsigned succCount = ehfDesc->bbeCount; - FlowEdge** const succTab = ehfDesc->bbeSuccs; + BBJumpTable* const ehfDesc = block->GetEhfTargets(); + const unsigned succCount = ehfDesc->GetSuccCount(); + FlowEdge** const succTab = ehfDesc->GetSuccs(); // Walk the successor table looking for the old successor, which we expect to find only once. unsigned oldSuccNum = UINT_MAX; @@ -344,48 +323,38 @@ void Compiler::fgReplaceEhfSuccessor(BasicBlock* block, BasicBlock* oldSucc, Bas // // Arguments: // block - BBJ_EHFINALLYRET block -// succIndex - index of the successor in block->GetEhfTargets()->bbeSuccs +// succIndex - index of the successor in the block's jump table // void Compiler::fgRemoveEhfSuccFromTable(BasicBlock* block, const unsigned succIndex) { assert(block != nullptr); assert(block->KindIs(BBJ_EHFINALLYRET)); - BBehfDesc* const ehfDesc = block->GetEhfTargets(); - const unsigned succCount = ehfDesc->bbeCount; - FlowEdge** succTab = ehfDesc->bbeSuccs; - assert(succIndex < succCount); - FlowEdge* const succEdge = succTab[succIndex]; - - // If succEdge is not the last entry, move everything after in the table down one slot. - if ((succIndex + 1) < succCount) - { - memmove_s(&succTab[succIndex], (succCount - succIndex) * sizeof(FlowEdge*), &succTab[succIndex + 1], - (succCount - succIndex - 1) * sizeof(FlowEdge*)); - } + BBJumpTable* const ehfDesc = block->GetEhfTargets(); + FlowEdge* const succEdge = ehfDesc->GetSucc(succIndex); + ehfDesc->RemoveSucc(succIndex); // Recompute the likelihoods of the block's other successor edges. const weight_t removedLikelihood = succEdge->getLikelihood(); - const unsigned newSuccCount = succCount - 1; + const unsigned newSuccCount = ehfDesc->GetSuccCount(); for (unsigned i = 0; i < newSuccCount; i++) { // If we removed all of the flow out of 'block', distribute flow among the remaining edges evenly. - const weight_t currLikelihood = succTab[i]->getLikelihood(); - const weight_t newLikelihood = + FlowEdge* const edge = ehfDesc->GetSucc(i); + const weight_t currLikelihood = edge->getLikelihood(); + const weight_t newLikelihood = (removedLikelihood == 1.0) ? (1.0 / newSuccCount) : (currLikelihood / (1.0 - removedLikelihood)); - succTab[i]->setLikelihood(min(1.0, newLikelihood)); + edge->setLikelihood(min(1.0, newLikelihood)); } #ifdef DEBUG // We only expect to see a successor once in the table. - for (unsigned i = succIndex; i < (succCount - 1); i++) + for (unsigned i = succIndex; i < newSuccCount; i++) { - assert(succTab[i]->getDestinationBlock() != succEdge->getDestinationBlock()); + assert(ehfDesc->GetSucc(i)->getDestinationBlock() != succEdge->getDestinationBlock()); } #endif // DEBUG - - ehfDesc->bbeCount--; } //------------------------------------------------------------------------ @@ -407,50 +376,18 @@ void Compiler::fgRemoveEhfSuccessor(FlowEdge* succEdge) fgRemoveRefPred(succEdge); - BBehfDesc* const ehfDesc = block->GetEhfTargets(); - const unsigned succCount = ehfDesc->bbeCount; - FlowEdge** succTab = ehfDesc->bbeSuccs; - bool found = false; + BBJumpTable* const ehfDesc = block->GetEhfTargets(); - // Search succTab for succEdge so we can splice it out of the table. - for (unsigned i = 0; i < succCount; i++) + for (unsigned i = 0; i < ehfDesc->GetSuccCount(); i++) { - if (succTab[i] == succEdge) + if (ehfDesc->GetSucc(i) == succEdge) { - // If succEdge not the last entry, move everything after in the table down one slot. - if ((i + 1) < succCount) - { - memmove_s(&succTab[i], (succCount - i) * sizeof(FlowEdge*), &succTab[i + 1], - (succCount - i - 1) * sizeof(FlowEdge*)); - } - - found = true; - -#ifdef DEBUG - // We only expect to see a successor once in the table. - for (; i < (succCount - 1); i++) - { - assert(succTab[i]->getDestinationBlock() != succEdge->getDestinationBlock()); - } -#endif // DEBUG + fgRemoveEhfSuccFromTable(block, i); + return; } } - // Recompute the likelihoods of the block's other successor edges. - const weight_t removedLikelihood = succEdge->getLikelihood(); - const unsigned newSuccCount = succCount - 1; - - for (unsigned i = 0; i < newSuccCount; i++) - { - // If we removed all of the flow out of 'block', distribute flow among the remaining edges evenly. - const weight_t currLikelihood = succTab[i]->getLikelihood(); - const weight_t newLikelihood = - (removedLikelihood == 1.0) ? (1.0 / newSuccCount) : (currLikelihood / (1.0 - removedLikelihood)); - succTab[i]->setLikelihood(min(1.0, newLikelihood)); - } - - assert(found); - ehfDesc->bbeCount--; + unreached(); } //------------------------------------------------------------------------ @@ -510,8 +447,8 @@ void Compiler::fgReplaceJumpTarget(BasicBlock* block, BasicBlock* oldTarget, Bas case BBJ_SWITCH: { - unsigned const jumpCnt = block->GetSwitchTargets()->bbsCount; - FlowEdge** const jumpTab = block->GetSwitchTargets()->bbsDstTab; + unsigned const jumpCnt = block->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const jumpTab = block->GetSwitchTargets()->GetCases(); FlowEdge* oldEdge = nullptr; FlowEdge* newEdge = nullptr; bool changed = false; @@ -562,8 +499,15 @@ void Compiler::fgReplaceJumpTarget(BasicBlock* block, BasicBlock* oldTarget, Bas assert(newEdge->getDestinationBlock() == newTarget); newEdge->addLikelihood(oldEdge->getLikelihood()); - // Remove 'oldEdge' from the switch map entry, if it exists. - fgRemoveSuccFromSwitchDescMapEntry(block, oldEdge); + for (unsigned i = block->GetSwitchTargets()->GetSuccCount(); i != 0; i--) + { + if (block->GetSwitchTargets()->GetSucc(i - 1) == oldEdge) + { + // Remove the old edge from the unique successor table. + block->GetSwitchTargets()->RemoveSucc(i - 1); + break; + } + } } // If we simply redirected 'oldEdge' to 'newTarget', we don't need to update the switch map entry, @@ -2876,26 +2820,34 @@ void Compiler::fgLinkBasicBlocks() case BBJ_SWITCH: { - const unsigned numSucc = curBBdesc->GetSwitchTargets()->bbsCount; - unsigned jumpCnt = numSucc; - FlowEdge** jumpPtr = curBBdesc->GetSwitchTargets()->bbsDstTab; + const unsigned numCases = curBBdesc->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const cases = curBBdesc->GetSwitchTargets()->GetCases(); + FlowEdge** const succs = cases - numCases; + unsigned numUnique = 0; - do + for (unsigned i = 0; i < numCases; i++) { - BasicBlock* jumpDest = fgLookupBB((unsigned)*(size_t*)jumpPtr); + BasicBlock* jumpDest = fgLookupBB((unsigned)*(size_t*)(cases + i)); FlowEdge* const newEdge = fgAddRefPred(jumpDest, curBBdesc); - newEdge->setLikelihood((1.0 / numSucc) * newEdge->getDupCount()); - *jumpPtr = newEdge; - if (jumpDest->bbNum <= curBBdesc->bbNum) + newEdge->setLikelihood((1.0 / numCases) * newEdge->getDupCount()); + cases[i] = newEdge; + + if (newEdge->getDupCount() == 1) { - fgMarkBackwardJump(jumpDest, curBBdesc); + succs[numUnique++] = newEdge; + if (jumpDest->bbNum <= curBBdesc->bbNum) + { + fgMarkBackwardJump(jumpDest, curBBdesc); + } } - } while (++jumpPtr, --jumpCnt); + } - /* Default case of CEE_SWITCH (next block), is at end of jumpTab[] */ + curBBdesc->GetSwitchTargets()->SetSuccs(succs, numUnique); - noway_assert(curBBdesc->NextIs((*(jumpPtr - 1))->getDestinationBlock())); + /* Default case of CEE_SWITCH (next block), is at end of cases[] */ + + noway_assert(curBBdesc->NextIs(cases[numCases - 1]->getDestinationBlock())); break; } @@ -3054,56 +3006,42 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case CEE_SWITCH: { - unsigned jmpBase; - unsigned jmpCnt; // # of switch cases (excluding default) - - FlowEdge** jmpTab; - FlowEdge** jmpPtr; - - /* Allocate the switch descriptor */ - - swtDsc = new (this, CMK_BasicBlock) BBswtDesc; - /* Read the number of entries in the table */ - jmpCnt = getU4LittleEndian(codeAddr); + const unsigned jmpCnt = getU4LittleEndian(codeAddr); // # of switch cases (excluding default) codeAddr += 4; /* Compute the base offset for the opcode */ - jmpBase = (IL_OFFSET)((codeAddr - codeBegp) + jmpCnt * sizeof(DWORD)); + const unsigned jmpBase = (IL_OFFSET)((codeAddr - codeBegp) + jmpCnt * sizeof(DWORD)); - /* Allocate the jump table */ + /* Allocate the jump table, ensuring there's space for all cases, the default case, and unique succs */ - jmpPtr = jmpTab = new (this, CMK_FlowEdge) FlowEdge*[jmpCnt + 1]; + FlowEdge** const jmpTab = new (this, CMK_FlowEdge) FlowEdge*[(jmpCnt + 1) * 2]; + FlowEdge** const cases = jmpTab + (jmpCnt + 1); /* Fill in the jump table */ - for (unsigned count = jmpCnt; count; count--) + for (unsigned i = 0; i < jmpCnt; i++) { jmpDist = getI4LittleEndian(codeAddr); codeAddr += 4; // store the offset in the pointer. We change these in fgLinkBasicBlocks(). - *jmpPtr++ = (FlowEdge*)(size_t)(jmpBase + jmpDist); + cases[i] = (FlowEdge*)(size_t)(jmpBase + jmpDist); } /* Append the default label to the target table */ - *jmpPtr++ = (FlowEdge*)(size_t)jmpBase; - - /* Make sure we found the right number of labels */ - - noway_assert(jmpPtr == jmpTab + jmpCnt + 1); + cases[jmpCnt] = (FlowEdge*)(size_t)jmpBase; /* Compute the size of the switch opcode operands */ sz = sizeof(DWORD) + jmpCnt * sizeof(DWORD); - /* Fill in the remaining fields of the switch descriptor */ + /* Allocate the switch descriptor; we will initialize the unique successors in fgLinkBasicBlocks */ - swtDsc->bbsCount = jmpCnt + 1; - swtDsc->bbsDstTab = jmpTab; + swtDsc = new (this, CMK_BasicBlock) BBswtDesc(nullptr, 0, cases, jmpCnt + 1, true); /* This is definitely a jump */ @@ -4240,7 +4178,7 @@ void Compiler::fgCheckBasicBlockControlFlow() break; case BBJ_SWITCH: // block ends with a switch statement - for (BasicBlock* const bTarget : blk->SwitchTargets()) + for (BasicBlock* const bTarget : blk->SwitchSuccs()) { fgControlFlowPermitted(blk, bTarget); } diff --git a/src/runtime/src/coreclr/jit/fgdiagnostic.cpp b/src/runtime/src/coreclr/jit/fgdiagnostic.cpp index 50145f04b32..9cbc76ceb77 100644 --- a/src/runtime/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/runtime/src/coreclr/jit/fgdiagnostic.cpp @@ -1068,7 +1068,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase, PhasePosition pos) { fprintf(fgxFile, "\n switchCases=\"%d\"", edge->getDupCount()); } - if (bSource->GetSwitchTargets()->getDefault()->getDestinationBlock() == bTarget) + if (bSource->GetSwitchTargets()->GetDefaultCase()->getDestinationBlock() == bTarget) { fprintf(fgxFile, "\n switchDefault=\"true\""); } @@ -1978,7 +1978,7 @@ void Compiler::fgTableDispBasicBlock(const BasicBlock* block, printf("->"); printedBlockWidth = 2 + 9 /* kind */; - const BBehfDesc* const ehfDesc = block->GetEhfTargets(); + const BBJumpTable* const ehfDesc = block->GetEhfTargets(); if (ehfDesc == nullptr) { printf(" ????"); @@ -1988,13 +1988,10 @@ void Compiler::fgTableDispBasicBlock(const BasicBlock* block, { // Very early in compilation, we won't have fixed up the BBJ_EHFINALLYRET successors yet. - const unsigned jumpCnt = ehfDesc->bbeCount; - FlowEdge** const jumpTab = ehfDesc->bbeSuccs; - - for (unsigned i = 0; i < jumpCnt; i++) + for (unsigned i = 0; i < ehfDesc->GetSuccCount(); i++) { printedBlockWidth += 1 /* space/comma */; - printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(jumpTab[i])); + printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(ehfDesc->GetSucc(i))); } } @@ -2040,22 +2037,22 @@ void Compiler::fgTableDispBasicBlock(const BasicBlock* block, printedBlockWidth = 2 + 9 /* kind */; const BBswtDesc* const jumpSwt = block->GetSwitchTargets(); - const unsigned jumpCnt = jumpSwt->bbsCount; - FlowEdge** const jumpTab = jumpSwt->bbsDstTab; + const unsigned jumpCnt = jumpSwt->GetCaseCount(); + FlowEdge** const jumpTab = jumpSwt->GetCases(); for (unsigned i = 0; i < jumpCnt; i++) { printedBlockWidth += 1 /* space/comma */; printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(jumpTab[i])); - const bool isDefault = jumpSwt->bbsHasDefault && (i == jumpCnt - 1); + const bool isDefault = jumpSwt->HasDefaultCase() && (i == jumpCnt - 1); if (isDefault) { printf("[def]"); printedBlockWidth += 5; } - const bool isDominant = jumpSwt->bbsHasDominantCase && (i == jumpSwt->bbsDominantCase); + const bool isDominant = jumpSwt->HasDominantCase() && (i == jumpSwt->GetDominantCase()); if (isDominant) { printf("[dom]"); @@ -2786,7 +2783,7 @@ bool BBPredsChecker::CheckJump(BasicBlock* blockPred, BasicBlock* block) break; case BBJ_SWITCH: - for (BasicBlock* const bTarget : blockPred->SwitchTargets()) + for (BasicBlock* const bTarget : blockPred->SwitchSuccs()) { if (block == bTarget) { @@ -2970,38 +2967,10 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef maxBBNum = max(maxBBNum, block->bbNum); - // Check that all the successors have the current traversal stamp. Use the 'Compiler*' version of the - // iterator, but not for BBJ_SWITCH: we don't want to end up calling GetDescriptorForSwitch(), which will - // dynamically create the unique switch list. - if (block->KindIs(BBJ_SWITCH)) + // Check that all the successors have the current traversal stamp. + for (BasicBlock* const succBlock : block->Succs(this)) { - for (BasicBlock* const succBlock : block->Succs()) - { - assert(succBlock->bbTraversalStamp == curTraversalStamp); - } - - // Also check the unique successor set, if it exists. Make sure to NOT allocate it if it doesn't exist! - BlockToSwitchDescMap* switchMap = GetSwitchDescMap(/* createIfNull */ false); - if (switchMap != nullptr) - { - SwitchUniqueSuccSet sd; - if (switchMap->Lookup(block, &sd)) - { - for (unsigned i = 0; i < sd.numDistinctSuccs; i++) - { - const BasicBlock* const nonDuplicateSucc = sd.nonDuplicates[i]->getDestinationBlock(); - assert(nonDuplicateSucc != nullptr); - assert(nonDuplicateSucc->bbTraversalStamp == curTraversalStamp); - } - } - } - } - else - { - for (BasicBlock* const succBlock : block->Succs(this)) - { - assert(succBlock->bbTraversalStamp == curTraversalStamp); - } + assert(succBlock->bbTraversalStamp == curTraversalStamp); } // If the block is a BBJ_COND, a BBJ_SWITCH or a @@ -3971,31 +3940,24 @@ void Compiler::fgDebugCheckBlockLinks() } // If this is a switch, check that the tables are consistent. - // Note that we don't call GetSwitchDescMap(), because it has the side-effect - // of allocating it if it is not present. - if (block->KindIs(BBJ_SWITCH) && m_switchDescMap != nullptr) + if (block->KindIs(BBJ_SWITCH)) { - SwitchUniqueSuccSet uniqueSuccSet; - if (m_switchDescMap->Lookup(block, &uniqueSuccSet)) + // Create a set with all the successors. + BitVecTraits bitVecTraits(fgBBNumMax + 1, this); + BitVec succBlocks(BitVecOps::MakeEmpty(&bitVecTraits)); + for (unsigned i = 0; i < block->GetSwitchTargets()->GetCaseCount(); i++) { - // Create a set with all the successors. Don't use BlockSet, so we don't need to worry - // about the BlockSet epoch. - BitVecTraits bitVecTraits(fgBBNumMax + 1, this); - BitVec succBlocks(BitVecOps::MakeEmpty(&bitVecTraits)); - for (BasicBlock* const bTarget : block->SwitchTargets()) - { - BitVecOps::AddElemD(&bitVecTraits, succBlocks, bTarget->bbNum); - } - // Now we should have a set of unique successors that matches what's in the switchMap. - // First, check the number of entries, then make sure all the blocks in uniqueSuccSet - // are in the BlockSet. - unsigned count = BitVecOps::Count(&bitVecTraits, succBlocks); - assert(uniqueSuccSet.numDistinctSuccs == count); - for (unsigned i = 0; i < uniqueSuccSet.numDistinctSuccs; i++) - { - assert(BitVecOps::IsMember(&bitVecTraits, succBlocks, - uniqueSuccSet.nonDuplicates[i]->getDestinationBlock()->bbNum)); - } + BasicBlock* const bTarget = block->GetSwitchTargets()->GetCase(i)->getDestinationBlock(); + BitVecOps::AddElemD(&bitVecTraits, succBlocks, bTarget->bbNum); + } + // Now we should have a set of unique successors that matches what's in the switchMap. + // First, check the number of entries, then make sure all the blocks in the unique successor table + // match the blocks in the set. + unsigned count = BitVecOps::Count(&bitVecTraits, succBlocks); + assert(block->GetSwitchTargets()->GetSuccCount() == count); + for (BasicBlock* const bTarget : block->SwitchSuccs()) + { + assert(BitVecOps::IsMember(&bitVecTraits, succBlocks, bTarget->bbNum)); } } } diff --git a/src/runtime/src/coreclr/jit/fgehopt.cpp b/src/runtime/src/coreclr/jit/fgehopt.cpp index 084afc58468..ceb5d7c12a2 100644 --- a/src/runtime/src/coreclr/jit/fgehopt.cpp +++ b/src/runtime/src/coreclr/jit/fgehopt.cpp @@ -1607,7 +1607,7 @@ PhaseStatus Compiler::fgCloneFinally() { if (block->KindIs(BBJ_EHFINALLYRET)) { - assert(block->GetEhfTargets()->bbeCount == 0); + assert(block->GetEhfTargets()->GetSuccCount() == 0); block->SetKind(BBJ_EHFAULTRET); } } diff --git a/src/runtime/src/coreclr/jit/fgflow.cpp b/src/runtime/src/coreclr/jit/fgflow.cpp index f7a055f4a76..c22bde11ea5 100644 --- a/src/runtime/src/coreclr/jit/fgflow.cpp +++ b/src/runtime/src/coreclr/jit/fgflow.cpp @@ -307,10 +307,10 @@ void Compiler::fgRemoveBlockAsPred(BasicBlock* block) case BBJ_EHFINALLYRET: { - BBehfDesc* const ehfDesc = block->GetEhfTargets(); - for (unsigned i = 0; i < ehfDesc->bbeCount; i++) + BBJumpTable* const ehfDesc = block->GetEhfTargets(); + for (unsigned i = 0; i < ehfDesc->GetSuccCount(); i++) { - fgRemoveRefPred(ehfDesc->bbeSuccs[i]); + fgRemoveAllRefPreds(ehfDesc->GetSucc(i)->getDestinationBlock(), block); } break; } @@ -323,9 +323,9 @@ void Compiler::fgRemoveBlockAsPred(BasicBlock* block) case BBJ_SWITCH: { BBswtDesc* const swtDesc = block->GetSwitchTargets(); - for (unsigned i = 0; i < swtDesc->bbsCount; i++) + for (unsigned i = 0; i < swtDesc->GetSuccCount(); i++) { - fgRemoveRefPred(swtDesc->bbsDstTab[i]); + fgRemoveAllRefPreds(swtDesc->GetSucc(i)->getDestinationBlock(), block); } break; } @@ -404,142 +404,3 @@ void Compiler::fgRedirectEdge(FlowEdge*& edge, BasicBlock* newTarget) // Pred list of target should still be ordered assert(newTarget->checkPredListOrder()); } - -//------------------------------------------------------------------------ -// GetDescriptorForSwitch: Returns the SwitchUniqueSuccSet corresponding to 'switchBlk'. -// If it does not exist in the map yet, we build and insert the entry. -// -// Arguments: -// switchBlk -- The switch block -// -// Returns: -// The SwitchUniqueSuccSet corresponding to 'switchBlk' -// -Compiler::SwitchUniqueSuccSet Compiler::GetDescriptorForSwitch(BasicBlock* switchBlk) -{ - assert(switchBlk->KindIs(BBJ_SWITCH)); - BlockToSwitchDescMap* switchMap = GetSwitchDescMap(); - SwitchUniqueSuccSet res; - if (switchMap->Lookup(switchBlk, &res)) - { - return res; - } - else - { - // We must compute the descriptor. Find which are dups, by creating a bit set with the unique successors. - // We create a temporary bitset of blocks to compute the unique set of successor blocks, - // since adding a block's number twice leaves just one "copy" in the bitset. - - BitVecTraits blockVecTraits(fgBBNumMax + 1, this); - BitVec uniqueSuccBlocks(BitVecOps::MakeEmpty(&blockVecTraits)); - for (BasicBlock* const targ : switchBlk->SwitchTargets()) - { - BitVecOps::AddElemD(&blockVecTraits, uniqueSuccBlocks, targ->bbNum); - } - // Now we have a set of unique successors. - unsigned numNonDups = BitVecOps::Count(&blockVecTraits, uniqueSuccBlocks); - - FlowEdge** nonDups = new (getAllocator()) FlowEdge*[numNonDups]; - - unsigned nonDupInd = 0; - - // At this point, all unique targets are in "uniqueSuccBlocks". As we encounter each, - // add to nonDups, remove from "uniqueSuccBlocks". - BBswtDesc* const swtDesc = switchBlk->GetSwitchTargets(); - for (unsigned i = 0; i < swtDesc->bbsCount; i++) - { - FlowEdge* const succEdge = swtDesc->bbsDstTab[i]; - BasicBlock* const targ = succEdge->getDestinationBlock(); - if (BitVecOps::IsMember(&blockVecTraits, uniqueSuccBlocks, targ->bbNum)) - { - nonDups[nonDupInd] = succEdge; - nonDupInd++; - BitVecOps::RemoveElemD(&blockVecTraits, uniqueSuccBlocks, targ->bbNum); - } - } - - assert(nonDupInd == numNonDups); - assert(BitVecOps::Count(&blockVecTraits, uniqueSuccBlocks) == 0); - res.numDistinctSuccs = numNonDups; - res.nonDuplicates = nonDups; - switchMap->Set(switchBlk, res); - return res; - } -} - -//------------------------------------------------------------------------ -// GetDescriptorForSwitchIfAvailable: Gets the SwitchUniqueSuccSet corresponding to 'switchBlk', -// if it exists. Unlike Compiler::GetDescriptorForSwitch, this will not modify the map. -// -// Arguments: -// switchBlk -- The switch block -// res [out] -- Pointer to the SwitchUniqueSuccSet to populate -// -// Returns: -// True if the map exists, and contains an entry for 'switchBlk' -// -bool Compiler::GetDescriptorForSwitchIfAvailable(BasicBlock* switchBlk, SwitchUniqueSuccSet* res) -{ - assert(switchBlk->KindIs(BBJ_SWITCH)); - return (m_switchDescMap != nullptr) && m_switchDescMap->Lookup(switchBlk, res); -} - -//------------------------------------------------------------------------ -// fgRemoveSuccFromSwitchDescMapEntry: Removes a successor edge from the map entry -// for 'switchBlk', if the entry exists. -// -// Arguments: -// switchBlk -- The switch block -// edge -- The successor edge to remove -// -void Compiler::fgRemoveSuccFromSwitchDescMapEntry(BasicBlock* switchBlk, FlowEdge* edge) -{ - assert(switchBlk->KindIs(BBJ_SWITCH)); - - SwitchUniqueSuccSet uniqueSuccSet; - if (!GetDescriptorForSwitchIfAvailable(switchBlk, &uniqueSuccSet)) - { - return; - } - - const unsigned succCount = uniqueSuccSet.numDistinctSuccs; - FlowEdge** const succTab = uniqueSuccSet.nonDuplicates; - bool found = false; - assert(succCount > 0); - assert(succTab != nullptr); - - for (unsigned i = 0; !found && (i < succCount); i++) - { - if (succTab[i] == edge) - { - // If 'edge' is not the last entry, move everything after in the table down one slot. - if ((i + 1) < succCount) - { - memmove_s(&succTab[i], (succCount - i) * sizeof(FlowEdge*), &succTab[i + 1], - (succCount - i - 1) * sizeof(FlowEdge*)); - } - - found = true; - } - } - - assert(found); - uniqueSuccSet.numDistinctSuccs--; - m_switchDescMap->Set(switchBlk, uniqueSuccSet, BlockToSwitchDescMap::SetKind::Overwrite); -} - -//------------------------------------------------------------------------ -// fgInvalidateSwitchDescMapEntry: Removes the entry for 'block' from the -// switch map, if the map exists. -// -// Arguments: -// block -- The switch block -// -void Compiler::fgInvalidateSwitchDescMapEntry(BasicBlock* block) -{ - // Check if map has no entries yet. - if (m_switchDescMap != nullptr) - { - m_switchDescMap->Remove(block); - } -} diff --git a/src/runtime/src/coreclr/jit/fgopt.cpp b/src/runtime/src/coreclr/jit/fgopt.cpp index 49362517371..252f8eba509 100644 --- a/src/runtime/src/coreclr/jit/fgopt.cpp +++ b/src/runtime/src/coreclr/jit/fgopt.cpp @@ -1588,17 +1588,13 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) { assert(block->KindIs(BBJ_SWITCH)); - unsigned jmpCnt = block->GetSwitchTargets()->bbsCount; - FlowEdge** jmpTab = block->GetSwitchTargets()->bbsDstTab; - BasicBlock* bNewDest; // the new jump target for the current switch case - BasicBlock* bDest; - bool modified = false; + bool modified = false; - do + for (unsigned i = 0; i < block->GetSwitchTargets()->GetSuccCount(); i++) { - REPEAT_SWITCH:; - bDest = (*jmpTab)->getDestinationBlock(); - bNewDest = bDest; + FlowEdge* const edge = block->GetSwitchTargets()->GetSucc(i); + BasicBlock* const bDest = edge->getDestinationBlock(); + BasicBlock* bNewDest = bDest; // Do we have a JUMP to an empty unconditional JUMP block? if (bDest->isEmpty() && bDest->KindIs(BBJ_ALWAYS) && !bDest->TargetIs(bDest)) // special case for self jumps @@ -1616,14 +1612,9 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) if (optimizeJump) { bNewDest = bDest->GetTarget(); -#ifdef DEBUG - if (verbose) - { - printf("\nOptimizing a switch jump to an empty block with an unconditional jump (" FMT_BB - " -> " FMT_BB " -> " FMT_BB ")\n", - block->bbNum, bDest->bbNum, bNewDest->bbNum); - } -#endif // DEBUG + JITDUMP("\nOptimizing a switch jump to an empty block with an unconditional jump (" FMT_BB " -> " FMT_BB + " -> " FMT_BB ")\n", + block->bbNum, bDest->bbNum, bNewDest->bbNum); } } @@ -1633,8 +1624,7 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) // if (bDest->hasProfileWeight()) { - FlowEdge* const oldEdge = *jmpTab; - bDest->decreaseBBProfileWeight(oldEdge->getLikelyWeight()); + bDest->decreaseBBProfileWeight(edge->getLikelyWeight()); } // Redirect the jump to the new target @@ -1642,10 +1632,11 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) fgReplaceJumpTarget(block, bDest, bNewDest); modified = true; - // we optimized a Switch label - goto REPEAT_SWITCH to follow this new jump - goto REPEAT_SWITCH; + // Try optimizing this edge again + // + i--; } - } while (++jmpTab, --jmpCnt); + } if (modified) { @@ -1678,24 +1669,15 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) // At this point all of the case jump targets have been updated such // that none of them go to block that is an empty unconditional block - // - jmpTab = block->GetSwitchTargets()->bbsDstTab; - jmpCnt = block->GetSwitchTargets()->bbsCount; - // Now check for two trivial switch jumps. // - if (block->NumSucc(this) == 1) + if (block->GetSwitchTargets()->GetSuccCount() == 1) { // Use BBJ_ALWAYS for a switch with only a default clause, or with only one unique successor. -#ifdef DEBUG - if (verbose) - { - printf("\nRemoving a switch jump with a single target (" FMT_BB ")\n", block->bbNum); - printf("BEFORE:\n"); - fgDispBasicBlocks(); - } -#endif // DEBUG + JITDUMP("\nRemoving a switch jump with a single target (" FMT_BB ")\n", block->bbNum); + JITDUMP("BEFORE:\n"); + DBEXEC(verbose, fgDispBasicBlocks()); if (block->IsLIR()) { @@ -1765,15 +1747,13 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) } // Change the switch jump into a BBJ_ALWAYS - block->SetKindAndTargetEdge(BBJ_ALWAYS, block->GetSwitchTargets()->bbsDstTab[0]); - for (unsigned i = 1; i < jmpCnt; ++i) - { - fgRemoveRefPred(jmpTab[i]); - } - + block->SetKindAndTargetEdge(BBJ_ALWAYS, block->GetSwitchTargets()->GetCase(0)); + const unsigned dupCount = block->GetTargetEdge()->getDupCount(); + block->GetTargetEdge()->decrementDupCount(dupCount - 1); + block->GetTarget()->bbRefs -= (dupCount - 1); return true; } - else if (block->GetSwitchTargets()->bbsCount == 2) + else if (block->GetSwitchTargets()->GetCaseCount() == 2) { /* Use a BBJ_COND(switchVal==0) for a switch with only one significant clause besides the default clause */ @@ -1795,16 +1775,10 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) // a COMMA node which results in noway asserts in fgMorphSmpOp(), optAssertionGen() and rpPredictTreeRegUse(). // For the same reason fgMorphSmpOp() marks GT_JTRUE nodes with RELOP children as GTF_DONT_CSE. -#ifdef DEBUG - if (verbose) - { - printf("\nConverting a switch (" FMT_BB ") with only one significant clause besides a default target to a " - "conditional branch. Before:\n", - block->bbNum); - - gtDispTree(switchTree); - } -#endif // DEBUG + JITDUMP("\nConverting a switch (" FMT_BB ") with only one significant clause besides a default target to a " + "conditional branch. Before:\n", + block->bbNum); + DISPNODE(switchTree); switchTree->ChangeOper(GT_JTRUE); GenTree* zeroConstNode = gtNewZeroConNode(genActualType(switchVal->TypeGet())); @@ -1824,8 +1798,8 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) fgSetStmtSeq(switchStmt); } - FlowEdge* const trueEdge = block->GetSwitchTargets()->bbsDstTab[0]; - FlowEdge* const falseEdge = block->GetSwitchTargets()->bbsDstTab[1]; + FlowEdge* const trueEdge = block->GetSwitchTargets()->GetCase(0); + FlowEdge* const falseEdge = block->GetSwitchTargets()->GetCase(1); block->SetCond(trueEdge, falseEdge); JITDUMP("After:\n"); @@ -2778,7 +2752,7 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump) void Compiler::fgPeelSwitch(BasicBlock* block) { assert(block->KindIs(BBJ_SWITCH)); - assert(block->GetSwitchTargets()->bbsHasDominantCase); + assert(block->GetSwitchTargets()->HasDominantCase()); assert(!block->isRunRarely()); // Lowering expands switches, so calling this method on lowered IR @@ -2790,13 +2764,13 @@ void Compiler::fgPeelSwitch(BasicBlock* block) // assert(block->hasProfileWeight()); - const unsigned dominantCase = block->GetSwitchTargets()->bbsDominantCase; + const unsigned dominantCase = block->GetSwitchTargets()->GetDominantCase(); JITDUMP(FMT_BB " has switch with dominant case %u, considering peeling\n", block->bbNum, dominantCase); // The dominant case should not be the default case, as we already peel that one. // - assert(dominantCase < (block->GetSwitchTargets()->bbsCount - 1)); - FlowEdge* const dominantEdge = block->GetSwitchTargets()->bbsDstTab[dominantCase]; + assert(dominantCase < (block->GetSwitchTargets()->GetCaseCount() - 1)); + FlowEdge* const dominantEdge = block->GetSwitchTargets()->GetCase(dominantCase); BasicBlock* const dominantTarget = dominantEdge->getDestinationBlock(); Statement* const switchStmt = block->lastStmt(); GenTree* const switchTree = switchStmt->GetRootNode(); @@ -2856,9 +2830,8 @@ void Compiler::fgPeelSwitch(BasicBlock* block) // and increase all other case likelihoods proportionally. // dominantEdge->setLikelihood(BB_ZERO_WEIGHT); - const SwitchUniqueSuccSet uniqueSuccSet = GetDescriptorForSwitch(newBlock); - const unsigned numSucc = uniqueSuccSet.numDistinctSuccs; - FlowEdge** const jumpTab = uniqueSuccSet.nonDuplicates; + const unsigned numSucc = newBlock->GetSwitchTargets()->GetSuccCount(); + FlowEdge** const jumpTab = newBlock->GetSwitchTargets()->GetSuccs(); for (unsigned i = 0; i < numSucc; i++) { // If we removed all of the flow out of 'block', distribute flow among the remaining edges evenly. @@ -2872,7 +2845,7 @@ void Compiler::fgPeelSwitch(BasicBlock* block) // // But it no longer has a dominant case. // - newBlock->GetSwitchTargets()->bbsHasDominantCase = false; + newBlock->GetSwitchTargets()->RemoveDominantCase(); if (fgNodeThreading == NodeThreading::AllTrees) { diff --git a/src/runtime/src/coreclr/jit/fgprofile.cpp b/src/runtime/src/coreclr/jit/fgprofile.cpp index bafd120b2b8..ff83d3d0e2b 100644 --- a/src/runtime/src/coreclr/jit/fgprofile.cpp +++ b/src/runtime/src/coreclr/jit/fgprofile.cpp @@ -4136,8 +4136,8 @@ void EfficientEdgeCountReconstructor::MarkInterestingSwitches(BasicBlock* block, // If it turns out often we fail at this stage, we might consider building a histogram of switch case // values at runtime, similar to what we do for classes at virtual call sites. // - const unsigned caseCount = block->GetSwitchTargets()->bbsCount; - FlowEdge** const jumpTab = block->GetSwitchTargets()->bbsDstTab; + const unsigned caseCount = block->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const jumpTab = block->GetSwitchTargets()->GetCases(); unsigned dominantCase = caseCount; for (unsigned i = 0; i < caseCount; i++) @@ -4164,7 +4164,7 @@ void EfficientEdgeCountReconstructor::MarkInterestingSwitches(BasicBlock* block, return; } - if (block->GetSwitchTargets()->bbsHasDefault && (dominantCase == caseCount - 1)) + if (block->GetSwitchTargets()->HasDefaultCase() && (dominantCase == caseCount - 1)) { // Dominant case is the default case. // This effectively gets peeled already, so defer. @@ -4178,8 +4178,7 @@ void EfficientEdgeCountReconstructor::MarkInterestingSwitches(BasicBlock* block, "; marking for peeling\n", dominantCase, dominantEdge->m_targetBlock->bbNum, fraction); - block->GetSwitchTargets()->bbsHasDominantCase = true; - block->GetSwitchTargets()->bbsDominantCase = dominantCase; + block->GetSwitchTargets()->SetDominantCase(dominantCase); } //------------------------------------------------------------------------ diff --git a/src/runtime/src/coreclr/jit/flowgraph.cpp b/src/runtime/src/coreclr/jit/flowgraph.cpp index 4db0f7b1ccb..70cfe579923 100644 --- a/src/runtime/src/coreclr/jit/flowgraph.cpp +++ b/src/runtime/src/coreclr/jit/flowgraph.cpp @@ -1290,11 +1290,7 @@ GenTree* Compiler::fgGetCritSectOfStaticMethod() } else { - void *critSect = nullptr, **pCrit = nullptr; - critSect = info.compCompHnd->getMethodSync(info.compMethodHnd, (void**)&pCrit); - noway_assert((!critSect) != (!pCrit)); - - tree = gtNewIconEmbHndNode(critSect, pCrit, GTF_ICON_GLOBAL_PTR, info.compMethodHnd); + tree = gtNewIconEmbClsHndNode(info.compClassHnd); // Given the class handle, get the pointer to the Monitor. tree = gtNewHelperCallNode(CORINFO_HELP_GETSYNCFROMCLASSHANDLE, TYP_REF, tree); diff --git a/src/runtime/src/coreclr/jit/gentree.cpp b/src/runtime/src/coreclr/jit/gentree.cpp index 29682889d4d..6066f4c5c94 100644 --- a/src/runtime/src/coreclr/jit/gentree.cpp +++ b/src/runtime/src/coreclr/jit/gentree.cpp @@ -20737,7 +20737,7 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, // Some intrinsics are effectively bitwise operations and so we // can freely update them to match the size of the actual mask - bool supportsMaskBaseSize4Or8 = false; + bool supportsMaskBaseSize2Or4 = false; switch (ins) { @@ -20762,13 +20762,13 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, case INS_xorpd: case INS_xorps: { - // These intrinsics support embedded broadcast and have masking support for 4 or 8 - assert((maskBaseSize == 4) || (maskBaseSize == 8)); + // These intrinsics support embedded broadcast and have masking support for 2 or 4 + assert((maskBaseSize == 2) || (maskBaseSize == 4)); if (!comp->codeGen->IsEmbeddedBroadcastEnabled(ins, node->Op(2))) { // We cannot change the base type if we've already contained a broadcast - supportsMaskBaseSize4Or8 = true; + supportsMaskBaseSize2Or4 = true; } break; } @@ -20776,13 +20776,13 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, case INS_vpternlogd: case INS_vpternlogq: { - // These intrinsics support embedded broadcast and have masking support for 4 or 8 - assert((maskBaseSize == 4) || (maskBaseSize == 8)); + // These intrinsics support embedded broadcast and have masking support for 2 or 4 + assert((maskBaseSize == 2) || (maskBaseSize == 4)); if (!comp->codeGen->IsEmbeddedBroadcastEnabled(ins, node->Op(3))) { // We cannot change the base type if we've already contained a broadcast - supportsMaskBaseSize4Or8 = true; + supportsMaskBaseSize2Or4 = true; } break; } @@ -20812,9 +20812,9 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, case INS_vinserti64x2: case INS_vinserti64x4: { - // These intrinsics don't support embedded broadcast and have masking support for 4 or 8 - assert((maskBaseSize == 4) || (maskBaseSize == 8)); - supportsMaskBaseSize4Or8 = true; + // These intrinsics don't support embedded broadcast and have masking support for 2 or 4 + assert((maskBaseSize == 2) || (maskBaseSize == 4)); + supportsMaskBaseSize2Or4 = true; break; } @@ -20824,9 +20824,9 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, } } - if (supportsMaskBaseSize4Or8) + if (supportsMaskBaseSize2Or4) { - if (tgtMaskBaseSize == 8) + if (tgtMaskBaseSize == 2) { if (varTypeIsFloating(simdBaseType)) { @@ -32618,6 +32618,78 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) { switch (ni) { +#if defined(TARGET_ARM64) + case NI_Vector64_ExtractMostSignificantBits: +#elif defined(TARGET_XARCH) + case NI_Vector256_ExtractMostSignificantBits: + case NI_X86Base_MoveMask: + case NI_AVX_MoveMask: + case NI_AVX2_MoveMask: +#endif + case NI_Vector128_ExtractMostSignificantBits: + { + simdmask_t simdMaskVal; + + switch (simdSize) + { + case 8: + { + EvaluateExtractMSB(simdBaseType, &simdMaskVal, cnsNode->AsVecCon()->gtSimd8Val); + break; + } + + case 16: + { + EvaluateExtractMSB(simdBaseType, &simdMaskVal, cnsNode->AsVecCon()->gtSimd16Val); + break; + } + +#if defined(TARGET_XARCH) + case 32: + { + EvaluateExtractMSB(simdBaseType, &simdMaskVal, cnsNode->AsVecCon()->gtSimd32Val); + break; + } +#endif // TARGET_XARCH + + default: + { + unreached(); + } + } + + uint32_t elemCount = simdSize / genTypeSize(simdBaseType); + uint64_t mask = simdMaskVal.GetRawBits() & simdmask_t::GetBitMask(elemCount); + + assert(varTypeIsInt(retType)); + assert(elemCount <= 32); + + resultNode = gtNewIconNode(static_cast(mask)); + break; + } + +#ifdef TARGET_XARCH + case NI_AVX512_MoveMask: + { + GenTreeMskCon* mskCns = cnsNode->AsMskCon(); + + uint32_t elemCount = simdSize / genTypeSize(simdBaseType); + uint64_t mask = mskCns->gtSimdMaskVal.GetRawBits() & simdmask_t::GetBitMask(elemCount); + + if (varTypeIsInt(retType)) + { + assert(elemCount <= 32); + resultNode = gtNewIconNode(static_cast(mask)); + } + else + { + assert(varTypeIsLong(retType)); + resultNode = gtNewLconNode(static_cast(mask)); + } + break; + } +#endif // TARGET_XARCH + #ifdef TARGET_ARM64 case NI_ArmBase_LeadingZeroCount: #else diff --git a/src/runtime/src/coreclr/jit/hwintrinsicarm64.cpp b/src/runtime/src/coreclr/jit/hwintrinsicarm64.cpp index 6631da478c9..18ba7125359 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/runtime/src/coreclr/jit/hwintrinsicarm64.cpp @@ -299,6 +299,18 @@ void Compiler::getHWIntrinsicImmTypes(NamedIntrinsic intrinsic, } } + if (intrinsic == NI_Sve2_MultiplyBySelectedScalar || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningEven || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningEvenAndAdd || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningOdd || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningOddAndAdd || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningOddAndSubtract || + intrinsic == NI_Sve2_MultiplySubtractBySelectedScalar) + { + indexedElementBaseType = simdBaseType; + } + assert(indexedElementBaseType == simdBaseType); } else if (intrinsic == NI_AdvSimd_Arm64_InsertSelectedScalar) @@ -362,14 +374,24 @@ void HWIntrinsicInfo::lookupImmBounds( } else if (category == HW_Category_SIMDByIndexedElement) { - if (intrinsic == NI_Sve_DuplicateSelectedScalarToVector) - { - // For SVE_DUP, the upper bound on index does not depend on the vector length. - immUpperBound = (512 / (BITS_PER_BYTE * genTypeSize(baseType))) - 1; - } - else + switch (intrinsic) { - immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType) - 1; + case NI_Sve_DuplicateSelectedScalarToVector: + // For SVE_DUP, the upper bound on index does not depend on the vector length. + immUpperBound = (512 / (BITS_PER_BYTE * genTypeSize(baseType))) - 1; + break; + case NI_Sve2_MultiplyBySelectedScalarWideningEven: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndAdd: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract: + case NI_Sve2_MultiplyBySelectedScalarWideningOdd: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndAdd: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndSubtract: + // Index is on the half-width vector, hence double the maximum index. + immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType) * 2 - 1; + break; + default: + immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType) - 1; + break; } } else @@ -1346,166 +1368,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_ExtractMostSignificantBits: { assert(sig->numArgs == 1); - - // ARM64 doesn't have a single instruction that performs the behavior so we'll emulate it instead. - // To do this, we effectively perform the following steps: - // 1. tmp = input & 0x80 ; and the input to clear all but the most significant bit - // 2. tmp = tmp >> index ; right shift each element by its index - // 3. tmp = sum(tmp) ; sum the elements together - - // For byte/sbyte, we also need to handle the fact that we can only shift by up to 8 - // but for Vector128, we have 16 elements to handle. In that scenario, we will simply - // extract both scalars, and combine them via: (upper << 8) | lower - - var_types simdType = getSIMDTypeForSize(simdSize); - - op1 = impSIMDPopStack(); - - GenTreeVecCon* vecCon2 = gtNewVconNode(simdType); - GenTreeVecCon* vecCon3 = gtNewVconNode(simdType); - - switch (simdBaseType) - { - case TYP_BYTE: - case TYP_UBYTE: - { - simdBaseType = TYP_UBYTE; - simdBaseJitType = CORINFO_TYPE_UBYTE; - - vecCon2->gtSimdVal.u64[0] = 0x8080808080808080; - vecCon3->gtSimdVal.u64[0] = 0x00FFFEFDFCFBFAF9; - - if (simdSize == 16) - { - vecCon2->gtSimdVal.u64[1] = 0x8080808080808080; - vecCon3->gtSimdVal.u64[1] = 0x00FFFEFDFCFBFAF9; - } - break; - } - - case TYP_SHORT: - case TYP_USHORT: - { - simdBaseType = TYP_USHORT; - simdBaseJitType = CORINFO_TYPE_USHORT; - - vecCon2->gtSimdVal.u64[0] = 0x8000800080008000; - vecCon3->gtSimdVal.u64[0] = 0xFFF4FFF3FFF2FFF1; - - if (simdSize == 16) - { - vecCon2->gtSimdVal.u64[1] = 0x8000800080008000; - vecCon3->gtSimdVal.u64[1] = 0xFFF8FFF7FFF6FFF5; - } - break; - } - - case TYP_INT: - case TYP_UINT: - case TYP_FLOAT: - { - simdBaseType = TYP_INT; - simdBaseJitType = CORINFO_TYPE_INT; - - vecCon2->gtSimdVal.u64[0] = 0x8000000080000000; - vecCon3->gtSimdVal.u64[0] = 0xFFFFFFE2FFFFFFE1; - - if (simdSize == 16) - { - vecCon2->gtSimdVal.u64[1] = 0x8000000080000000; - vecCon3->gtSimdVal.u64[1] = 0xFFFFFFE4FFFFFFE3; - } - break; - } - - case TYP_LONG: - case TYP_ULONG: - case TYP_DOUBLE: - { - simdBaseType = TYP_LONG; - simdBaseJitType = CORINFO_TYPE_LONG; - - vecCon2->gtSimdVal.u64[0] = 0x8000000000000000; - vecCon3->gtSimdVal.u64[0] = 0xFFFFFFFFFFFFFFC1; - - if (simdSize == 16) - { - vecCon2->gtSimdVal.u64[1] = 0x8000000000000000; - vecCon3->gtSimdVal.u64[1] = 0xFFFFFFFFFFFFFFC2; - } - break; - } - - default: - { - unreached(); - } - } - - op3 = vecCon3; - op2 = vecCon2; - op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op2, NI_AdvSimd_And, simdBaseJitType, simdSize); - - NamedIntrinsic shiftIntrinsic = NI_AdvSimd_ShiftLogical; - - if ((simdSize == 8) && varTypeIsLong(simdBaseType)) - { - shiftIntrinsic = NI_AdvSimd_ShiftLogicalScalar; - } - - op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op3, shiftIntrinsic, simdBaseJitType, simdSize); - - if (varTypeIsByte(simdBaseType) && (simdSize == 16)) - { - op1 = impCloneExpr(op1, &op2, CHECK_SPILL_ALL, - nullptr DEBUGARG("Clone op1 for vector extractmostsignificantbits")); - - op1 = gtNewSimdGetLowerNode(TYP_SIMD8, op1, simdBaseJitType, simdSize); - op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, 8); - op1 = gtNewSimdToScalarNode(genActualType(simdBaseType), op1, simdBaseJitType, 8); - op1 = gtNewCastNode(TYP_INT, op1, /* isUnsigned */ true, TYP_INT); - - GenTree* zero = gtNewZeroConNode(TYP_SIMD16); - ssize_t index = 8 / genTypeSize(simdBaseType); - - op2 = gtNewSimdGetUpperNode(TYP_SIMD8, op2, simdBaseJitType, simdSize); - op2 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op2, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, 8); - op2 = gtNewSimdToScalarNode(genActualType(simdBaseType), op2, simdBaseJitType, 8); - op2 = gtNewCastNode(TYP_INT, op2, /* isUnsigned */ true, TYP_INT); - - op2 = gtNewOperNode(GT_LSH, TYP_INT, op2, gtNewIconNode(8)); - retNode = gtNewOperNode(GT_OR, TYP_INT, op1, op2); - } - else - { - if (!varTypeIsLong(simdBaseType)) - { - if ((simdSize == 8) && ((simdBaseType == TYP_INT) || (simdBaseType == TYP_UINT))) - { - op1 = impCloneExpr(op1, &op2, CHECK_SPILL_ALL, - nullptr DEBUGARG("Clone op1 for vector extractmostsignificantbits")); - op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, op2, NI_AdvSimd_AddPairwise, simdBaseJitType, - simdSize); - } - else - { - op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, - simdSize); - } - } - else if (simdSize == 16) - { - op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddPairwiseScalar, simdBaseJitType, - simdSize); - } - - retNode = gtNewSimdToScalarNode(genActualType(simdBaseType), op1, simdBaseJitType, 8); - - if ((simdBaseType != TYP_INT) && (simdBaseType != TYP_UINT)) - { - retNode = gtNewCastNode(TYP_INT, retNode, /* isUnsigned */ true, TYP_INT); - } - } + op1 = impSIMDPopStack(); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize); break; } diff --git a/src/runtime/src/coreclr/jit/hwintrinsiclistarm64.h b/src/runtime/src/coreclr/jit/hwintrinsiclistarm64.h index 25433249351..ec721f567c5 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/runtime/src/coreclr/jit/hwintrinsiclistarm64.h @@ -51,7 +51,7 @@ HARDWARE_INTRINSIC(Vector64, CreateSequence, HARDWARE_INTRINSIC(Vector64, Dot, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, Equals, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, EqualsAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, ExtractMostSignificantBits, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, ExtractMostSignificantBits, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, Floor, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, FusedMultiplyAdd, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, GetElement, 8, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SupportsContainment) @@ -182,7 +182,7 @@ HARDWARE_INTRINSIC(Vector128, CreateSequence, HARDWARE_INTRINSIC(Vector128, Dot, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, Equals, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, EqualsAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, Floor, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, FusedMultiplyAdd, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SupportsContainment) diff --git a/src/runtime/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/runtime/src/coreclr/jit/hwintrinsiclistarm64sve.h index e122c847bb5..e29129dde94 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/runtime/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -324,6 +324,8 @@ HARDWARE_INTRINSIC(Sve2, AddHighNarrowingEven, HARDWARE_INTRINSIC(Sve2, AddHighNarrowingOdd, -1, 3, {INS_sve_addhnt, INS_sve_addhnt, INS_sve_addhnt, INS_sve_addhnt, INS_sve_addhnt, INS_sve_addhnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, AddPairwise, -1, -1, {INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_faddp, INS_sve_faddp}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve2, AddPairwiseWideningAndAdd, -1, -1, {INS_invalid, INS_invalid, INS_sve_sadalp, INS_sve_uadalp, INS_sve_sadalp, INS_sve_uadalp, INS_sve_sadalp, INS_sve_uadalp, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve2, AddRoundedHighNarrowingEven, -1, 2, {INS_sve_raddhnb, INS_sve_raddhnb, INS_sve_raddhnb, INS_sve_raddhnb, INS_sve_raddhnb, INS_sve_raddhnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, AddRoundedHighNarrowingOdd, -1, 3, {INS_sve_raddhnt, INS_sve_raddhnt, INS_sve_raddhnt, INS_sve_raddhnt, INS_sve_raddhnt, INS_sve_raddhnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, AddSaturate, -1, -1, {INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, AddSaturateWithSignedAddend, -1, -1, {INS_invalid, INS_sve_usqadd, INS_invalid, INS_sve_usqadd, INS_invalid, INS_sve_usqadd, INS_invalid, INS_sve_usqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, AddSaturateWithUnsignedAddend, -1, -1, {INS_sve_suqadd, INS_invalid, INS_sve_suqadd, INS_invalid, INS_sve_suqadd, INS_invalid, INS_sve_suqadd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) @@ -335,9 +337,28 @@ HARDWARE_INTRINSIC(Sve2, BitwiseSelect, HARDWARE_INTRINSIC(Sve2, BitwiseSelectLeftInverted, -1, 3, {INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelectRightInverted, -1, 3, {INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, FusedAddHalving, -1, -1, {INS_sve_shadd, INS_sve_uhadd, INS_sve_shadd, INS_sve_uhadd, INS_sve_shadd, INS_sve_uhadd, INS_sve_shadd, INS_sve_uhadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve2, FusedAddRoundedHalving, -1, -1, {INS_sve_srhadd, INS_sve_urhadd, INS_sve_srhadd, INS_sve_urhadd, INS_sve_srhadd, INS_sve_urhadd, INS_sve_srhadd, INS_sve_urhadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, FusedSubtractHalving, -1, -1, {INS_sve_shsub, INS_sve_uhsub, INS_sve_shsub, INS_sve_uhsub, INS_sve_shsub, INS_sve_uhsub, INS_sve_shsub, INS_sve_uhsub, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, InterleavingXorEvenOdd, -1, 3, {INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, InterleavingXorOddEven, -1, 3, {INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyAddBySelectedScalar, -1, 4, {INS_invalid, INS_invalid, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalar, -1, 3, {INS_invalid, INS_invalid, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningEven, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smullb, INS_sve_umullb, INS_sve_smullb, INS_sve_umullb, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningEvenAndAdd, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smlalb, INS_sve_umlalb, INS_sve_smlalb, INS_sve_umlalb, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningEvenAndSubtract, -1, 4, {INS_invalid, INS_invalid, INS_sve_smlslb, INS_sve_umlslb, INS_sve_smlslb, INS_sve_umlslb, INS_sve_smlslb, INS_sve_umlslb, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningOdd, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smullt, INS_sve_umullt, INS_sve_smullt, INS_sve_umullt, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningOddAndAdd, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smlalt, INS_sve_umlalt, INS_sve_smlalt, INS_sve_umlalt, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningOddAndSubtract, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smlslt, INS_sve_umlslt, INS_sve_smlslt, INS_sve_umlslt, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplySubtractBySelectedScalar, -1, 4, {INS_invalid, INS_invalid, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_smullb, INS_sve_umullb, INS_sve_smullb, INS_sve_umullb, INS_sve_smullb, INS_sve_umullb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningEvenAndAdd, -1, 3, {INS_invalid, INS_invalid, INS_sve_smlalb, INS_sve_umlalb, INS_sve_smlalb, INS_sve_umlalb, INS_sve_smlalb, INS_sve_umlalb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningEvenAndSubtract, -1, 3, {INS_invalid, INS_invalid, INS_sve_smlslb, INS_sve_umlslb, INS_sve_smlslb, INS_sve_umlslb, INS_sve_smlslb, INS_sve_umlslb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_smullt, INS_sve_umullt, INS_sve_smullt, INS_sve_umullt, INS_sve_smullt, INS_sve_umullt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningOddAndAdd, -1, 3, {INS_invalid, INS_invalid, INS_sve_smlalt, INS_sve_umlalt, INS_sve_smlalt, INS_sve_umlalt, INS_sve_smlalt, INS_sve_umlalt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningOddAndSubtract, -1, 3, {INS_invalid, INS_invalid, INS_sve_smlslt, INS_sve_umlslt, INS_sve_smlslt, INS_sve_umlslt, INS_sve_smlslt, INS_sve_umlslt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, PolynomialMultiply, -1, 2, {INS_sve_pmul, INS_sve_pmul, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, PolynomialMultiplyWideningEven, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_sve_pmullb, INS_invalid, INS_invalid, INS_invalid, INS_sve_pmullb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, PolynomialMultiplyWideningOdd, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_sve_pmullt, INS_invalid, INS_invalid, INS_invalid, INS_sve_pmullt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, ShiftArithmeticRounded, -1, -1, {INS_sve_srshl, INS_invalid, INS_sve_srshl, INS_invalid, INS_sve_srshl, INS_invalid, INS_sve_srshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, ShiftArithmeticRoundedSaturate, -1, -1, {INS_sve_sqrshl, INS_invalid, INS_sve_sqrshl, INS_invalid, INS_sve_sqrshl, INS_invalid, INS_sve_sqrshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, ShiftArithmeticSaturate, -1, -1, {INS_sve_sqshl, INS_invalid, INS_sve_sqshl, INS_invalid, INS_sve_sqshl, INS_invalid, INS_sve_sqshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) @@ -369,16 +390,17 @@ HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingEven, HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingOdd, -1, 3, {INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingSaturateEven, -1, 2, {INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingSaturateOdd, -1, 3, {INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, SubtractBorrowWideningEven, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sbclb, INS_invalid, INS_sve_sbclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, SubtractBorrowWideningOdd, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sbclt, INS_invalid, INS_sve_sbclt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, SubtractHighNarrowingEven, -1, 2, {INS_sve_subhnb, INS_sve_subhnb, INS_sve_subhnb, INS_sve_subhnb, INS_sve_subhnb, INS_sve_subhnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, SubtractHighNarrowingOdd, -1, 3, {INS_sve_subhnt, INS_sve_subhnt, INS_sve_subhnt, INS_sve_subhnt, INS_sve_subhnt, INS_sve_subhnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, SubtractRoundedHighNarrowingEven, -1, 2, {INS_sve_rsubhnb, INS_sve_rsubhnb, INS_sve_rsubhnb, INS_sve_rsubhnb, INS_sve_rsubhnb, INS_sve_rsubhnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, SubtractRoundedHighNarrowingOdd, -1, 3, {INS_sve_rsubhnt, INS_sve_rsubhnt, INS_sve_rsubhnt, INS_sve_rsubhnt, INS_sve_rsubhnt, INS_sve_rsubhnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, SubtractSaturate, -1, -1, {INS_sve_sqsub, INS_sve_uqsub, INS_sve_sqsub, INS_sve_uqsub, INS_sve_sqsub, INS_sve_uqsub, INS_sve_sqsub, INS_sve_uqsub, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sve2, SubtractSaturateReversed, -1, -1, {INS_sve_sqsubr, INS_sve_uqsubr, INS_sve_sqsubr, INS_sve_uqsubr, INS_sve_sqsubr, INS_sve_uqsubr, INS_sve_sqsubr, INS_sve_uqsubr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, SubtractWideningEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_ssubwb, INS_sve_usubwb, INS_sve_ssubwb, INS_sve_usubwb, INS_sve_ssubwb, INS_sve_usubwb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve2, SubtractWideningEvenOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_ssublbt, INS_invalid, INS_sve_ssublbt, INS_invalid, INS_sve_ssublbt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, SubtractWideningOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_ssubwt, INS_sve_usubwt, INS_sve_ssubwt, INS_sve_usubwt, INS_sve_ssubwt, INS_sve_usubwt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve2, SubtractWideningOddEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_ssubltb, INS_invalid, INS_sve_ssubltb, INS_invalid, INS_sve_ssubltb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) -HARDWARE_INTRINSIC(Sve2, SubtractWithBorrowWideningLower, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sbclb, INS_invalid, INS_sve_sbclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sve2, SubtractWithBorrowWideningUpper, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sbclt, INS_invalid, INS_sve_sbclt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, VectorTableLookup, -1, 2, {INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_NeedsConsecutiveRegisters|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve2, VectorTableLookupExtension, -1, 3, {INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, Xor, -1, 3, {INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) diff --git a/src/runtime/src/coreclr/jit/hwintrinsiclistxarch.h b/src/runtime/src/coreclr/jit/hwintrinsiclistxarch.h index 7786d481a11..be680becff0 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/runtime/src/coreclr/jit/hwintrinsiclistxarch.h @@ -69,7 +69,7 @@ HARDWARE_INTRINSIC(Vector128, CreateSequence, HARDWARE_INTRINSIC(Vector128, Dot, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, Equals, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, EqualsAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, Floor, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, FusedMultiplyAdd, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_extractps, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) @@ -197,7 +197,7 @@ HARDWARE_INTRINSIC(Vector256, CreateSequence, HARDWARE_INTRINSIC(Vector256, Dot, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, Equals, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, EqualsAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector256, ExtractMostSignificantBits, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector256, ExtractMostSignificantBits, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector256, Floor, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, FusedMultiplyAdd, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, GetElement, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible) diff --git a/src/runtime/src/coreclr/jit/hwintrinsicxarch.cpp b/src/runtime/src/coreclr/jit/hwintrinsicxarch.cpp index a333b87bbff..c614918b207 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/runtime/src/coreclr/jit/hwintrinsicxarch.cpp @@ -2406,7 +2406,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { op1 = impSIMDPopStack(); - op1 = gtNewSimdCvtVectorToMaskNode(TYP_MASK, op1, simdBaseJitType, simdSize); + op1 = gtFoldExpr(gtNewSimdCvtVectorToMaskNode(TYP_MASK, op1, simdBaseJitType, simdSize)); retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize); break; } @@ -2432,64 +2432,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case TYP_SHORT: case TYP_USHORT: { - simd_t simdVal = {}; - - assert((simdSize == 16) || (simdSize == 32) || (simdSize == 64)); - simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UBYTE : CORINFO_TYPE_BYTE; - - // We want to tightly pack the most significant byte of each short/ushort - // and then zero the tightly packed least significant bytes - // - // The most significant bit being set means zero the value - - simdVal.u64[0] = 0x0F0D0B0907050301; - simdVal.u64[1] = 0x8080808080808080; - - if (simdSize == 32) - { - // Vector256 works on 2x128-bit lanes, so repeat the same indices for the upper lane - - simdVal.u64[2] = 0x0F0D0B0907050301; - simdVal.u64[3] = 0x8080808080808080; - - shuffleIntrinsic = NI_AVX2_Shuffle; - moveMaskIntrinsic = NI_X86Base_MoveMask; - } - else if (compOpportunisticallyDependsOn(InstructionSet_SSE42)) - { - shuffleIntrinsic = NI_SSE42_Shuffle; - moveMaskIntrinsic = NI_X86Base_MoveMask; - } - else - { - return nullptr; - } - - op2 = gtNewVconNode(simdType); - memcpy(&op2->AsVecCon()->gtSimdVal, &simdVal, simdSize); - - op1 = impSIMDPopStack(); - op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op2, shuffleIntrinsic, simdBaseJitType, simdSize); - - if (simdSize == 32) - { - CorInfoType simdOtherJitType; - - // Since Vector256 is 2x128-bit lanes we need a full width permutation so we get the lower - // 64-bits of each lane next to eachother. The upper bits should be zero, but also don't - // matter so we can also then simplify down to a 128-bit move mask. - - simdOtherJitType = (simdBaseType == TYP_UBYTE) ? CORINFO_TYPE_ULONG : CORINFO_TYPE_LONG; - - op1 = gtNewSimdHWIntrinsicNode(simdType, op1, gtNewIconNode(0xD8), NI_AVX2_Permute4x64, - simdOtherJitType, simdSize); - - simdType = TYP_SIMD16; - - op1 = gtNewSimdGetLowerNode(simdType, op1, simdBaseJitType, simdSize); - - simdSize = 16; - } + op1 = impSIMDPopStack(); + moveMaskIntrinsic = intrinsic; break; } @@ -2523,6 +2467,14 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(op1 != nullptr); retNode = gtNewSimdHWIntrinsicNode(retType, op1, moveMaskIntrinsic, simdBaseJitType, simdSize); + + if ((simdSize == 16) && varTypeIsShort(simdBaseType)) + { + if (!compOpportunisticallyDependsOn(InstructionSet_SSE42)) + { + retNode->AsHWIntrinsic()->SetMethodHandle(this, method R2RARG(*entryPoint)); + } + } } break; } @@ -4993,7 +4945,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } } intrinsic = NI_AVX512_BlendVariableMask; - op3 = gtNewSimdCvtVectorToMaskNode(TYP_MASK, op3, simdBaseJitType, simdSize); + op3 = gtFoldExpr(gtNewSimdCvtVectorToMaskNode(TYP_MASK, op3, simdBaseJitType, simdSize)); } retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize); break; @@ -5531,7 +5483,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { retType = getSIMDTypeForSize(simdSize); assert(retType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass))); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdCvtMaskToVectorNode(retType, gtFoldExpr(retNode), simdBaseJitType, simdSize); } else if (isMinMaxIntrinsic) { diff --git a/src/runtime/src/coreclr/jit/importer.cpp b/src/runtime/src/coreclr/jit/importer.cpp index bee5fe142f4..70b78bc0477 100644 --- a/src/runtime/src/coreclr/jit/importer.cpp +++ b/src/runtime/src/coreclr/jit/importer.cpp @@ -8056,8 +8056,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) { // Find the jump target size_t switchVal = (size_t)op1->AsIntCon()->gtIconVal; - unsigned jumpCnt = block->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTab = block->GetSwitchTargets()->bbsDstTab; + unsigned jumpCnt = block->GetSwitchTargets()->GetCaseCount(); + FlowEdge** jumpTab = block->GetSwitchTargets()->GetCases(); bool foundVal = false; Metrics.ImporterSwitchFold++; @@ -8084,15 +8084,11 @@ void Compiler::impImportBlockCode(BasicBlock* block) } assert(foundVal); -#ifdef DEBUG - if (verbose) - { - printf("\nSwitch folded at " FMT_BB "\n", block->bbNum); - printf(FMT_BB " becomes a %s", block->bbNum, "BBJ_ALWAYS"); - printf(" to " FMT_BB, block->GetTarget()->bbNum); - printf("\n"); - } -#endif + JITDUMP("\nSwitch folded at " FMT_BB "\n", block->bbNum); + JITDUMP(FMT_BB " becomes a %s", block->bbNum, "BBJ_ALWAYS"); + JITDUMP(" to " FMT_BB, block->GetTarget()->bbNum); + JITDUMP("\n"); + if (block->hasProfileWeight()) { // We are unlikely to be able to repair the profile. @@ -11841,7 +11837,7 @@ void Compiler::impImportBlock(BasicBlock* block) addStmt = impExtractLastStmt(); assert(addStmt->GetRootNode()->OperIs(GT_SWITCH)); - for (BasicBlock* const tgtBlock : block->SwitchTargets()) + for (BasicBlock* const tgtBlock : block->SwitchSuccs()) { multRef |= tgtBlock->bbRefs; @@ -12758,19 +12754,13 @@ void Compiler::impFixPredLists() } } - BBehfDesc* jumpEhf = new (this, CMK_BasicBlock) BBehfDesc; + BBJumpTable* jumpEhf; - // It's possible for the `finally` to have no CALLFINALLY predecessors if the `try` block - // has an unconditional `throw` (the finally will still be invoked in the exceptional - // case via the runtime). In that case, jumpEhf->bbeCount remains the default, zero, - // and jumpEhf->bbeSuccs remains the default, nullptr. if (predCount > 0) { - jumpEhf->bbeCount = predCount; - jumpEhf->bbeSuccs = new (this, CMK_FlowEdge) FlowEdge*[predCount]; - - unsigned predNum = 0; - weight_t remainingLikelihood = 1.0; + FlowEdge** const succTab = new (this, CMK_FlowEdge) FlowEdge*[predCount]; + unsigned predNum = 0; + weight_t remainingLikelihood = 1.0; for (BasicBlock* const predBlock : finallyBegBlock->PredBlocks()) { // We only care about preds that are callfinallies. @@ -12799,8 +12789,7 @@ void Compiler::impFixPredLists() newEdge->setLikelihood(1.0 / predCount); } - jumpEhf->bbeSuccs[predNum] = newEdge; - ++predNum; + succTab[predNum++] = newEdge; if (!added) { @@ -12808,7 +12797,17 @@ void Compiler::impFixPredLists() added = true; } } + assert(predNum == predCount); + jumpEhf = new (this, CMK_FlowEdge) BBJumpTable(succTab, predCount); + } + else + { + // It's possible for the `finally` to have no CALLFINALLY predecessors if the `try` block + // has an unconditional `throw` (the finally will still be invoked in the exceptional + // case via the runtime). In that case, jumpEhf->succCount remains the default, zero, + // and jumpEhf->succs remains the default, nullptr. + jumpEhf = new (this, CMK_FlowEdge) BBJumpTable(); } finallyBlock->SetEhfTargets(jumpEhf); diff --git a/src/runtime/src/coreclr/jit/lower.cpp b/src/runtime/src/coreclr/jit/lower.cpp index 838a4a243e7..dbe684b3b39 100644 --- a/src/runtime/src/coreclr/jit/lower.cpp +++ b/src/runtime/src/coreclr/jit/lower.cpp @@ -844,9 +844,11 @@ GenTree* Lowering::LowerSwitch(GenTree* node) // jumpCnt is the number of elements in the jump table array. // jumpTab is the actual pointer to the jump table array. // targetCnt is the number of unique targets in the jump table array. - const unsigned jumpCnt = originalSwitchBB->GetSwitchTargets()->bbsCount; - FlowEdge** const jumpTab = originalSwitchBB->GetSwitchTargets()->bbsDstTab; - const unsigned targetCnt = originalSwitchBB->NumSucc(comp); + // uniqueSuccs is the array of the switch's unique successors. + const unsigned jumpCnt = originalSwitchBB->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const jumpTab = originalSwitchBB->GetSwitchTargets()->GetCases(); + unsigned targetCnt = originalSwitchBB->GetSwitchTargets()->GetSuccCount(); + FlowEdge** const uniqueSuccs = originalSwitchBB->GetSwitchTargets()->GetSuccs(); // GT_SWITCH must be a top-level node with no use. #ifdef DEBUG @@ -868,10 +870,9 @@ GenTree* Lowering::LowerSwitch(GenTree* node) originalSwitchBB->SetKindAndTargetEdge(BBJ_ALWAYS, jumpTab[0]); // Remove extra predecessor links if there was more than one case. - for (unsigned i = 1; i < jumpCnt; ++i) - { - comp->fgRemoveRefPred(jumpTab[i]); - } + const unsigned dupCount = originalSwitchBB->GetTargetEdge()->getDupCount(); + originalSwitchBB->GetTargetEdge()->decrementDupCount(dupCount - 1); + originalSwitchBB->GetTarget()->bbRefs -= (dupCount - 1); // We have to get rid of the GT_SWITCH node but a child might have side effects so just assign // the result of the child subtree to a temp. @@ -953,7 +954,7 @@ GenTree* Lowering::LowerSwitch(GenTree* node) assert(originalSwitchBB->TargetIs(afterDefaultCondBlock)); assert(originalSwitchBB->JumpsToNext()); assert(afterDefaultCondBlock->KindIs(BBJ_SWITCH)); - assert(afterDefaultCondBlock->GetSwitchTargets()->bbsHasDefault); + assert(afterDefaultCondBlock->GetSwitchTargets()->HasDefaultCase()); assert(afterDefaultCondBlock->isEmpty()); // Nothing here yet. // The GT_SWITCH code is still in originalSwitchBB (it will be removed later). @@ -997,36 +998,16 @@ GenTree* Lowering::LowerSwitch(GenTree* node) // If we originally had 2 unique successors, check to see whether there is a unique // non-default case, in which case we can eliminate the switch altogether. // Note that the single unique successor case is handled above. - FlowEdge* uniqueSucc = nullptr; - if (targetCnt == 2) - { - uniqueSucc = jumpTab[0]; - noway_assert(jumpCnt >= 2); - for (unsigned i = 1; i < jumpCnt - 1; i++) - { - if (jumpTab[i] != uniqueSucc) - { - uniqueSucc = nullptr; - break; - } - } - } - if (uniqueSucc != nullptr) + if ((targetCnt == 2) && (defaultEdge->getDupCount() == 0)) { - // If the unique successor immediately follows this block, we have nothing to do - - // it will simply fall-through after we remove the switch, below. - // Otherwise, make this a BBJ_ALWAYS. - // Now, fixup the predecessor links to uniqueSucc's target block. In the original jumpTab: - // jumpTab[i-1] was the default target, which we handled above, - // jumpTab[0] is the first target, and we'll leave that predecessor link. - // Remove any additional predecessor links to uniqueSucc's target block. - for (unsigned i = 1; i < jumpCnt - 1; ++i) - { - assert(jumpTab[i] == uniqueSucc); - comp->fgRemoveRefPred(uniqueSucc); - } - + // The default case was peeled off, and we have only one other unique successor. + // Jump directly to this remaining successor. + FlowEdge* const uniqueSucc = (uniqueSuccs[0] == defaultEdge) ? uniqueSuccs[1] : uniqueSuccs[0]; + assert(uniqueSucc != defaultEdge); afterDefaultCondBlock->SetKindAndTargetEdge(BBJ_ALWAYS, uniqueSucc); + const unsigned dupCount = uniqueSucc->getDupCount(); + uniqueSucc->decrementDupCount(dupCount - 1); + uniqueSucc->getDestinationBlock()->bbRefs -= (dupCount - 1); } // If the number of possible destinations is small enough, we proceed to expand the switch // into a series of conditional branches, otherwise we follow the jump table based switch @@ -1209,9 +1190,9 @@ GenTree* Lowering::LowerSwitch(GenTree* node) if (afterDefaultCondBlock->hasProfileWeight()) { bool profileInconsistent = false; - for (unsigned i = 0; i < jumpCnt - 1; i++) + for (unsigned i = 0; i < targetCnt; i++) { - BasicBlock* const targetBlock = jumpTab[i]->getDestinationBlock(); + BasicBlock* const targetBlock = uniqueSuccs[i]->getDestinationBlock(); targetBlock->setBBProfileWeight(targetBlock->computeIncomingWeight()); profileInconsistent |= (targetBlock->NumSucc() > 0); } @@ -1255,24 +1236,29 @@ GenTree* Lowering::LowerSwitch(GenTree* node) switchBlockRange.InsertAfter(switchValue, switchTable, switchJump); // This block no longer has a default switch case. - // If no other cases branch to this successor, remove it from the switch map entry. + // If no other cases branch to this successor, remove it from the unique successor table. if (defaultEdge->getDupCount() == 0) { - comp->fgRemoveSuccFromSwitchDescMapEntry(afterDefaultCondBlock, defaultEdge); + for (unsigned i = 0; i < targetCnt; i++) + { + FlowEdge* const edge = uniqueSuccs[i]; + if (edge == defaultEdge) + { + afterDefaultCondBlock->GetSwitchTargets()->RemoveSucc(i); + break; + } + } + + assert(targetCnt == (afterDefaultCondBlock->GetSwitchTargets()->GetSuccCount() + 1)); + targetCnt--; } - afterDefaultCondBlock->GetSwitchTargets()->removeDefault(); + afterDefaultCondBlock->GetSwitchTargets()->RemoveDefaultCase(); // We need to scale up the likelihood of the remaining switch edges, now that we've peeled off // the default case. But if the remaining likelihood is zero (default likelihood was 1.0), // we don't know the case likelihoods. Instead, divide likelihood evenly among all cases. // - // First, rebuild the unique succ set - // - Compiler::SwitchUniqueSuccSet successors = comp->GetDescriptorForSwitch(afterDefaultCondBlock); - - // Then fix each successor edge - // if (Compiler::fgProfileWeightsEqual(defaultLikelihood, 1.0, 0.001)) { JITDUMP("Zero weight switch block " FMT_BB ", distributing likelihoods equally per case\n", @@ -1280,9 +1266,9 @@ GenTree* Lowering::LowerSwitch(GenTree* node) // jumpCnt-1 here because we peeled the default after copying this value. weight_t const newLikelihood = 1.0 / (jumpCnt - 1); bool profileInconsistent = false; - for (unsigned i = 0; i < successors.numDistinctSuccs; i++) + for (unsigned i = 0; i < targetCnt; i++) { - FlowEdge* const edge = successors.nonDuplicates[i]; + FlowEdge* const edge = uniqueSuccs[i]; weight_t const oldEdgeWeight = edge->getLikelyWeight(); edge->setLikelihood(newLikelihood * edge->getDupCount()); weight_t const newEdgeWeight = edge->getLikelyWeight(); @@ -1307,9 +1293,9 @@ GenTree* Lowering::LowerSwitch(GenTree* node) weight_t const scaleFactor = 1.0 / (1.0 - defaultLikelihood); JITDUMP("Scaling switch block " FMT_BB " likelihoods by " FMT_WT "\n", afterDefaultCondBlock->bbNum, scaleFactor); - for (unsigned i = 0; i < successors.numDistinctSuccs; i++) + for (unsigned i = 0; i < targetCnt; i++) { - FlowEdge* const edge = successors.nonDuplicates[i]; + FlowEdge* const edge = uniqueSuccs[i]; weight_t newLikelihood = scaleFactor * edge->getLikelihood(); if (newLikelihood > 1.0) @@ -1322,11 +1308,6 @@ GenTree* Lowering::LowerSwitch(GenTree* node) } } } - else - { - // 'afterDefaultCondBlock' is no longer a switch block. Remove its switch map entry. - comp->fgInvalidateSwitchDescMapEntry(afterDefaultCondBlock); - } } GenTree* next = node->gtNext; diff --git a/src/runtime/src/coreclr/jit/lsraarm64.cpp b/src/runtime/src/coreclr/jit/lsraarm64.cpp index 15f658c656e..87d73acd0da 100644 --- a/src/runtime/src/coreclr/jit/lsraarm64.cpp +++ b/src/runtime/src/coreclr/jit/lsraarm64.cpp @@ -2164,9 +2164,18 @@ SingleTypeRegSet LinearScan::getOperandCandidates(GenTreeHWIntrinsic* intrinsicT case NI_Sve_FusedMultiplyAddBySelectedScalar: case NI_Sve_FusedMultiplySubtractBySelectedScalar: case NI_Sve_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndAdd: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndAdd: + case NI_Sve2_MultiplySubtractBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndSubtract: isLowVectorOpNum = (opNum == 3); break; case NI_Sve_MultiplyBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEven: + case NI_Sve2_MultiplyBySelectedScalarWideningOdd: isLowVectorOpNum = (opNum == 2); break; default: @@ -2183,7 +2192,7 @@ SingleTypeRegSet LinearScan::getOperandCandidates(GenTreeHWIntrinsic* intrinsicT } else { - assert(baseElementSize == 4); + assert(baseElementSize <= 4); opCandidates = RBM_SVE_INDEXED_S_ELEMENT_ALLOWED_REGS.GetFloatRegSet(); } } diff --git a/src/runtime/src/coreclr/jit/morph.cpp b/src/runtime/src/coreclr/jit/morph.cpp index e00d9c3c408..e95b098e4ce 100644 --- a/src/runtime/src/coreclr/jit/morph.cpp +++ b/src/runtime/src/coreclr/jit/morph.cpp @@ -12888,8 +12888,8 @@ Compiler::FoldResult Compiler::fgFoldConditional(BasicBlock* block) // Find the actual jump target size_t switchVal = (size_t)cond->AsIntCon()->gtIconVal; - unsigned jumpCnt = block->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTab = block->GetSwitchTargets()->bbsDstTab; + unsigned jumpCnt = block->GetSwitchTargets()->GetCaseCount(); + FlowEdge** jumpTab = block->GetSwitchTargets()->GetCases(); bool foundVal = false; bool profileInconsistent = false; diff --git a/src/runtime/src/coreclr/jit/optimizer.cpp b/src/runtime/src/coreclr/jit/optimizer.cpp index 6399e26d3fc..3cdea868da5 100644 --- a/src/runtime/src/coreclr/jit/optimizer.cpp +++ b/src/runtime/src/coreclr/jit/optimizer.cpp @@ -585,14 +585,12 @@ void Compiler::optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, Blo case BBJ_EHFINALLYRET: { - BBehfDesc* currEhfDesc = blk->GetEhfTargets(); - BBehfDesc* newEhfDesc = new (this, CMK_BasicBlock) BBehfDesc; - newEhfDesc->bbeCount = currEhfDesc->bbeCount; - newEhfDesc->bbeSuccs = new (this, CMK_FlowEdge) FlowEdge*[newEhfDesc->bbeCount]; + BBJumpTable* currEhfDesc = blk->GetEhfTargets(); + FlowEdge** newSuccs = new (this, CMK_FlowEdge) FlowEdge*[currEhfDesc->GetSuccCount()]; - for (unsigned i = 0; i < newEhfDesc->bbeCount; i++) + for (unsigned i = 0; i < currEhfDesc->GetSuccCount(); i++) { - FlowEdge* const inspiringEdge = currEhfDesc->bbeSuccs[i]; + FlowEdge* const inspiringEdge = currEhfDesc->GetSucc(i); BasicBlock* const ehfTarget = inspiringEdge->getDestinationBlock(); FlowEdge* newEdge; @@ -606,9 +604,10 @@ void Compiler::optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, Blo newEdge = fgAddRefPred(ehfTarget, newBlk, inspiringEdge); } - newEhfDesc->bbeSuccs[i] = newEdge; + newSuccs[i] = newEdge; } + BBJumpTable* newEhfDesc = new (this, CMK_BasicBlock) BBJumpTable(newSuccs, currEhfDesc->GetSuccCount()); newBlk->SetEhf(newEhfDesc); break; } @@ -616,12 +615,12 @@ void Compiler::optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, Blo case BBJ_SWITCH: { BBswtDesc* currSwtDesc = blk->GetSwitchTargets(); - BBswtDesc* newSwtDesc = new (this, CMK_BasicBlock) BBswtDesc(currSwtDesc); - newSwtDesc->bbsDstTab = new (this, CMK_FlowEdge) FlowEdge*[newSwtDesc->bbsCount]; + BBswtDesc* newSwtDesc = new (this, CMK_BasicBlock) BBswtDesc(this, currSwtDesc); + FlowEdge** succPtr = newSwtDesc->GetSuccs(); - for (unsigned i = 0; i < newSwtDesc->bbsCount; i++) + for (unsigned i = 0; i < newSwtDesc->GetCaseCount(); i++) { - FlowEdge* const inspiringEdge = currSwtDesc->bbsDstTab[i]; + FlowEdge* const inspiringEdge = currSwtDesc->GetCase(i); BasicBlock* const switchTarget = inspiringEdge->getDestinationBlock(); FlowEdge* newEdge; @@ -637,13 +636,16 @@ void Compiler::optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, Blo // Transfer likelihood... instead of doing this gradually // for dup'd edges, we set it once, when we add the last dup. + // Also, add the new edge to the unique successor table. // if (newEdge->getDupCount() == inspiringEdge->getDupCount()) { newEdge->setLikelihood(inspiringEdge->getLikelihood()); + *succPtr = newEdge; + succPtr++; } - newSwtDesc->bbsDstTab[i] = newEdge; + newSwtDesc->GetCases()[i] = newEdge; } newBlk->SetSwitch(newSwtDesc); diff --git a/src/runtime/src/coreclr/jit/rationalize.cpp b/src/runtime/src/coreclr/jit/rationalize.cpp index 3f1b55136d0..fd1c2a774aa 100644 --- a/src/runtime/src/coreclr/jit/rationalize.cpp +++ b/src/runtime/src/coreclr/jit/rationalize.cpp @@ -418,6 +418,20 @@ void Rationalizer::RewriteHWIntrinsicAsUserCall(GenTree** use, ArrayStackcompOpportunisticallyDependsOn(InstructionSet_SSE42)) + { + // We want to keep this as is, because we'll rewrite it in post-order + return; + } + break; + } +#endif // TARGET_XARCH + default: { if (sigInfo.numArgs == 0) @@ -612,6 +626,17 @@ void Rationalizer::RewriteHWIntrinsic(GenTree** use, Compiler::GenTreeStack& par } #endif // TARGET_XARCH +#if defined(TARGET_ARM64) + case NI_Vector64_ExtractMostSignificantBits: +#elif defined(TARGET_XARCH) + case NI_Vector256_ExtractMostSignificantBits: +#endif + case NI_Vector128_ExtractMostSignificantBits: + { + RewriteHWIntrinsicExtractMsb(use, parents); + break; + } + default: { break; @@ -1305,6 +1330,316 @@ bool Rationalizer::ShouldRewriteToNonMaskHWIntrinsic(GenTree* node) return false; } #endif // TARGET_XARCH + +//---------------------------------------------------------------------------------------------- +// RewriteHWIntrinsicExtractMsb: Rewrites a hwintrinsic ExtractMostSignificantBytes operation +// +// Arguments: +// use - A pointer to the hwintrinsic node +// parents - A reference to tree walk data providing the context +// +void Rationalizer::RewriteHWIntrinsicExtractMsb(GenTree** use, Compiler::GenTreeStack& parents) +{ + GenTreeHWIntrinsic* node = (*use)->AsHWIntrinsic(); + + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); + CorInfoType simdBaseJitType = node->GetSimdBaseJitType(); + var_types simdBaseType = node->GetSimdBaseType(); + unsigned simdSize = node->GetSimdSize(); + var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + + GenTree* op1 = node->Op(1); + +#if defined(TARGET_ARM64) + // ARM64 doesn't have a single instruction that performs the behavior so we'll emulate it instead. + // To do this, we effectively perform the following steps: + // 1. tmp = input & 0x80 ; and the input to clear all but the most significant bit + // 2. tmp = tmp >> index ; right shift each element by its index + // 3. tmp = sum(tmp) ; sum the elements together + + GenTreeVecCon* vecCon2 = comp->gtNewVconNode(simdType); + GenTreeVecCon* vecCon3 = comp->gtNewVconNode(simdType); + + switch (simdBaseType) + { + case TYP_BYTE: + case TYP_UBYTE: + { + simdBaseType = TYP_UBYTE; + simdBaseJitType = CORINFO_TYPE_UBYTE; + + vecCon2->gtSimdVal.u64[0] = 0x8080808080808080; + vecCon3->gtSimdVal.u64[0] = 0x00FFFEFDFCFBFAF9; + + if (simdSize == 16) + { + vecCon2->gtSimdVal.u64[1] = 0x8080808080808080; + vecCon3->gtSimdVal.u64[1] = 0x00FFFEFDFCFBFAF9; + } + break; + } + + case TYP_SHORT: + case TYP_USHORT: + { + simdBaseType = TYP_USHORT; + simdBaseJitType = CORINFO_TYPE_USHORT; + + vecCon2->gtSimdVal.u64[0] = 0x8000800080008000; + vecCon3->gtSimdVal.u64[0] = 0xFFF4FFF3FFF2FFF1; + + if (simdSize == 16) + { + vecCon2->gtSimdVal.u64[1] = 0x8000800080008000; + vecCon3->gtSimdVal.u64[1] = 0xFFF8FFF7FFF6FFF5; + } + break; + } + + case TYP_INT: + case TYP_UINT: + case TYP_FLOAT: + { + simdBaseType = TYP_INT; + simdBaseJitType = CORINFO_TYPE_INT; + + vecCon2->gtSimdVal.u64[0] = 0x8000000080000000; + vecCon3->gtSimdVal.u64[0] = 0xFFFFFFE2FFFFFFE1; + + if (simdSize == 16) + { + vecCon2->gtSimdVal.u64[1] = 0x8000000080000000; + vecCon3->gtSimdVal.u64[1] = 0xFFFFFFE4FFFFFFE3; + } + break; + } + + case TYP_LONG: + case TYP_ULONG: + case TYP_DOUBLE: + { + simdBaseType = TYP_LONG; + simdBaseJitType = CORINFO_TYPE_LONG; + + vecCon2->gtSimdVal.u64[0] = 0x8000000000000000; + vecCon3->gtSimdVal.u64[0] = 0xFFFFFFFFFFFFFFC1; + + if (simdSize == 16) + { + vecCon2->gtSimdVal.u64[1] = 0x8000000000000000; + vecCon3->gtSimdVal.u64[1] = 0xFFFFFFFFFFFFFFC2; + } + break; + } + + default: + { + unreached(); + } + } + + BlockRange().InsertAfter(op1, vecCon2); + GenTree* tmp = comp->gtNewSimdBinOpNode(GT_AND, simdType, op1, vecCon2, simdBaseJitType, simdSize); + BlockRange().InsertAfter(vecCon2, tmp); + op1 = tmp; + + if ((simdSize == 8) && varTypeIsLong(simdBaseType)) + { + intrinsic = NI_AdvSimd_ShiftLogicalScalar; + } + else + { + intrinsic = NI_AdvSimd_ShiftLogical; + } + + BlockRange().InsertAfter(op1, vecCon3); + tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, vecCon3, intrinsic, simdBaseJitType, simdSize); + BlockRange().InsertAfter(vecCon3, tmp); + op1 = tmp; + + if (varTypeIsByte(simdBaseType) && (simdSize == 16)) + { + // For byte/sbyte, we also need to handle the fact that we can only shift by up to 8 + // but for Vector128, we have 16 elements to handle. In that scenario, we will widen + // to ushort and combine the lower/upper halves. + + LIR::Use op1Use; + LIR::Use::MakeDummyUse(BlockRange(), op1, &op1Use); + + op1Use.ReplaceWithLclVar(comp); + op1 = op1Use.Def(); + + GenTree* op2 = comp->gtClone(op1); + BlockRange().InsertAfter(op1, op2); + + tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, NI_AdvSimd_ZeroExtendWideningUpper, simdBaseJitType, 16); + BlockRange().InsertBefore(op2, tmp); + op1 = tmp; + + GenTree* icon = comp->gtNewIconNode(8); + BlockRange().InsertBefore(op2, icon); + + tmp = comp->gtNewSimdBinOpNode(GT_LSH, simdType, op1, icon, CORINFO_TYPE_USHORT, simdSize); + BlockRange().InsertBefore(op2, tmp); + op1 = tmp; + + tmp = comp->gtNewSimdGetLowerNode(TYP_SIMD8, op2, simdBaseJitType, 16); + BlockRange().InsertAfter(op2, tmp); + op2 = tmp; + + tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, op2, NI_AdvSimd_AddWideningLower, simdBaseJitType, 8); + BlockRange().InsertAfter(op2, tmp); + op1 = tmp; + + simdBaseType = TYP_USHORT; + simdBaseJitType = CORINFO_TYPE_USHORT; + } + + // Sum the elements + + if (!varTypeIsLong(simdBaseType)) + { + if ((simdSize == 8) && ((simdBaseType == TYP_INT) || (simdBaseType == TYP_UINT))) + { + LIR::Use op1Use; + LIR::Use::MakeDummyUse(BlockRange(), op1, &op1Use); + + op1Use.ReplaceWithLclVar(comp); + op1 = op1Use.Def(); + + GenTree* op2 = comp->gtClone(op1); + BlockRange().InsertAfter(op1, op2); + + tmp = + comp->gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, op2, NI_AdvSimd_AddPairwise, simdBaseJitType, simdSize); + BlockRange().InsertAfter(op2, tmp); + op1 = tmp; + } + else + { + tmp = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, simdSize); + BlockRange().InsertAfter(op1, tmp); + op1 = tmp; + } + } + else if (simdSize == 16) + { + tmp = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddPairwiseScalar, simdBaseJitType, + simdSize); + BlockRange().InsertAfter(op1, tmp); + op1 = tmp; + } + + if (simdSize == 8) + { + intrinsic = NI_Vector64_ToScalar; + } + else + { + intrinsic = NI_Vector128_ToScalar; + } + + node->gtType = genActualType(simdBaseType); + node->ChangeHWIntrinsicId(intrinsic); + node->SetSimdSize(8); + node->SetSimdBaseJitType(simdBaseJitType); + node->Op(1) = op1; + + if ((simdBaseType != TYP_INT) && (simdBaseType != TYP_UINT)) + { + GenTree* castNode = comp->gtNewCastNode(TYP_INT, node, /* isUnsigned */ true, TYP_INT); + BlockRange().InsertAfter(node, castNode); + + if (parents.Height() > 1) + { + parents.Top(1)->ReplaceOperand(use, castNode); + } + else + { + *use = castNode; + } + + // Adjust the parent stack + assert(parents.Top() == node); + (void)parents.Pop(); + parents.Push(castNode); + } +#elif defined(TARGET_XARCH) + NamedIntrinsic moveMaskIntrinsic = NI_Illegal; + NamedIntrinsic shuffleIntrinsic = NI_Illegal; + + simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UBYTE : CORINFO_TYPE_BYTE; + + // We want to tightly pack the most significant byte of each short/ushort + // and then zero the tightly packed least significant bytes + // + // The most significant bit being set means zero the value + + simd_t simdVal = {}; + + simdVal.u64[0] = 0x0F0D0B0907050301; + simdVal.u64[1] = 0x8080808080808080; + + if (simdSize == 32) + { + // Vector256 works on 2x128-bit lanes, so repeat the same indices for the upper lane + + simdVal.u64[2] = 0x0F0D0B0907050301; + simdVal.u64[3] = 0x8080808080808080; + + shuffleIntrinsic = NI_AVX2_Shuffle; + moveMaskIntrinsic = NI_X86Base_MoveMask; + } + else + { + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE42)); + + shuffleIntrinsic = NI_SSE42_Shuffle; + moveMaskIntrinsic = NI_X86Base_MoveMask; + } + + GenTree* op2 = comp->gtNewVconNode(simdType); + memcpy(&op2->AsVecCon()->gtSimdVal, &simdVal, simdSize); + BlockRange().InsertAfter(op1, op2); + + GenTree* tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, op2, shuffleIntrinsic, simdBaseJitType, simdSize); + BlockRange().InsertAfter(op2, tmp); + op1 = tmp; + + if (simdSize == 32) + { + CorInfoType simdOtherJitType; + + // Since Vector256 is 2x128-bit lanes we need a full width permutation so we get the lower + // 64-bits of each lane next to eachother. The upper bits should be zero, but also don't + // matter so we can also then simplify down to a 128-bit move mask. + + simdOtherJitType = (simdBaseType == TYP_UBYTE) ? CORINFO_TYPE_ULONG : CORINFO_TYPE_LONG; + + GenTree* icon = comp->gtNewIconNode(0xD8); + BlockRange().InsertAfter(op1, icon); + + tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, icon, NI_AVX2_Permute4x64, simdOtherJitType, simdSize); + BlockRange().InsertAfter(icon, tmp); + op1 = tmp; + + simdType = TYP_SIMD16; + + tmp = comp->gtNewSimdGetLowerNode(simdType, op1, simdBaseJitType, simdSize); + BlockRange().InsertAfter(op1, tmp); + op1 = tmp; + + simdSize = 16; + } + + node->ChangeHWIntrinsicId(moveMaskIntrinsic); + node->SetSimdSize(simdSize); + node->SetSimdBaseJitType(simdBaseJitType); + node->Op(1) = op1; +#else + unreached(); +#endif +} #endif // FEATURE_HW_INTRINSICS #ifdef TARGET_ARM64 diff --git a/src/runtime/src/coreclr/jit/rationalize.h b/src/runtime/src/coreclr/jit/rationalize.h index b09bb04da5f..a4d18f25f70 100644 --- a/src/runtime/src/coreclr/jit/rationalize.h +++ b/src/runtime/src/coreclr/jit/rationalize.h @@ -63,6 +63,8 @@ class Rationalizer final : public Phase bool ShouldRewriteToNonMaskHWIntrinsic(GenTree* node); #endif // TARGET_XARCH + + void RewriteHWIntrinsicExtractMsb(GenTree** use, Compiler::GenTreeStack& parents); #endif // FEATURE_HW_INTRINSICS #ifdef TARGET_ARM64 diff --git a/src/runtime/src/coreclr/jit/simd.h b/src/runtime/src/coreclr/jit/simd.h index 36164f01761..6f7b191451b 100644 --- a/src/runtime/src/coreclr/jit/simd.h +++ b/src/runtime/src/coreclr/jit/simd.h @@ -56,7 +56,7 @@ struct simd8_t { simd8_t result; - result.u64[0] = 0xFFFFFFFFFFFFFFFF; + result.u64[0] = UINT64_MAX; return result; } @@ -113,9 +113,9 @@ struct simd12_t { simd12_t result; - result.u32[0] = 0xFFFFFFFF; - result.u32[1] = 0xFFFFFFFF; - result.u32[2] = 0xFFFFFFFF; + result.u32[0] = UINT32_MAX; + result.u32[1] = UINT32_MAX; + result.u32[2] = UINT32_MAX; return result; } @@ -322,7 +322,7 @@ struct simdmask_t bool operator==(const simdmask_t& other) const { - return (u64[0] == other.u64[0]); + return GetRawBits() == other.GetRawBits(); } bool operator!=(const simdmask_t& other) const @@ -330,19 +330,25 @@ struct simdmask_t return !(*this == other); } - static simdmask_t AllBitsSet(unsigned elementCount) + static uint64_t GetBitMask(uint32_t elementCount) { assert((elementCount >= 1) && (elementCount <= 64)); - simdmask_t result; if (elementCount == 64) { - result.u64[0] = 0xFFFFFFFFFFFFFFFF; + return UINT64_MAX; } else { - result.u64[0] = (1ULL << elementCount) - 1; + return (1ULL << elementCount) - 1; } + } + + static simdmask_t AllBitsSet(uint32_t elementCount) + { + simdmask_t result; + + result.u64[0] = GetBitMask(elementCount); return result; } @@ -357,6 +363,13 @@ struct simdmask_t return *this == Zero(); } + uint64_t GetRawBits() const + { + uint64_t value; + memcpy(&value, &u64[0], sizeof(uint64_t)); + return value; + } + static simdmask_t Zero() { return {}; @@ -469,7 +482,7 @@ void EvaluateUnaryMask(genTreeOps oper, bool scalar, unsigned simdSize, simdmask } assert((count == 8) || (count == 16) || (count == 32) || (count == 64)); - uint64_t bitMask = static_cast((static_cast(1) << count) - 1); + uint64_t bitMask = simdmask_t::GetBitMask(count); #elif defined(TARGET_ARM64) // For Arm64 we have count total bits to write, but they are sizeof(TBase) bits apart uint64_t bitMask; @@ -509,8 +522,7 @@ void EvaluateUnaryMask(genTreeOps oper, bool scalar, unsigned simdSize, simdmask #error Unsupported platform #endif - uint64_t arg0Value; - memcpy(&arg0Value, &arg0.u64[0], sizeof(simdmask_t)); + uint64_t arg0Value = arg0.GetRawBits(); // We're only considering these bits arg0Value &= bitMask; @@ -582,6 +594,68 @@ inline void EvaluateUnaryMask( } } } + +template +inline void EvaluateExtractMSB(simdmask_t* result, const TSimd& arg0) +{ + uint64_t resultValue = 0; + uint32_t count = sizeof(TSimd) / sizeof(TBase); + + for (uint32_t i = 0; i < count; i++) + { + TBase input0; + memcpy(&input0, &arg0.u8[i * sizeof(TBase)], sizeof(TBase)); + + if (input0 < 0) + { + resultValue |= (static_cast(1) << i); + } + } + + memcpy(&result->u64[0], &resultValue, sizeof(uint64_t)); +} + +template +inline void EvaluateExtractMSB(var_types baseType, simdmask_t* result, const TSimd& arg0) +{ + switch (baseType) + { + case TYP_BYTE: + case TYP_UBYTE: + { + EvaluateExtractMSB(result, arg0); + break; + } + + case TYP_SHORT: + case TYP_USHORT: + { + EvaluateExtractMSB(result, arg0); + break; + } + + case TYP_INT: + case TYP_UINT: + case TYP_FLOAT: + { + EvaluateExtractMSB(result, arg0); + break; + } + + case TYP_LONG: + case TYP_ULONG: + case TYP_DOUBLE: + { + EvaluateExtractMSB(result, arg0); + break; + } + + default: + { + unreached(); + } + } +} #endif // FEATURE_MASKED_HW_INTRINSICS template @@ -1059,7 +1133,7 @@ void EvaluateBinaryMask( } assert((count == 8) || (count == 16) || (count == 32) || (count == 64)); - uint64_t bitMask = static_cast((static_cast(1) << count) - 1); + uint64_t bitMask = simdmask_t::GetBitMask(count); #elif defined(TARGET_ARM64) // For Arm64 we have count total bits to write, but they are sizeof(TBase) bits apart uint64_t bitMask; @@ -1099,11 +1173,8 @@ void EvaluateBinaryMask( #error Unsupported platform #endif - uint64_t arg0Value; - memcpy(&arg0Value, &arg0.u64[0], sizeof(simdmask_t)); - - uint64_t arg1Value; - memcpy(&arg1Value, &arg1.u64[0], sizeof(simdmask_t)); + uint64_t arg0Value = arg0.GetRawBits(); + uint64_t arg1Value = arg1.GetRawBits(); // We're only considering these bits arg0Value &= bitMask; diff --git a/src/runtime/src/coreclr/jit/switchrecognition.cpp b/src/runtime/src/coreclr/jit/switchrecognition.cpp index 6818a6b15b8..163171cc69b 100644 --- a/src/runtime/src/coreclr/jit/switchrecognition.cpp +++ b/src/runtime/src/coreclr/jit/switchrecognition.cpp @@ -42,12 +42,12 @@ PhaseStatus Compiler::optRecognizeAndOptimizeSwitchJumps() modified = true; // Converted switches won't have dominant cases, so we can skip the switch peeling check. - assert(!block->GetSwitchTargets()->bbsHasDominantCase); + assert(!block->GetSwitchTargets()->HasDominantCase()); } else #endif - if (block->KindIs(BBJ_SWITCH) && block->GetSwitchTargets()->bbsHasDominantCase) + if (block->KindIs(BBJ_SWITCH) && block->GetSwitchTargets()->HasDominantCase()) { fgPeelSwitch(block); modified = true; @@ -377,7 +377,12 @@ bool Compiler::optSwitchConvert( FlowEdge* const falseEdge = firstBlock->GetFalseEdge(); // Convert firstBlock to a switch block - firstBlock->SetSwitch(new (this, CMK_BasicBlock) BBswtDesc); + const unsigned jumpCount = static_cast(maxValue - minValue + 1); + assert((jumpCount > 0) && (jumpCount <= SWITCH_MAX_DISTANCE + 1)); + FlowEdge** const jmpTab = + new (this, CMK_FlowEdge) FlowEdge*[2 + jumpCount + 1 /* true/false edges | cases | default case */]; + + firstBlock->SetSwitch(new (this, CMK_BasicBlock) BBswtDesc(jmpTab, 2, jmpTab + 2, jumpCount + 1, true)); firstBlock->bbCodeOffsEnd = lastBlock->bbCodeOffsEnd; firstBlock->lastStmt()->GetRootNode()->ChangeOper(GT_SWITCH); @@ -406,14 +411,7 @@ bool Compiler::optSwitchConvert( blockToRemove = nextBlockToRemove; } - const unsigned jumpCount = static_cast(maxValue - minValue + 1); - assert((jumpCount > 0) && (jumpCount <= SWITCH_MAX_DISTANCE + 1)); - FlowEdge** jmpTab = new (this, CMK_FlowEdge) FlowEdge*[jumpCount + 1 /*default case*/]; - - fgHasSwitch = true; - firstBlock->GetSwitchTargets()->bbsCount = jumpCount + 1; - firstBlock->GetSwitchTargets()->bbsHasDefault = true; - firstBlock->GetSwitchTargets()->bbsDstTab = jmpTab; + fgHasSwitch = true; // Splitting doesn't work well with jump-tables currently opts.compProcedureSplitting = false; @@ -430,7 +428,8 @@ bool Compiler::optSwitchConvert( // Unlink blockIfTrue from firstBlock, we're going to link it again in the loop below. fgRemoveRefPred(trueEdge); - FlowEdge* switchTrueEdge = nullptr; + FlowEdge* switchTrueEdge = nullptr; + FlowEdge** const cases = jmpTab + 2; for (unsigned i = 0; i < jumpCount; i++) { @@ -438,7 +437,7 @@ bool Compiler::optSwitchConvert( const bool isTrue = (bitVector & static_cast(1ULL << i)) != 0; FlowEdge* const newEdge = fgAddRefPred((isTrue ? blockIfTrue : blockIfFalse), firstBlock); - jmpTab[i] = newEdge; + cases[i] = newEdge; if ((switchTrueEdge == nullptr) && isTrue) { @@ -450,11 +449,15 @@ bool Compiler::optSwitchConvert( // Link the 'default' case FlowEdge* const switchDefaultEdge = fgAddRefPred(blockIfFalse, firstBlock); - jmpTab[jumpCount] = switchDefaultEdge; + cases[jumpCount] = switchDefaultEdge; // Fix likelihoods switchDefaultEdge->setLikelihood(falseLikelihood); switchTrueEdge->setLikelihood(1.0 - falseLikelihood); + // Initialize unique successor table + firstBlock->GetSwitchTargets()->GetSuccs()[0] = cases[0]; + firstBlock->GetSwitchTargets()->GetSuccs()[1] = (cases[0] == switchTrueEdge) ? switchDefaultEdge : switchTrueEdge; + return true; } diff --git a/src/runtime/src/coreclr/jit/valuenum.cpp b/src/runtime/src/coreclr/jit/valuenum.cpp index 6cc89a08a81..9bbbfccf208 100644 --- a/src/runtime/src/coreclr/jit/valuenum.cpp +++ b/src/runtime/src/coreclr/jit/valuenum.cpp @@ -7907,6 +7907,79 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunUnary(GenTreeHWIntrinsic* tree, switch (ni) { +#if defined(TARGET_ARM64) + case NI_Vector64_ExtractMostSignificantBits: +#elif defined(TARGET_XARCH) + case NI_Vector256_ExtractMostSignificantBits: + case NI_X86Base_MoveMask: + case NI_AVX_MoveMask: + case NI_AVX2_MoveMask: +#endif + case NI_Vector128_ExtractMostSignificantBits: + { + simdmask_t simdMaskVal; + + switch (simdSize) + { + case 8: + { + simd8_t arg0 = GetConstantSimd8(arg0VN); + EvaluateExtractMSB(baseType, &simdMaskVal, arg0); + break; + } + + case 16: + { + simd16_t arg0 = GetConstantSimd16(arg0VN); + EvaluateExtractMSB(baseType, &simdMaskVal, arg0); + break; + } + +#if defined(TARGET_XARCH) + case 32: + { + simd32_t arg0 = GetConstantSimd32(arg0VN); + EvaluateExtractMSB(baseType, &simdMaskVal, arg0); + break; + } +#endif // TARGET_XARCH + + default: + { + unreached(); + } + } + + uint32_t elemCount = simdSize / genTypeSize(baseType); + uint64_t mask = simdMaskVal.GetRawBits() & simdmask_t::GetBitMask(elemCount); + + assert(varTypeIsInt(type)); + assert(elemCount <= 32); + + return VNForIntCon(static_cast(mask)); + } + +#ifdef TARGET_XARCH + case NI_AVX512_MoveMask: + { + simdmask_t arg0 = GetConstantSimdMask(arg0VN); + + uint32_t elemCount = simdSize / genTypeSize(baseType); + uint64_t mask = arg0.GetRawBits() & simdmask_t::GetBitMask(elemCount); + + if (varTypeIsInt(type)) + { + assert(elemCount <= 32); + return VNForIntCon(static_cast(mask)); + } + else + { + assert(varTypeIsLong(type)); + return VNForLongCon(static_cast(mask)); + } + } +#endif // TARGET_XARCH + #ifdef TARGET_ARM64 case NI_ArmBase_LeadingZeroCount: #else diff --git a/src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 4e5b53a938b..b655d3879ac 100644 --- a/src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -141,8 +141,8 @@ The .NET Foundation licenses this file to you under the MIT license. - - + + diff --git a/src/runtime/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/runtime/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 6be49af5d42..dd427561f98 100644 --- a/src/runtime/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/runtime/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1958,21 +1958,6 @@ private static void _getFunctionFixedEntryPoint(IntPtr thisHandle, IntPtr* ppExc } } - [UnmanagedCallersOnly] - private static void* _getMethodSync(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodSync(ftn, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] private static CorInfoHelpFunc _getLazyStringLiteralHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* handle) { @@ -2651,7 +2636,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 179); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 178); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_notifyMethodInfoUsage; @@ -2785,53 +2770,52 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[129] = (delegate* unmanaged)&_getHelperFtn; callbacks[130] = (delegate* unmanaged)&_getFunctionEntryPoint; callbacks[131] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[132] = (delegate* unmanaged)&_getMethodSync; - callbacks[133] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[134] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[135] = (delegate* unmanaged)&_embedClassHandle; - callbacks[136] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[137] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[138] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[139] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[140] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[141] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[142] = (delegate* unmanaged)&_GetCookieForInterpreterCalliSig; - callbacks[143] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[144] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[145] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[146] = (delegate* unmanaged)&_getCallInfo; - callbacks[147] = (delegate* unmanaged)&_getStaticFieldContent; - callbacks[148] = (delegate* unmanaged)&_getObjectContent; - callbacks[149] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[150] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[151] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[152] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[153] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[154] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[155] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[156] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[157] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[158] = (delegate* unmanaged)&_getAsyncResumptionStub; - callbacks[159] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[160] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[161] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[162] = (delegate* unmanaged)&_allocMem; - callbacks[163] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[164] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[165] = (delegate* unmanaged)&_allocGCInfo; - callbacks[166] = (delegate* unmanaged)&_setEHcount; - callbacks[167] = (delegate* unmanaged)&_setEHinfo; - callbacks[168] = (delegate* unmanaged)&_logMsg; - callbacks[169] = (delegate* unmanaged)&_doAssert; - callbacks[170] = (delegate* unmanaged)&_reportFatalError; - callbacks[171] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[172] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[173] = (delegate* unmanaged)&_recordCallSite; - callbacks[174] = (delegate* unmanaged)&_recordRelocation; - callbacks[175] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[176] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[177] = (delegate* unmanaged)&_getJitFlags; - callbacks[178] = (delegate* unmanaged)&_getSpecialCopyHelper; + callbacks[132] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[133] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[134] = (delegate* unmanaged)&_embedClassHandle; + callbacks[135] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[136] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[137] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[138] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[139] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[140] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[141] = (delegate* unmanaged)&_GetCookieForInterpreterCalliSig; + callbacks[142] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[143] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[144] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[145] = (delegate* unmanaged)&_getCallInfo; + callbacks[146] = (delegate* unmanaged)&_getStaticFieldContent; + callbacks[147] = (delegate* unmanaged)&_getObjectContent; + callbacks[148] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[149] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[150] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[151] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[152] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[153] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[154] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[155] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[156] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[157] = (delegate* unmanaged)&_getAsyncResumptionStub; + callbacks[158] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[159] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[160] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[161] = (delegate* unmanaged)&_allocMem; + callbacks[162] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[163] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[164] = (delegate* unmanaged)&_allocGCInfo; + callbacks[165] = (delegate* unmanaged)&_setEHcount; + callbacks[166] = (delegate* unmanaged)&_setEHinfo; + callbacks[167] = (delegate* unmanaged)&_logMsg; + callbacks[168] = (delegate* unmanaged)&_doAssert; + callbacks[169] = (delegate* unmanaged)&_reportFatalError; + callbacks[170] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[171] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[172] = (delegate* unmanaged)&_recordCallSite; + callbacks[173] = (delegate* unmanaged)&_recordRelocation; + callbacks[174] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[175] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[176] = (delegate* unmanaged)&_getJitFlags; + callbacks[177] = (delegate* unmanaged)&_getSpecialCopyHelper; return (IntPtr)callbacks; } diff --git a/src/runtime/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/runtime/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 7b5f8a7d79f..18f4498a848 100644 --- a/src/runtime/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/runtime/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -298,7 +298,6 @@ FUNCTIONS void getHelperFtn (CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_HANDLE *pMethod); void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, REF_CORINFO_CONST_LOOKUP pResult, CORINFO_ACCESS_FLAGS accessFlags); void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, bool isUnsafeFunctionPointer, REF_CORINFO_CONST_LOOKUP pResult); - void* getMethodSync(CORINFO_METHOD_HANDLE ftn, void **ppIndirection); CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle); CORINFO_MODULE_HANDLE embedModuleHandle(CORINFO_MODULE_HANDLE handle, void **ppIndirection); CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle, void **ppIndirection); diff --git a/src/runtime/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/runtime/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 3e3c1762f18..afa3677e648 100644 --- a/src/runtime/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/runtime/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2954,11 +2954,6 @@ private void getMethodVTableOffset(CORINFO_METHOD_STRUCT_* method, ref uint offs private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_GENERICHANDLE_RESULT pResult) { throw new NotImplementedException("expandRawHandleIntrinsic"); } - private void* getMethodSync(CORINFO_METHOD_STRUCT_* ftn, ref void* ppIndirection) - { - throw new RequiresRuntimeJitException($"{MethodBeingCompiled} -> {nameof(getMethodSync)}"); - } - private byte[] _bbCounts; partial void findKnownBBCountBlock(ref BlockType blockType, void* location, ref int offset) diff --git a/src/runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 90d54ed2bd7..1cd7c8503a1 100644 --- a/src/runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -1894,26 +1894,6 @@ private uint getMethodAttribs(CORINFO_METHOD_STRUCT_* ftn) return getMethodAttribsInternal(HandleToObject(ftn)); } - private void* getMethodSync(CORINFO_METHOD_STRUCT_* ftn, ref void* ppIndirection) - { - MethodDesc method = HandleToObject(ftn); - TypeDesc type = method.OwningType; - ISymbolNode methodSync = _compilation.NecessaryTypeSymbolIfPossible(type); - - void* result = (void*)ObjectToHandle(methodSync); - - if (methodSync.RepresentsIndirectionCell) - { - ppIndirection = result; - return null; - } - else - { - ppIndirection = null; - return result; - } - } - private unsafe HRESULT allocPgoInstrumentationBySchema(CORINFO_METHOD_STRUCT_* ftnHnd, PgoInstrumentationSchema* pSchema, uint countSchemaItems, byte** pInstrumentationData) { throw new NotImplementedException("allocPgoInstrumentationBySchema"); diff --git a/src/runtime/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/runtime/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index f72f9cdeef2..6376292d538 100644 --- a/src/runtime/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/runtime/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -143,7 +143,6 @@ struct JitInterfaceCallbacks void (* getHelperFtn)(void * thisHandle, CorInfoExceptionClass** ppException, CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_HANDLE* pMethod); void (* getFunctionEntryPoint)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult, CORINFO_ACCESS_FLAGS accessFlags); void (* getFunctionFixedEntryPoint)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, bool isUnsafeFunctionPointer, CORINFO_CONST_LOOKUP* pResult); - void* (* getMethodSync)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, void** ppIndirection); CorInfoHelpFunc (* getLazyStringLiteralHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE handle); CORINFO_MODULE_HANDLE (* embedModuleHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE handle, void** ppIndirection); CORINFO_CLASS_HANDLE (* embedClassHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE handle, void** ppIndirection); @@ -1480,16 +1479,6 @@ class JitInterfaceWrapper : public ICorJitInfo if (pException != nullptr) throw pException; } - virtual void* getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) -{ - CorInfoExceptionClass* pException = nullptr; - void* temp = _callbacks->getMethodSync(_thisHandle, &pException, ftn, ppIndirection); - if (pException != nullptr) throw pException; - return temp; -} - virtual CorInfoHelpFunc getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) { diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index b65429f3153..595f376ff73 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -115,7 +115,6 @@ LWM(HaveSameMethodDefinition, DLDL, DWORD) LWM(GetTypeDefinition, DWORDLONG, DWORDLONG) LWM(GetMethodNameFromMetadata, Agnostic_CORINFO_METHODNAME_TOKENin, Agnostic_CORINFO_METHODNAME_TOKENout) LWM(GetMethodSig, DLDL, Agnostic_CORINFO_SIG_INFO) -LWM(GetMethodSync, DWORDLONG, DLDL) LWM(GetMethodVTableOffset, DWORDLONG, DDD) LWM(GetNewArrHelper, DWORDLONG, DWORD) LWM(GetNewHelper, DWORDLONG, DDD) diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index bfdab057de4..152e1299e89 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -2396,7 +2396,7 @@ void MethodContext::recGetHelperFtn(CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP } void MethodContext::dmpGetHelperFtn(DWORD key, Agnostic_GetHelperFtn value) { - printf("GetHelperFtn key ftn-%u nativeEntrypoint {%s}, helperMethod-%016" PRIX64 "", key, + printf("GetHelperFtn key ftn-%u nativeEntrypoint {%s}, helperMethod-%016" PRIX64 "", key, SpmiDumpHelper::DumpAgnostic_CORINFO_CONST_LOOKUP(value.helperLookup).c_str(), value.helperMethod); } @@ -5504,37 +5504,6 @@ void MethodContext::repFindCallSiteSig(CORINFO_MODULE_HANDLE module, *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, FindCallSiteSig, SigInstHandleMap, cr->getOrCreateMemoryTracker()); } -void MethodContext::recGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection, void* result) -{ - if (GetMethodSync == nullptr) - GetMethodSync = new LightWeightMap(); - DLDL value; - if (ppIndirection != nullptr) - value.A = CastPointer(*ppIndirection); - else - value.A = 0; - value.B = CastPointer(result); - - DWORDLONG key = CastHandle(ftn); - GetMethodSync->Add(key, value); - DEBUG_REC(dmpGetMethodSync(key, value)); -} -void MethodContext::dmpGetMethodSync(DWORDLONG key, DLDL value) -{ - printf("GetMethodSync key %016" PRIX64 ", value pp-%016" PRIX64 " res-%016" PRIX64 "", key, value.A, value.B); -} -void* MethodContext::repGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection) -{ - DWORDLONG key = CastHandle(ftn); - DLDL value = LookupByKeyOrMiss(GetMethodSync, key, ": key %016" PRIX64 "", key); - - DEBUG_REP(dmpGetMethodSync(key, value)); - - if (ppIndirection != nullptr) - *ppIndirection = (void*)value.A; - return (void*)value.B; -} - void MethodContext::recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection, CORINFO_VARARGS_HANDLE result) { if (GetVarArgsHandle == nullptr) diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 06c1c1e33bd..d7ce4ed4069 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -460,13 +460,13 @@ class MethodContext void dmpGetUnboxedEntry(DWORDLONG key, DLD value); CORINFO_METHOD_HANDLE repGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg); - void recGetInstantiatedEntry(CORINFO_METHOD_HANDLE ftn, + void recGetInstantiatedEntry(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_HANDLE methodHandle, CORINFO_CLASS_HANDLE classHandle, CORINFO_METHOD_HANDLE result); void dmpGetInstantiatedEntry(DWORDLONG key, const Agnostic_GetInstantiatedEntryResult& value); - CORINFO_METHOD_HANDLE repGetInstantiatedEntry(CORINFO_METHOD_HANDLE ftn, - CORINFO_METHOD_HANDLE* methodHandle, + CORINFO_METHOD_HANDLE repGetInstantiatedEntry(CORINFO_METHOD_HANDLE ftn, + CORINFO_METHOD_HANDLE* methodHandle, CORINFO_CLASS_HANDLE* classHandle); void recGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result); @@ -713,10 +713,6 @@ class MethodContext CORINFO_CONTEXT_HANDLE context, CORINFO_SIG_INFO* sig); - void recGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection, void* result); - void dmpGetMethodSync(DWORDLONG key, DLDL value); - void* repGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection); - void recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection, CORINFO_VARARGS_HANDLE result); void dmpGetVarArgsHandle(const GetVarArgsHandleValue& key, DLDL value); CORINFO_VARARGS_HANDLE repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection); @@ -1068,7 +1064,7 @@ enum mcPackets Packet_GetMethodHash = 73, Packet_GetMethodInfo = 74, Packet_GetMethodSig = 76, - Packet_GetMethodSync = 77, + // Packet_GetMethodSync = 77, Packet_GetMethodVTableOffset = 78, Packet_GetNewArrHelper = 79, Packet_GetNewHelper = 80, diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp index 529d8260b67..3165ac8ab73 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp @@ -94,7 +94,7 @@ MethodContextReader::MethodContextReader( , Offset(offset) , Increment(increment) { - this->mutex = CreateMutexW(NULL, FALSE, nullptr); + minipal_mutex_init(&this->mutex); std::string tocFileName, mchFileName; @@ -140,20 +140,19 @@ MethodContextReader::~MethodContextReader() CloseHandle(this->fileHandle); } - CloseHandle(this->mutex); - + minipal_mutex_destroy(&this->mutex); CleanExcludedMethods(); } bool MethodContextReader::AcquireLock() { - DWORD res = WaitForSingleObject(this->mutex, INFINITE); - return (res == WAIT_OBJECT_0); + minipal_mutex_enter(&this->mutex); + return true; } void MethodContextReader::ReleaseLock() { - ReleaseMutex(this->mutex); + minipal_mutex_leave(&this->mutex); } bool MethodContextReader::atEof() @@ -418,7 +417,7 @@ bool MethodContextReader::hasTOC() bool MethodContextReader::isValid() { - return this->fileHandle != INVALID_HANDLE_VALUE && this->mutex != INVALID_HANDLE_VALUE; + return this->fileHandle != INVALID_HANDLE_VALUE; } // Return a measure of "progress" through the method contexts, as follows: @@ -640,7 +639,7 @@ void MethodContextReader::Reset(const int* newIndexes, int newIndexCount) int64_t pos = 0; BOOL result = SetFilePointerEx(fileHandle, *(PLARGE_INTEGER)&pos, NULL, FILE_BEGIN); assert(result); - + Indexes = newIndexes; IndexCount = newIndexCount; curIndexPos = 0; diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h index df3ca7b3165..f5ef48009b8 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h @@ -10,6 +10,7 @@ #include "methodcontext.h" #include "tocfile.h" +#include struct MethodContextBuffer { @@ -56,7 +57,7 @@ class MethodContextReader int curMCIndex; // The synchronization mutex - HANDLE mutex; + minipal_mutex mutex; bool AcquireLock(); void ReleaseLock(); diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index eab692b4d37..bc2fc013151 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1504,15 +1504,6 @@ void interceptor_ICJI::getFunctionFixedEntryPoint( mc->recGetFunctionFixedEntryPoint(ftn, pResult); } -// get the synchronization handle that is passed to monXstatic function -void* interceptor_ICJI::getMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection) -{ - mc->cr->AddCall("getMethodSync"); - void* temp = original_ICorJitInfo->getMethodSync(ftn, ppIndirection); - mc->recGetMethodSync(ftn, ppIndirection, temp); - return temp; -} - // These entry points must be called if a handle is being embedded in // the code to be passed to a JIT helper function. (as opposed to just // being passed back into the ICorInfo interface.) diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index ffcf2dc7496..615f8c9dca1 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -1069,14 +1069,6 @@ void interceptor_ICJI::getFunctionFixedEntryPoint( original_ICorJitInfo->getFunctionFixedEntryPoint(ftn, isUnsafeFunctionPointer, pResult); } -void* interceptor_ICJI::getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) -{ - mcs->AddCall("getMethodSync"); - return original_ICorJitInfo->getMethodSync(ftn, ppIndirection); -} - CorInfoHelpFunc interceptor_ICJI::getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) { diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index 718959681da..c4caa76a895 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -937,13 +937,6 @@ void interceptor_ICJI::getFunctionFixedEntryPoint( original_ICorJitInfo->getFunctionFixedEntryPoint(ftn, isUnsafeFunctionPointer, pResult); } -void* interceptor_ICJI::getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) -{ - return original_ICorJitInfo->getMethodSync(ftn, ppIndirection); -} - CorInfoHelpFunc interceptor_ICJI::getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) { diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index fafda8ea9fd..c40cd89f854 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -1299,13 +1299,6 @@ void MyICJI::getFunctionFixedEntryPoint( jitInstance->mc->repGetFunctionFixedEntryPoint(ftn, isUnsafeFunctionPointer, pResult); } -// get the synchronization handle that is passed to monXstatic function -void* MyICJI::getMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection) -{ - jitInstance->mc->cr->AddCall("getMethodSync"); - return jitInstance->mc->repGetMethodSync(ftn, ppIndirection); -} - // These entry points must be called if a handle is being embedded in // the code to be passed to a JIT helper function. (as opposed to just // being passed back into the ICorInfo interface.) diff --git a/src/runtime/src/coreclr/utilcode/log.cpp b/src/runtime/src/coreclr/utilcode/log.cpp index e56255f8362..296757812e6 100644 --- a/src/runtime/src/coreclr/utilcode/log.cpp +++ b/src/runtime/src/coreclr/utilcode/log.cpp @@ -33,7 +33,7 @@ static DWORD LogFlags = 0; static CQuickWSTR szLogFileName; static HANDLE LogFileHandle = INVALID_HANDLE_VALUE; -static volatile HANDLE LogFileMutex = 0; +static minipal_mutex* volatile LogFileMutex = nullptr; static DWORD LogFacilityMask = LF_ALL; static DWORD LogFacilityMask2 = 0; static DWORD LogVMLevel = LL_INFO100; @@ -156,11 +156,9 @@ VOID EnterLogLock() // rather hard to care about this, as we LOG all over the place. CONTRACT_VIOLATION(TakesLockViolation); - if(LogFileMutex != 0) + if (LogFileMutex != nullptr) { - DWORD status; - status = WaitForSingleObjectEx(LogFileMutex, INFINITE, FALSE); - _ASSERTE(WAIT_OBJECT_0 == status); + minipal_mutex_enter(LogFileMutex); } } @@ -169,11 +167,9 @@ VOID LeaveLogLock() STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; - if(LogFileMutex != 0) + if (LogFileMutex != nullptr) { - BOOL success; - success = ReleaseMutex(LogFileMutex); - _ASSERTE(success); + minipal_mutex_leave(LogFileMutex); } } @@ -185,11 +181,14 @@ VOID InitializeLogging() if (bLoggingInitialized) return; - HANDLE mutex = CreateMutex(NULL, FALSE, NULL); - _ASSERTE(mutex != 0); - if (InterlockedCompareExchangeT(&LogFileMutex, mutex, 0) != 0) + minipal_mutex* mutex = new minipal_mutex; + bool success = minipal_mutex_init(mutex); + _ASSERTE(success); + + if (InterlockedCompareExchangeT(&LogFileMutex, mutex, nullptr) != nullptr) { - CloseHandle(mutex); + minipal_mutex_destroy(mutex); + delete mutex; } EnterLogLock(); diff --git a/src/runtime/src/coreclr/vm/appdomain.hpp b/src/runtime/src/coreclr/vm/appdomain.hpp index 5e74fd4e7c8..85a87d4ff82 100644 --- a/src/runtime/src/coreclr/vm/appdomain.hpp +++ b/src/runtime/src/coreclr/vm/appdomain.hpp @@ -423,7 +423,6 @@ class LoadLevelLimiter final enum { - ATTACH_ASSEMBLY_LOAD = 0x1, ATTACH_MODULE_LOAD = 0x2, ATTACH_CLASS_LOAD = 0x4, diff --git a/src/runtime/src/coreclr/vm/arm64/asmhelpers.S b/src/runtime/src/coreclr/vm/arm64/asmhelpers.S index b4a87823304..5a00639e6af 100644 --- a/src/runtime/src/coreclr/vm/arm64/asmhelpers.S +++ b/src/runtime/src/coreclr/vm/arm64/asmhelpers.S @@ -695,11 +695,11 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler #endif INLINE_GETTHREAD x20 // thrashes x0 on Apple OSes (and possibly other arg registers on other Unixes) - ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] + ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] cbnz x11, LOCAL_LABEL(HaveInterpThreadContext) #ifdef TARGET_APPLE - // There Thread::GetInterpThreadContext can destroy all argument registers, so we + // There Thread::GetInterpThreadContext can destroy all argument registers, so we // need to save them. For non-Apple, they have been already saved in the PROLOG_WITH_TRANSITION_BLOCK // Restore x0 thrashed by the INLINE_GETTHREAD mov x0, x21 @@ -887,6 +887,30 @@ NESTED_ENTRY InterpreterStubRet4Float, _TEXT, NoHandler EPILOG_RETURN NESTED_END InterpreterStubRet4Float, _TEXT +NESTED_ENTRY InterpreterStubRetVector64, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED fp, lr, -16 + // The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 // the IR bytecode pointer + mov x2, xzr + bl C_FUNC(ExecuteInterpretedMethod) + ldr d0, [x0] + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 + EPILOG_RETURN +NESTED_END InterpreterStubRetVector64, _TEXT + +NESTED_ENTRY InterpreterStubRetVector128, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED fp, lr, -16 + // The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 // the IR bytecode pointer + mov x2, xzr + bl C_FUNC(ExecuteInterpretedMethod) + ldr q0, [x0] + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 + EPILOG_RETURN +NESTED_END InterpreterStubRetVector128, _TEXT + // Copy arguments from the processor stack to the interpreter stack // The CPU stack slots are aligned to pointer size. @@ -1834,4 +1858,42 @@ NESTED_ENTRY CallJittedMethodRet4Float, _TEXT, NoHandler EPILOG_RETURN NESTED_END CallJittedMethodRet4Float, _TEXT +// X0 - routines array +// X1 - interpreter stack args location +// X2 - interpreter stack return value location +// X3 - stack arguments size (properly aligned) +NESTED_ENTRY CallJittedMethodRetVector64, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32 + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str d0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 32 + EPILOG_RETURN +NESTED_END CallJittedMethodRetVector64, _TEXT + +// X0 - routines array +// X1 - interpreter stack args location +// X2 - interpreter stack return value location +// X3 - stack arguments size (properly aligned) +NESTED_ENTRY CallJittedMethodRetVector128, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32 + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str q0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 32 + EPILOG_RETURN +NESTED_END CallJittedMethodRetVector128, _TEXT + #endif // FEATURE_INTERPRETER diff --git a/src/runtime/src/coreclr/vm/arm64/asmhelpers.asm b/src/runtime/src/coreclr/vm/arm64/asmhelpers.asm index 9d2f8ee9555..f5de9e3488c 100644 --- a/src/runtime/src/coreclr/vm/arm64/asmhelpers.asm +++ b/src/runtime/src/coreclr/vm/arm64/asmhelpers.asm @@ -1240,6 +1240,30 @@ HaveInterpThreadContext EPILOG_RETURN NESTED_END InterpreterStubRet4Float + NESTED_ENTRY InterpreterStubRetVector64 + PROLOG_SAVE_REG_PAIR fp, lr, #-16! + ; The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 ; the IR bytecode pointer + mov x2, xzr + bl ExecuteInterpretedMethod + ldr d0, [x0] + EPILOG_RESTORE_REG_PAIR fp, lr, #16! + EPILOG_RETURN + NESTED_END InterpreterStubRetVector64 + + NESTED_ENTRY InterpreterStubRetVector128 + PROLOG_SAVE_REG_PAIR fp, lr, #-16! + ; The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 ; the IR bytecode pointer + mov x2, xzr + bl ExecuteInterpretedMethod + ldr q0, [x0] + EPILOG_RESTORE_REG_PAIR fp, lr, #16! + EPILOG_RETURN + NESTED_END InterpreterStubRetVector128 + ; Routines for passing value type arguments by reference in general purpose registers X0..X7 ; from native code to the interpreter @@ -1259,7 +1283,7 @@ StoreCopyLoop ldr x11, [x10], #8 EPILOG_BRANCH_REG x11 LEAF_END Store_Stack - + LEAF_ENTRY Load_Stack_Ref ldr w11, [x10], #4 ; SP offset ldr w12, [x10], #4 ; size of the value type @@ -2117,6 +2141,44 @@ CopyLoop EPILOG_RETURN NESTED_END CallJittedMethodRet4Float + ; X0 - routines array + ; X1 - interpreter stack args location + ; X2 - interpreter stack return value location + ; X3 - stack arguments size (properly aligned) + NESTED_ENTRY CallJittedMethodRetVector64 + PROLOG_SAVE_REG_PAIR fp, lr, #-32! + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str d0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR fp, lr, #32! + EPILOG_RETURN + NESTED_END CallJittedMethodRetVector64 + + ; X0 - routines array + ; X1 - interpreter stack args location + ; X2 - interpreter stack return value location + ; X3 - stack arguments size (properly aligned) + NESTED_ENTRY CallJittedMethodRetVector128 + PROLOG_SAVE_REG_PAIR fp, lr, #-32! + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str q0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR fp, lr, #32! + EPILOG_RETURN + NESTED_END CallJittedMethodRetVector128 + #endif // FEATURE_INTERPRETER ; Must be at very end of file diff --git a/src/runtime/src/coreclr/vm/assembly.cpp b/src/runtime/src/coreclr/vm/assembly.cpp index 95fd73a73ad..cf6e0834dcb 100644 --- a/src/runtime/src/coreclr/vm/assembly.cpp +++ b/src/runtime/src/coreclr/vm/assembly.cpp @@ -2365,7 +2365,7 @@ void Assembly::DeliverSyncEvents() SetShouldNotifyDebugger(); // Still work to do even if no debugger is attached. - NotifyDebuggerLoad(ATTACH_ASSEMBLY_LOAD, FALSE); + NotifyDebuggerLoad(ATTACH_MODULE_LOAD, FALSE); } #endif // DEBUGGING_SUPPORTED @@ -2488,16 +2488,7 @@ BOOL Assembly::NotifyDebuggerLoad(int flags, BOOL attaching) } // There is still work we need to do even when no debugger is attached. - if (flags & ATTACH_ASSEMBLY_LOAD) - { - if (ShouldNotifyDebugger()) - { - g_pDebugInterface->LoadAssembly(GetDomainAssembly()); - } - result = TRUE; - } - - if(this->ShouldNotifyDebugger()) + if(this->ShouldNotifyDebugger() && !(flags & ATTACH_MODULE_LOAD)) { result = result || this->GetModule()->NotifyDebuggerLoad(GetDomainAssembly(), flags, attaching); diff --git a/src/runtime/src/coreclr/vm/callstubgenerator.cpp b/src/runtime/src/coreclr/vm/callstubgenerator.cpp index bfc3931e0e0..be815aaf7e6 100644 --- a/src/runtime/src/coreclr/vm/callstubgenerator.cpp +++ b/src/runtime/src/coreclr/vm/callstubgenerator.cpp @@ -1090,6 +1090,8 @@ extern "C" void CallJittedMethodRetFloat(PCODE *routines, int8_t*pArgs, int8_t*p extern "C" void CallJittedMethodRet2Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); extern "C" void CallJittedMethodRet3Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); extern "C" void CallJittedMethodRet4Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); +extern "C" void CallJittedMethodRetVector64(PCODE *routines, int8_t *pArgs, int8_t *pRet, int totalStackSize); +extern "C" void CallJittedMethodRetVector128(PCODE *routines, int8_t *pArgs, int8_t *pRet, int totalStackSize); extern "C" void InterpreterStubRet2I8(); extern "C" void InterpreterStubRet2Double(); extern "C" void InterpreterStubRet3Double(); @@ -1098,6 +1100,8 @@ extern "C" void InterpreterStubRetFloat(); extern "C" void InterpreterStubRet2Float(); extern "C" void InterpreterStubRet3Float(); extern "C" void InterpreterStubRet4Float(); +extern "C" void InterpreterStubRetVector64(); +extern "C" void InterpreterStubRetVector128(); #endif // TARGET_ARM64 #if LOG_COMPUTE_CALL_STUB @@ -1154,6 +1158,10 @@ CallStubHeader::InvokeFunctionPtr CallStubGenerator::GetInvokeFunctionPtr(CallSt INVOKE_FUNCTION_PTR(CallJittedMethodRet3Float); case ReturnType4Float: INVOKE_FUNCTION_PTR(CallJittedMethodRet4Float); + case ReturnTypeVector64: + INVOKE_FUNCTION_PTR(CallJittedMethodRetVector64); + case ReturnTypeVector128: + INVOKE_FUNCTION_PTR(CallJittedMethodRetVector128); #endif // TARGET_ARM64 default: _ASSERTE(!"Unexpected return type for interpreter stub"); @@ -1215,6 +1223,10 @@ PCODE CallStubGenerator::GetInterpreterReturnTypeHandler(CallStubGenerator::Retu RETURN_TYPE_HANDLER(InterpreterStubRet3Float); case ReturnType4Float: RETURN_TYPE_HANDLER(InterpreterStubRet4Float); + case ReturnTypeVector64: + RETURN_TYPE_HANDLER(InterpreterStubRetVector64); + case ReturnTypeVector128: + RETURN_TYPE_HANDLER(InterpreterStubRetVector128); #endif // TARGET_ARM64 default: _ASSERTE(!"Unexpected return type for interpreter stub"); @@ -1417,23 +1429,8 @@ void CallStubGenerator::ComputeCallStub(MetaSig &sig, PCODE *pRoutines) #endif // The "this" argument register is not enumerated by the arg iterator, so // we need to "inject" it here. -#if defined(TARGET_WINDOWS) && defined(TARGET_AMD64) - if (argIt.HasRetBuffArg()) - { -#if LOG_COMPUTE_CALL_STUB - printf("argIt.HasRetBuffArg() on WINDOWS AMD64\n"); -#endif - // The return buffer on Windows AMD64 is passed in the first argument register, so the - // "this" argument is be passed in the second argument register. - m_r1 = 1; - m_r2 = 1; - } - else -#endif // TARGET_WINDOWS && TARGET_AMD64 - { - // The "this" pointer is passed in the first argument register. - m_r1 = 0; - } + // CLR ABI specifies that unlike the native Windows x64 calling convention, it is passed in the first argument register. + m_r1 = 0; } if (argIt.HasParamType()) @@ -1724,7 +1721,7 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg } #else return ReturnTypeBuff; -#endif +#endif } else { @@ -1842,8 +1839,30 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg break; } break; +#ifdef FEATURE_SIMD + case CORINFO_HFA_ELEM_VECTOR64: + switch (thReturnValueType.GetSize()) + { + case 8: + return ReturnTypeVector64; + default: + _ASSERTE(!"Unsupported Vector64 HFA size"); + break; + } + break; + case CORINFO_HFA_ELEM_VECTOR128: + switch (thReturnValueType.GetSize()) + { + case 16: + return ReturnTypeVector128; + default: + _ASSERTE(!"Unsupported Vector128 HFA size"); + break; + } + break; +#endif default: - _ASSERTE(!"HFA types other than float and double are not supported yet"); + _ASSERTE(!"HFA type is not supported"); break; } } diff --git a/src/runtime/src/coreclr/vm/callstubgenerator.h b/src/runtime/src/coreclr/vm/callstubgenerator.h index 9f628f6ac08..55ef6911480 100644 --- a/src/runtime/src/coreclr/vm/callstubgenerator.h +++ b/src/runtime/src/coreclr/vm/callstubgenerator.h @@ -83,7 +83,9 @@ class CallStubGenerator ReturnTypeFloat, ReturnType2Float, ReturnType3Float, - ReturnType4Float + ReturnType4Float, + ReturnTypeVector64, + ReturnTypeVector128 #endif // TARGET_ARM64 }; diff --git a/src/runtime/src/coreclr/vm/codeman.h b/src/runtime/src/coreclr/vm/codeman.h index 9720f029e30..1be9d9ce96d 100644 --- a/src/runtime/src/coreclr/vm/codeman.h +++ b/src/runtime/src/coreclr/vm/codeman.h @@ -1980,9 +1980,7 @@ class EECodeGenManager : public IJitManager // must hold critical section to access this structure. CUnorderedArray m_DomainCodeHeaps; CUnorderedArray m_DynamicDomainCodeHeaps; -#ifndef DACCESS_COMPILE CUnorderedArray m_delayUnload; -#endif // !DACCESS_COMPILE protected: Crst m_CodeHeapLock; diff --git a/src/runtime/src/coreclr/vm/dbginterface.h b/src/runtime/src/coreclr/vm/dbginterface.h index 0b2eadf4479..23fec81a347 100644 --- a/src/runtime/src/coreclr/vm/dbginterface.h +++ b/src/runtime/src/coreclr/vm/dbginterface.h @@ -299,14 +299,6 @@ class DebugInterface virtual HRESULT UpdateAppDomainEntryInIPC (AppDomain *pAppDomain) = 0; - // Called when an assembly is being loaded into an AppDomain. - // This includes when a domain neutral assembly is loaded into a new AppDomain. - // This is called only when a debugger is attached, and will occur after the - // related AddAppDomainToIPCBlock call and before any LoadModule or - // LoadClass calls for this assembly. - virtual void LoadAssembly(DomainAssembly * pDomainAssembly) = 0; // the assembly being loaded - - // Called for all assemblies in an AppDomain when the AppDomain is unloaded. // This includes domain neutral assemblies that are also loaded into other domains. // This is called only when a debugger is attached, and will occur after all UnloadClass diff --git a/src/runtime/src/coreclr/vm/interpexec.cpp b/src/runtime/src/coreclr/vm/interpexec.cpp index 927bd812a4a..ea0a3509320 100644 --- a/src/runtime/src/coreclr/vm/interpexec.cpp +++ b/src/runtime/src/coreclr/vm/interpexec.cpp @@ -162,14 +162,23 @@ static OBJECTREF CreateMultiDimArray(MethodTable* arrayClass, int8_t* stack, int #define LOCAL_VAR(offset,type) (*LOCAL_VAR_ADDR(offset, type)) #define NULL_CHECK(o) do { if ((o) == NULL) { COMPlusThrow(kNullReferenceException); } } while (0) -template static THelper GetPossiblyIndirectHelper(void* dataItem) +template static THelper GetPossiblyIndirectHelper(const InterpMethod *pMethod, int32_t _data) { - size_t helperDirectOrIndirect = (size_t)dataItem; - if (helperDirectOrIndirect & INTERP_DIRECT_HELPER_TAG) - // Clear the direct flag and then raise the thumb bit as needed - return (THelper)PINSTRToPCODE((TADDR)(helperDirectOrIndirect & ~INTERP_DIRECT_HELPER_TAG)); - else - return *(THelper *)helperDirectOrIndirect; + InterpHelperData data; + memcpy(&data, &_data, sizeof(int32_t)); + + void *addr = pMethod->pDataItems[data.addressDataItemIndex]; + switch (data.accessType) { + case IAT_VALUE: + return (THelper)addr; + case IAT_PVALUE: + return *(THelper *)addr; + case IAT_PPVALUE: + return **(THelper **)addr; + default: + COMPlusThrowHR(COR_E_EXECUTIONENGINE); + return (THelper)nullptr; + } } // At present our behavior for float to int conversions is to perform a saturating conversion down to either 32 or 64 bits @@ -1695,7 +1704,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_P: { - HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[2]]); + HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[2]); void* helperArg = pMethod->pDataItems[ip[3]]; LOCAL_VAR(ip[1], void*) = helperFtn(helperArg); @@ -1705,7 +1714,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_S: { - HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[2]]); + HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[2]); void* helperArg = LOCAL_VAR(ip[3], void*); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg); @@ -1715,7 +1724,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_PS: { - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); void* helperArg = pMethod->pDataItems[ip[4]]; LOCAL_VAR(ip[1], void*) = helperFtn(helperArg, LOCAL_VAR(ip[2], void*)); @@ -1725,7 +1734,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_SP: { - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); void* helperArg = pMethod->pDataItems[ip[4]]; LOCAL_VAR(ip[1], void*) = helperFtn(LOCAL_VAR(ip[2], void*), helperArg); @@ -1738,7 +1747,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[4]]; void* helperArg = DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg); ip += 5; @@ -1750,7 +1759,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; void* helperArg = DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[4]); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg, LOCAL_VAR(ip[3], void*)); ip += 6; @@ -1762,7 +1771,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; void* helperArg = DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[4]); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg, LOCAL_VAR_ADDR(ip[3], void*)); ip += 6; break; @@ -1770,7 +1779,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_PA: { - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); void* helperArg = pMethod->pDataItems[ip[4]]; LOCAL_VAR(ip[1], void*) = helperFtn(helperArg, LOCAL_VAR_ADDR(ip[2], void*)); ip += 5; @@ -1782,7 +1791,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; void* helperArg = DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_V_PPP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_V_PPP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[4]); helperFtn(LOCAL_VAR_ADDR(ip[1], void*), helperArg, LOCAL_VAR(ip[3], void*)); ip += 6; break; @@ -1790,7 +1799,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_V_APS: { - HELPER_FTN_V_PPP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_V_PPP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); void* helperArg = pMethod->pDataItems[ip[4]]; helperFtn(LOCAL_VAR_ADDR(ip[1], void*), helperArg, LOCAL_VAR(ip[2], void*)); ip += 5; @@ -1986,9 +1995,6 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr int32_t vtSize = ip[4]; void *vtThis = stack + returnOffset; - // clear the valuetype - memset(vtThis, 0, vtSize); - // pass the address of the valuetype LOCAL_VAR(callArgsOffset, void*) = vtThis; @@ -2021,18 +2027,6 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; } - case INTOP_GC_COLLECT: - { - // HACK: blocking gc of all generations to enable early stackwalk testing - // Interpreter-TODO: Remove this - { - pInterpreterFrame->SetTopInterpMethodContextFrame(pFrame); - GCX_COOP(); - GCHeapUtilities::GetGCHeap()->GarbageCollect(-1, false, collection_blocking | collection_aggressive); - } - ip++; - break; - } case INTOP_THROW: { OBJECTREF throwable; @@ -2068,7 +2062,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr int opcode = *ip; int dreg = ip[1]; int sreg = ip[2]; - HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper(pMethod, ip[3]); MethodTable *pMT = (MethodTable*)pMethod->pDataItems[ip[4]]; // private static ref byte Unbox(MethodTable* toTypeHnd, object obj) @@ -2088,7 +2082,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; MethodTable *pMTBoxedObj = (MethodTable*)DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper(pMethod, ip[4]); // private static ref byte Unbox(MethodTable* toTypeHnd, object obj) Object *src = LOCAL_VAR(sreg, Object*); @@ -2105,7 +2099,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr COMPlusThrow(kArgumentOutOfRangeException); MethodTable* arrayClsHnd = (MethodTable*)pMethod->pDataItems[ip[3]]; - HELPER_FTN_NEWARR helper = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_NEWARR helper = GetPossiblyIndirectHelper(pMethod, ip[4]); Object* arr = helper(arrayClsHnd, (intptr_t)length); LOCAL_VAR(ip[1], OBJECTREF) = ObjectToOBJECTREF(arr); @@ -2122,7 +2116,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; MethodTable *arrayClsHnd = (MethodTable*)DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_NEWARR helper = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_NEWARR helper = GetPossiblyIndirectHelper(pMethod, ip[4]); Object* arr = helper(arrayClsHnd, (intptr_t)length); LOCAL_VAR(ip[1], OBJECTREF) = ObjectToOBJECTREF(arr); @@ -2460,11 +2454,8 @@ do \ case INTOP_THROW_PNSE: COMPlusThrow(kPlatformNotSupportedException); break; - case INTOP_FAILFAST: - assert(0); - break; default: - assert(0); + assert(!"Unimplemented or invalid interpreter opcode"); break; } } diff --git a/src/runtime/src/coreclr/vm/jitinterface.cpp b/src/runtime/src/coreclr/vm/jitinterface.cpp index b0e80d386f8..c1bd8aad1fc 100644 --- a/src/runtime/src/coreclr/vm/jitinterface.cpp +++ b/src/runtime/src/coreclr/vm/jitinterface.cpp @@ -12355,41 +12355,6 @@ CORINFO_CLASS_HANDLE CEECodeGenInfo::getStaticFieldCurrentClass(CORINFO_FIELD_HA return result; } -/*********************************************************************/ -static void *GetClassSync(MethodTable *pMT) -{ - STANDARD_VM_CONTRACT; - - GCX_COOP(); - - OBJECTREF ref = pMT->GetManagedClassObject(); - return (void*)ref->GetSyncBlock()->GetMonitor(); -} - -/*********************************************************************/ -void* CEECodeGenInfo::getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, - void **ppIndirection) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - void * result = NULL; - - if (ppIndirection != NULL) - *ppIndirection = NULL; - - JIT_TO_EE_TRANSITION(); - - result = GetClassSync((GetMethod(ftnHnd))->GetMethodTable()); - - EE_TO_JIT_TRANSITION(); - - return result; -} - CORINFO_METHOD_INFO* CEECodeGenInfo::getMethodInfoInternal() { LIMITED_METHOD_CONTRACT; @@ -14850,13 +14815,6 @@ CORINFO_CLASS_HANDLE CEEInfo::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE fi UNREACHABLE(); // only called on derived class. } -void* CEEInfo::getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, - void **ppIndirection) -{ - LIMITED_METHOD_CONTRACT; - UNREACHABLE(); // only called on derived class. -} - HRESULT CEEInfo::allocPgoInstrumentationBySchema( CORINFO_METHOD_HANDLE ftnHnd, /* IN */ PgoInstrumentationSchema* pSchema, /* IN/OUT */ diff --git a/src/runtime/src/coreclr/vm/jitinterface.h b/src/runtime/src/coreclr/vm/jitinterface.h index 00ed950e5d5..e825d94a129 100644 --- a/src/runtime/src/coreclr/vm/jitinterface.h +++ b/src/runtime/src/coreclr/vm/jitinterface.h @@ -574,7 +574,6 @@ class CEECodeGenInfo : public CEEInfo InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue) override; InfoAccessType emptyStringLiteral(void ** ppValue) override; CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool* pIsSpeculative) override; - void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection) override; CORINFO_METHOD_INFO* getMethodInfoInternal(); CORJIT_FLAGS* getJitFlagsInternal(); diff --git a/src/runtime/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs b/src/runtime/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs index 9abf075d60c..d24a7314592 100644 --- a/src/runtime/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs +++ b/src/runtime/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs @@ -16,8 +16,6 @@ internal static partial class Interop { internal static partial class AppleCrypto { - private static readonly IdnMapping s_idnMapping = new IdnMapping(); - // Read data from connection (or an instance delegate captured context) and write it to data // dataLength comes in as the capacity of data, goes out as bytes written. // Note: the true type of dataLength is `size_t*`, but on macOS that's most equal to `void**` @@ -152,13 +150,6 @@ internal static unsafe partial int SslSetIoCallbacks( [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_SslRead")] internal static unsafe partial PAL_TlsIo SslRead(SafeSslHandle sslHandle, byte* writeFrom, int count, out int bytesWritten); - [LibraryImport(Interop.Libraries.AppleCryptoNative)] - private static partial int AppleCryptoNative_SslIsHostnameMatch( - SafeSslHandle handle, - SafeCreateHandle cfHostname, - SafeCFDateHandle cfValidTime, - out int pOSStatus); - [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_SslShutdown")] internal static partial int SslShutdown(SafeSslHandle sslHandle); @@ -462,40 +453,6 @@ internal static unsafe int SslCtxSetAlpnProtocol(SafeSslHandle ctx, SslApplicati protocol.Dispose(); } } - - public static bool SslCheckHostnameMatch(SafeSslHandle handle, string hostName, DateTime notBefore, out int osStatus) - { - int result; - // The IdnMapping converts Unicode input into the IDNA punycode sequence. - // It also does host case normalization. The bypass logic would be something - // like "all characters being within [a-z0-9.-]+" - // - // The SSL Policy (SecPolicyCreateSSL) has been verified as not inherently supporting - // IDNA as of macOS 10.12.1 (Sierra). If it supports low-level IDNA at a later date, - // this code could be removed. - // - // It was verified as supporting case invariant match as of 10.12.1 (Sierra). - string matchName = string.IsNullOrEmpty(hostName) ? string.Empty : s_idnMapping.GetAscii(hostName); - - using (SafeCFDateHandle cfNotBefore = CoreFoundation.CFDateCreate(notBefore)) - using (SafeCreateHandle cfHostname = CoreFoundation.CFStringCreateWithCString(matchName)) - { - result = AppleCryptoNative_SslIsHostnameMatch(handle, cfHostname, cfNotBefore, out osStatus); - } - - switch (result) - { - case 0: - return false; - case 1: - return true; - default: - if (NetEventSource.Log.IsEnabled()) - NetEventSource.Error(null, $"AppleCryptoNative_SslIsHostnameMatch returned '{result}' for '{hostName}'"); - Debug.Fail($"AppleCryptoNative_SslIsHostnameMatch returned {result}"); - throw new SslException(); - } - } } } diff --git a/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs b/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs index 0f69af42cb0..376a133244b 100644 --- a/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs +++ b/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs @@ -111,5 +111,44 @@ internal static unsafe void BCryptSignHashPqcPure( throw Interop.BCrypt.CreateCryptographicException(status); } } + + internal static unsafe void BCryptSignHashPqcPreHash( + SafeBCryptKeyHandle key, + ReadOnlySpan hash, + string hashAlgorithmIdentifier, + ReadOnlySpan context, + Span destination) + { + NTSTATUS status; + int bytesWritten; + + fixed (byte* pHash = &MemoryMarshal.GetReference(hash)) + fixed (byte* pDest = &MemoryMarshal.GetReference(destination)) + fixed (byte* pContext = &MemoryMarshal.GetReference(context)) + fixed (char* pHashAlgorithmIdentifier = hashAlgorithmIdentifier) + { + BCRYPT_PQDSA_PADDING_INFO paddingInfo = default; + paddingInfo.pbCtx = (IntPtr)pContext; + paddingInfo.cbCtx = context.Length; + paddingInfo.pszPreHashAlgId = (IntPtr)pHashAlgorithmIdentifier; + + status = BCryptSignHash( + key, + &paddingInfo, + pHash, + hash.Length, + pDest, + destination.Length, + out bytesWritten, + BCryptSignVerifyFlags.BCRYPT_PAD_PQDSA); + } + + Debug.Assert(bytesWritten == destination.Length); + + if (status != BCrypt.NTSTATUS.STATUS_SUCCESS) + { + throw BCrypt.CreateCryptographicException(status); + } + } } } diff --git a/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs b/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs index 6934e7e2c11..da39ca0dcdd 100644 --- a/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs +++ b/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs @@ -115,5 +115,37 @@ internal static unsafe bool BCryptVerifySignaturePqcPure( return status == NTSTATUS.STATUS_SUCCESS; } + + internal static unsafe bool BCryptVerifySignaturePqcPreHash( + SafeBCryptKeyHandle key, + ReadOnlySpan hash, + string hashAlgorithmIdentifier, + ReadOnlySpan context, + ReadOnlySpan signature) + { + NTSTATUS status; + + fixed (byte* pHash = &MemoryMarshal.GetReference(hash)) + fixed (byte* pSignature = &MemoryMarshal.GetReference(signature)) + fixed (byte* pContext = &MemoryMarshal.GetReference(context)) + fixed (char* pHashAlgorithmIdentifier = hashAlgorithmIdentifier) + { + BCRYPT_PQDSA_PADDING_INFO paddingInfo = default; + paddingInfo.pbCtx = (IntPtr)pContext; + paddingInfo.cbCtx = context.Length; + paddingInfo.pszPreHashAlgId = (IntPtr)pHashAlgorithmIdentifier; + + status = BCryptVerifySignature( + key, + &paddingInfo, + pHash, + hash.Length, + pSignature, + signature.Length, + BCryptSignVerifyFlags.BCRYPT_PAD_PQDSA); + } + + return status == NTSTATUS.STATUS_SUCCESS; + } } } diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs index 12ca0f66a8b..1c9a498a273 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs @@ -325,7 +325,29 @@ public void SignPreHash(ReadOnlySpan hash, Span destination, string SR.Argument_SignatureContextTooLong255); } - Helpers.ValidateHashLength(hash, hashAlgorithmOid); + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + if (hashAlgorithmIdentifier is null) + { + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmOid)); + } + + if (insufficientCollisionResistance) + { + throw new CryptographicException(SR.Format( + SR.Cryptography_HashMLDsaAlgorithmMismatch, + Algorithm.Name, + hashAlgorithmIdentifier)); + } + + if (hashLengthInBytes != hash.Length) + { + throw new CryptographicException(SR.Cryptography_HashLengthMismatch); + } + ThrowIfDisposed(); SignPreHashCore(hash, context, hashAlgorithmOid, destination); @@ -413,14 +435,24 @@ public bool VerifyPreHash(ReadOnlySpan hash, ReadOnlySpan signature, SR.Argument_SignatureContextTooLong255); } - Helpers.ValidateHashLength(hash, hashAlgorithmOid); - ThrowIfDisposed(); + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); - if (signature.Length != Algorithm.SignatureSizeInBytes) + if (hashAlgorithmIdentifier is null || insufficientCollisionResistance || + signature.Length != Algorithm.SignatureSizeInBytes) { return false; } + if (hashLengthInBytes != hash.Length) + { + throw new CryptographicException(SR.Cryptography_HashLengthMismatch); + } + + ThrowIfDisposed(); + return VerifyPreHashCore(hash, context, hashAlgorithmOid, signature); } @@ -2114,7 +2146,76 @@ internal static void ThrowIfNotSupported() } } + // Returns a hash algorithm identifier for an OID. + // insufficientCollisionResistance is true if the hash algorithm is known, but does not meet the required + // collision resistance from FIPS 204. + private protected string? MapHashOidToAlgorithm( + string hashOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance) + { + int hashLambda; + string hashAlgorithmIdentifier; + + switch (hashOid) + { + case Oids.Md5: + hashLengthInBytes = 128 / 8; + insufficientCollisionResistance = true; + return HashAlgorithmNames.MD5; + case Oids.Sha1: + hashLengthInBytes = 160 / 8; + insufficientCollisionResistance = true; + return HashAlgorithmNames.SHA1; + case Oids.Sha256: + hashLengthInBytes = 256 / 8; + hashLambda = 256 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA256; + break; + case Oids.Sha3_256: + hashLengthInBytes = 256 / 8; + hashLambda = 256 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA3_256; + break; + case Oids.Sha384: + hashLengthInBytes = 384 / 8; + hashLambda = 384 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA384; + break; + case Oids.Sha3_384: + hashLengthInBytes = 384 / 8; + hashLambda = 384 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA3_384; + break; + case Oids.Sha512: + hashLengthInBytes = 512 / 8; + hashLambda = 512 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA512; + break; + case Oids.Sha3_512: + hashLengthInBytes = 512 / 8; + hashLambda = 512 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA3_512; + break; + case Oids.Shake128: // SHAKE-128 with 256-bits of output + hashLengthInBytes = 256 / 8; + hashLambda = 256 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHAKE128; + break; + case Oids.Shake256: // SHAKE-256 with 512-bits of output + hashLengthInBytes = 512 / 8; + hashLambda = 512 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHAKE256; + break; + default: + hashLengthInBytes = 0; + insufficientCollisionResistance = false; + return null; + } + insufficientCollisionResistance = hashLambda < Algorithm.LambdaCollisionStrength; + return hashAlgorithmIdentifier; + } private delegate TResult ExportPkcs8PrivateKeyFunc(ReadOnlySpan pkcs8); } diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs index c058daab3bb..63d29d3dae6 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs @@ -54,31 +54,21 @@ public sealed class MLDsaAlgorithm : IEquatable public int SignatureSizeInBytes { get; } internal string Oid { get; } - - /// - /// Initializes a new instance of the structure with a custom name. - /// - /// - /// The name of the algorithm. - /// - /// - /// The size of the secret key in bytes. - /// - /// - /// The size of the public key in bytes. - /// - /// - /// The size of the signature in bytes. - /// - /// - /// The OID of the algorithm. - /// - private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeInBytes, int signatureSizeInBytes, string oid) + internal int LambdaCollisionStrength { get; } + + private MLDsaAlgorithm( + string name, + int secretKeySizeInBytes, + int publicKeySizeInBytes, + int signatureSizeInBytes, + int lambdaCollisionStrength, + string oid) { Name = name; SecretKeySizeInBytes = secretKeySizeInBytes; PublicKeySizeInBytes = publicKeySizeInBytes; SignatureSizeInBytes = signatureSizeInBytes; + LambdaCollisionStrength = lambdaCollisionStrength; Oid = oid; } @@ -91,7 +81,7 @@ private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeI /// /// An ML-DSA algorithm identifier for the ML-DSA-44 algorithm. /// - public static MLDsaAlgorithm MLDsa44 { get; } = new MLDsaAlgorithm("ML-DSA-44", 2560, 1312, 2420, Oids.MLDsa44); + public static MLDsaAlgorithm MLDsa44 { get; } = new MLDsaAlgorithm("ML-DSA-44", 2560, 1312, 2420, 128, Oids.MLDsa44); /// /// Gets an ML-DSA algorithm identifier for the ML-DSA-65 algorithm. @@ -99,7 +89,7 @@ private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeI /// /// An ML-DSA algorithm identifier for the ML-DSA-65 algorithm. /// - public static MLDsaAlgorithm MLDsa65 { get; } = new MLDsaAlgorithm("ML-DSA-65", 4032, 1952, 3309, Oids.MLDsa65); + public static MLDsaAlgorithm MLDsa65 { get; } = new MLDsaAlgorithm("ML-DSA-65", 4032, 1952, 3309, 192, Oids.MLDsa65); /// /// Gets an ML-DSA algorithm identifier for the ML-DSA-87 algorithm. @@ -107,7 +97,7 @@ private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeI /// /// An ML-DSA algorithm identifier for the ML-DSA-87 algorithm. /// - public static MLDsaAlgorithm MLDsa87 { get; } = new MLDsaAlgorithm("ML-DSA-87", 4896, 2592, 4627, Oids.MLDsa87); + public static MLDsaAlgorithm MLDsa87 { get; } = new MLDsaAlgorithm("ML-DSA-87", 4896, 2592, 4627, 256, Oids.MLDsa87); internal static MLDsaAlgorithm? GetMLDsaAlgorithmFromOid(string? oid) { diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs index 63825cb3481..bd384cab56c 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs @@ -267,12 +267,74 @@ protected override unsafe bool VerifyDataCore(ReadOnlySpan data, ReadOnlyS } /// - protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => - throw new PlatformNotSupportedException(); + protected override unsafe void SignPreHashCore( + ReadOnlySpan hash, + ReadOnlySpan context, + string hashAlgorithmOid, + Span destination) + { + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); + + using (SafeNCryptKeyHandle duplicatedHandle = _key.Handle) + { + fixed (char* pHashAlgorithmIdentifier = hashAlgorithmIdentifier) + fixed (void* pContext = context) + { + BCRYPT_PQDSA_PADDING_INFO paddingInfo = default; + paddingInfo.pbCtx = (IntPtr)pContext; + paddingInfo.cbCtx = context.Length; + paddingInfo.pszPreHashAlgId = (IntPtr)pHashAlgorithmIdentifier; + + duplicatedHandle.SignHash( + hash, + destination, + Interop.NCrypt.AsymmetricPaddingMode.NCRYPT_PAD_PQDSA_FLAG, + &paddingInfo); + } + } + } /// - protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => - throw new PlatformNotSupportedException(); + protected override unsafe bool VerifyPreHashCore( + ReadOnlySpan hash, + ReadOnlySpan context, + string hashAlgorithmOid, + ReadOnlySpan signature) + { + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); + + using (SafeNCryptKeyHandle duplicatedHandle = _key.Handle) + { + fixed (char* pHashAlgorithmIdentifier = hashAlgorithmIdentifier) + fixed (void* pContext = context) + { + BCRYPT_PQDSA_PADDING_INFO paddingInfo = default; + paddingInfo.pbCtx = (IntPtr)pContext; + paddingInfo.cbCtx = context.Length; + paddingInfo.pszPreHashAlgId = (IntPtr)pHashAlgorithmIdentifier; + + return duplicatedHandle.VerifyHash( + hash, + signature, + Interop.NCrypt.AsymmetricPaddingMode.NCRYPT_PAD_PQDSA_FLAG, + &paddingInfo); + } + } + } [SupportedOSPlatform("windows")] internal static MLDsaCng ImportPkcs8PrivateKey(byte[] source, out int bytesRead) diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs index 65c3c320960..5b62f4a6e40 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs @@ -47,11 +47,46 @@ protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => Interop.BCrypt.BCryptVerifySignaturePqcPure(_key, data, context, signature); - protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => - throw new PlatformNotSupportedException(); + protected override void SignPreHashCore( + ReadOnlySpan hash, + ReadOnlySpan context, + string hashAlgorithmOid, + Span destination) + { + if (!_hasSecretKey) + { + throw new CryptographicException(SR.Cryptography_MLDsaNoSecretKey); + } + + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); - protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => - throw new PlatformNotSupportedException(); + Interop.BCrypt.BCryptSignHashPqcPreHash(_key, hash, hashAlgorithmIdentifier, context, destination); + } + + protected override bool VerifyPreHashCore( + ReadOnlySpan hash, + ReadOnlySpan context, + string hashAlgorithmOid, + ReadOnlySpan signature) + { + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); + + return Interop.BCrypt.BCryptVerifySignaturePqcPreHash(_key, hash, hashAlgorithmIdentifier, context, signature); + } internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algorithm) { diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs index 678e8ea6d78..c9c0a6a6f77 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs @@ -372,7 +372,12 @@ public bool IgnoreEncryptedAuthSafes /// to fail loading when duplicate attributes are found. /// The default is . /// - internal bool AllowDuplicateAttributes +#if NET10_0_OR_GREATER + public +#else + internal +#endif + bool AllowDuplicateAttributes { get => _allowDuplicateAttributes; set diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs index 552d77c21e8..0d63c336370 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs @@ -99,7 +99,9 @@ internal static MLDsaTestImplementation CreateOverriddenCoreMethodsFail(MLDsaAlg ExportMLDsaPublicKeyHook = _ => Assert.Fail(), ExportMLDsaSecretKeyHook = _ => Assert.Fail(), SignDataHook = (_, _, _) => Assert.Fail(), + SignPreHashHook = delegate { Assert.Fail(); }, VerifyDataHook = (_, _, _) => { Assert.Fail(); return false; }, + VerifyPreHashHook = delegate { Assert.Fail(); return false; }, DisposeHook = _ => { }, TryExportPkcs8PrivateKeyHook = (_, out bytesWritten) => diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs index b6cb0c35672..27b920761db 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs @@ -128,8 +128,8 @@ public static void ArgumentValidation(MLDsaAlgorithm algorithm, bool shouldDispo AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaPrivateSeed(new byte[privateSeedSize + 1])); AssertExtensions.Throws("destination", () => mldsa.SignData(ReadOnlySpan.Empty, new byte[signatureSize - 1], ReadOnlySpan.Empty)); AssertExtensions.Throws("destination", () => mldsa.SignData(ReadOnlySpan.Empty, new byte[signatureSize + 1], ReadOnlySpan.Empty)); - AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha256.OutputSize], new byte[signatureSize - 1], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); - AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha256.OutputSize], new byte[signatureSize + 1], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize], new byte[signatureSize - 1], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize], new byte[signatureSize + 1], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); // Context length must be less than 256 AssertExtensions.Throws("context", () => mldsa.SignData(ReadOnlySpan.Empty, signature, new byte[256])); @@ -140,21 +140,17 @@ public static void ArgumentValidation(MLDsaAlgorithm algorithm, bool shouldDispo AssertExtensions.Throws("context", () => mldsa.SignPreHash(hash, HashInfo.Sha256.Oid, new byte[256])); // Hash length of known OID hash algorithms must be correct - AssertExtensions.Throws(() => mldsa.SignPreHash(new byte[HashInfo.Sha256.OutputSize - 1], new byte[signatureSize], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); - AssertExtensions.Throws(() => mldsa.SignPreHash(new byte[HashInfo.Sha256.OutputSize + 1], new byte[signatureSize], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); - AssertExtensions.Throws(() => mldsa.VerifyPreHash(new byte[HashInfo.Sha256.OutputSize - 1], new byte[signatureSize], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); - AssertExtensions.Throws(() => mldsa.VerifyPreHash(new byte[HashInfo.Sha256.OutputSize + 1], new byte[signatureSize], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws(() => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize - 1], new byte[signatureSize], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws(() => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize + 1], new byte[signatureSize], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws(() => mldsa.VerifyPreHash(new byte[HashInfo.Sha512.OutputSize - 1], new byte[signatureSize], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws(() => mldsa.VerifyPreHash(new byte[HashInfo.Sha512.OutputSize + 1], new byte[signatureSize], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); // Must be valid OID Assert.Throws(() => mldsa.SignPreHash([], "not.an.oid")); Assert.Throws(() => mldsa.SignPreHash([], signature, "not-an-oid")); - Assert.Throws(() => mldsa.VerifyPreHash(Array.Empty(), signature, "1")); - Assert.Throws(() => mldsa.VerifyPreHash([], signature.AsSpan(), "a")); Assert.Throws(() => mldsa.SignPreHash([1], string.Empty)); Assert.Throws(() => mldsa.SignPreHash([1], signature, "-1.0.0")); - Assert.Throws(() => mldsa.VerifyPreHash(new byte[] { 1 }, signature, "a")); - Assert.Throws(() => mldsa.VerifyPreHash([1], signature.AsSpan(), "a")); } public static IEnumerable ArgumentValidation_Hash_WrongSizeInputs() @@ -194,61 +190,26 @@ public static void ArgumentValidation_Hash_WrongSize(bool shouldDispose, HashInf } [Fact] - public static void ArgumentValidation_HashAlgorithm_UnknownOidCallsCore() + public static void ArgumentValidation_HashAlgorithm_UnknownOidDoesNotCallCore() { - using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); + using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44); byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; string hashAlgorithmOid = "1.0"; - - mlDsa.SignPreHashHook = (_, _, _, _) => { }; - mlDsa.AddSignatureBufferIsSameAssertion(signature.AsMemory()); - mlDsa.AddHashAlgorithmIsSameAssertion(hashAlgorithmOid.AsMemory()); - - _ = mlDsa.SignPreHash([], hashAlgorithmOid); - Assert.Equal(1, mlDsa.SignPreHashCoreCallCount); - - mlDsa.SignPreHash([], signature, hashAlgorithmOid); - Assert.Equal(2, mlDsa.SignPreHashCoreCallCount); - - _ = mlDsa.SignPreHash([1], hashAlgorithmOid); - Assert.Equal(3, mlDsa.SignPreHashCoreCallCount); - - mlDsa.SignPreHash([1], signature, hashAlgorithmOid); - Assert.Equal(4, mlDsa.SignPreHashCoreCallCount); - - mlDsa.SignPreHashHook = (_, _, _, _) => Assert.Fail(); - mlDsa.VerifyPreHashHook = (_, _, _, _) => true; - mlDsa.AddSignatureBufferIsSameAssertion(signature.AsMemory()); - mlDsa.AddHashAlgorithmIsSameAssertion(hashAlgorithmOid.AsMemory()); - - _ = mlDsa.VerifyPreHash(Array.Empty(), signature, hashAlgorithmOid); - Assert.Equal(1, mlDsa.VerifyPreHashCoreCallCount); - - _ = mlDsa.VerifyPreHash([], signature.AsSpan(), hashAlgorithmOid); - Assert.Equal(2, mlDsa.VerifyPreHashCoreCallCount); - - _ = mlDsa.VerifyPreHash(new byte[] { 1 }, signature, hashAlgorithmOid); - Assert.Equal(3, mlDsa.VerifyPreHashCoreCallCount); - - _ = mlDsa.VerifyPreHash([1], signature.AsSpan(), hashAlgorithmOid); - Assert.Equal(4, mlDsa.VerifyPreHashCoreCallCount); + CryptographicException ce = Assert.Throws(() => mlDsa.SignPreHash([], hashAlgorithmOid)); + Assert.Contains(hashAlgorithmOid, ce.Message); } - public static IEnumerable AllHashesAndLengthsAndExtraUnknown() + public static IEnumerable AllHashesAndLengths() { foreach (HashInfo hashInfo in HashInfo.AllHashInfos()) { yield return new object[] { hashInfo.Oid, hashInfo.OutputSize }; } - - yield return new object[] { "1.0", 0 }; - yield return new object[] { "1.0", 1 }; - yield return new object[] { "1.0", 2 }; } [Theory] - [MemberData(nameof(AllHashesAndLengthsAndExtraUnknown))] + [MemberData(nameof(AllHashesAndLengths))] public static void SignPreHash_CallsCore(string hashAlgorithmOid, int hashLength) { MLDsaAlgorithm algorithm = MLDsaAlgorithm.MLDsa44; @@ -285,7 +246,7 @@ public static void SignPreHash_CallsCore(string hashAlgorithmOid, int hashLength } [Theory] - [MemberData(nameof(AllHashesAndLengthsAndExtraUnknown))] + [MemberData(nameof(AllHashesAndLengths))] public static void VerifyPreHash_CallsCore(string hashAlgorithmOid, int hashLength) { using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); @@ -321,7 +282,7 @@ public static void VerifyPreHash_CallsCore(string hashAlgorithmOid, int hashLeng } [Theory] - [MemberData(nameof(AllHashesAndLengthsAndExtraUnknown))] + [MemberData(nameof(AllHashesAndLengths))] public static void VerifyPreHash_ByteArray_CallsCore(string hashAlgorithmOid, int hashLength) { using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs index c2da6357672..6f4ed26dc51 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs @@ -29,7 +29,7 @@ public void AlgorithmIsAssigned(MLDsaAlgorithm algorithm) public void GenerateSignVerifyNoContext(MLDsaAlgorithm algorithm) { using MLDsa mldsa = GenerateKey(algorithm); - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature = mldsa.SignData(data); ExerciseSuccessfulVerify(mldsa, data, signature, []); } @@ -40,9 +40,9 @@ public void GenerateSignVerifyPreHashNoContext(MLDsaAlgorithm algorithm) { using MLDsa mldsa = GenerateKey(algorithm); byte[] data = [1, 2, 3, 4, 5]; - byte[] hash = HashInfo.Sha256.GetHash(data); - byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha256.Oid, []); - ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha256.Oid, hash, signature, []); + byte[] hash = HashInfo.Sha512.GetHash(data); + byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid, []); + ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha512.Oid, hash, signature, []); } [Theory] @@ -50,8 +50,8 @@ public void GenerateSignVerifyPreHashNoContext(MLDsaAlgorithm algorithm) public void GenerateSignVerifyWithContext(MLDsaAlgorithm algorithm) { using MLDsa mldsa = GenerateKey(algorithm); - byte[] context = [ 1, 1, 3, 5, 6 ]; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] context = [1, 1, 3, 5, 6]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature = mldsa.SignData(data, context); ExerciseSuccessfulVerify(mldsa, data, signature, context); @@ -64,10 +64,10 @@ public void GenerateSignVerifyPreHashWithContext(MLDsaAlgorithm algorithm) using MLDsa mldsa = GenerateKey(algorithm); byte[] context = [1, 1, 3, 5, 6]; byte[] data = [1, 2, 3, 4, 5]; - byte[] hash = HashInfo.Sha256.GetHash(data); - byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha256.Oid, context); + byte[] hash = HashInfo.Sha512.GetHash(data); + byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid, context); - ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha256.Oid, hash, signature, context); + ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha512.Oid, hash, signature, context); } [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SigningEmptyDataIsSupported))] @@ -96,9 +96,9 @@ public void GenerateSignVerifyEmptyMessageWithContext(MLDsaAlgorithm algorithm) public void GenerateSignExportPublicVerifyWithPublicOnly(MLDsaAlgorithm algorithm) { byte[] publicKey; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature; - byte[] hash = HashInfo.Sha256.GetHash(data); + byte[] hash = HashInfo.Sha512.GetHash(data); byte[] signaturePreHash; using (MLDsa mldsa = GenerateKey(algorithm)) @@ -106,8 +106,8 @@ public void GenerateSignExportPublicVerifyWithPublicOnly(MLDsaAlgorithm algorith signature = mldsa.SignData(data); AssertExtensions.TrueExpression(mldsa.VerifyData(data, signature)); - signaturePreHash = mldsa.SignPreHash(hash, HashInfo.Sha256.Oid); - AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signaturePreHash, HashInfo.Sha256.Oid)); + signaturePreHash = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid); + AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signaturePreHash, HashInfo.Sha512.Oid)); publicKey = mldsa.ExportMLDsaPublicKey(); } @@ -115,8 +115,8 @@ public void GenerateSignExportPublicVerifyWithPublicOnly(MLDsaAlgorithm algorith using (MLDsa mldsaPub = ImportPublicKey(algorithm, publicKey)) { ExerciseSuccessfulVerify(mldsaPub, data, signature, []); - ExerciseSuccessfulVerifyPreHash(mldsaPub, HashInfo.Sha256.Oid, hash, signaturePreHash, []); - AssertExtensions.FalseExpression(mldsaPub.VerifyPreHash(hash, signature, HashInfo.Sha256.Oid)); + ExerciseSuccessfulVerifyPreHash(mldsaPub, HashInfo.Sha512.Oid, hash, signaturePreHash, []); + AssertExtensions.FalseExpression(mldsaPub.VerifyPreHash(hash, signature, HashInfo.Sha512.Oid)); } } @@ -125,7 +125,7 @@ public void GenerateSignExportPublicVerifyWithPublicOnly(MLDsaAlgorithm algorith public void GenerateExportSecretKeySignAndVerify(MLDsaAlgorithm algorithm) { byte[] secretKey; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature; using (MLDsa mldsaTmp = GenerateKey(algorithm)) @@ -153,7 +153,7 @@ public void GenerateExportSecretKeySignAndVerify(MLDsaAlgorithm algorithm) public void GenerateExportPrivateSeedSignAndVerify(MLDsaAlgorithm algorithm) { byte[] privateSeed; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature; using (MLDsa mldsaTmp = GenerateKey(algorithm)) @@ -312,6 +312,18 @@ public void SignData_PublicKeyOnlyThrows(MLDsaKeyInfo info) Assert.DoesNotContain("unknown", ce.Message, StringComparison.OrdinalIgnoreCase); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] + [MemberData(nameof(UnsupportedWindowsPreHashCombinations))] + public void SignPreHash_ThrowsForUnsupportedAlgorithmCombinations(MLDsaAlgorithm algorithm, HashInfo hashInfo) + { + using MLDsa mldsa = GenerateKey(algorithm); + byte[] hash = hashInfo.GetHash([1, 2, 3, 4]); + + CryptographicException ce = Assert.Throws(() => mldsa.SignPreHash(hash, hashInfo.Oid)); + Assert.Contains(algorithm.Name, ce.Message); + Assert.Contains(hashInfo.Name.Name, ce.Message); + } + protected static void ExerciseSuccessfulVerify(MLDsa mldsa, byte[] data, byte[] signature, byte[] context) { ReadOnlySpan buffer = [0, 1, 2, 3]; @@ -407,5 +419,25 @@ protected static void ExerciseSuccessfulVerifyPreHash(MLDsa mldsa, string hashAl AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, context)); } + + public static IEnumerable UnsupportedWindowsPreHashCombinations() + { + yield return new object[] { MLDsaAlgorithm.MLDsa44, HashInfo.Md5 }; + yield return new object[] { MLDsaAlgorithm.MLDsa44, HashInfo.Sha1 }; + + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Md5 }; + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Sha1 }; + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Sha256 }; + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Sha3_256 }; + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Shake128 }; + + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Md5 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha1 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha256 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha3_256 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha384 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha3_384 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Shake128 }; + } } } diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs index 754c1e64fc7..8d9cbb81a3d 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs @@ -3676,7 +3676,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) new MLDsaNistTestCase( nistTestCaseId: 54, algorithm: MLDsaAlgorithm.MLDsa65, - shouldPass: true, + shouldPass: false, // SHAKE128 does not meet lambda requirement of HashML-DSA-65. publicKeyHex: "D8D1170517D75DB90659838E13D45E98ED20D1961D98AEC16D2F10C51DF289E7FC4ED97D52166C8C" + "913E7CE9D2CA02AFD7791B95E8F2919F7487F9F1C6B0FE2133E2227FC405FD890DEE8C1B79114C32" + @@ -4015,7 +4015,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) new MLDsaNistTestCase( nistTestCaseId: 76, algorithm: MLDsaAlgorithm.MLDsa87, - shouldPass: true, + shouldPass: false, // SHA-3-256 does not meet lambda requirement of ML-DSA-87. publicKeyHex: "E4C74427766F1AE8399213E114EFA1EEFC7A85CD583C28B38EDFB5AA2351698ACABF5487E7B721F6" + "D15D5A60E0D0B629C663D2EF7007CE21C574F3F01A1D9C7A9A80E4DED8B3D14E3996C9FBD4018390" + diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs index 7708694c275..60fa07254d5 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs @@ -32,16 +32,16 @@ public class HashInfo public static readonly HashInfo Sha384 = new HashInfo(Sha384Oid, 384 / 8, HashAlgorithmName.SHA384); public static readonly HashInfo Sha512 = new HashInfo(Sha512Oid, 512 / 8, HashAlgorithmName.SHA512); - private static readonly HashAlgorithmName HashAlgSHAKE128 = new HashAlgorithmName("BOGUS-SHAKE128"); - private static readonly HashAlgorithmName HashAlgSHAKE256 = new HashAlgorithmName("BOGUS-SHAKE256"); + private static readonly HashAlgorithmName HashAlgSHAKE128 = new HashAlgorithmName("SHAKE128"); + private static readonly HashAlgorithmName HashAlgSHAKE256 = new HashAlgorithmName("SHAKE256"); #if NET private static readonly HashAlgorithmName HashAlgSHA3_256 = HashAlgorithmName.SHA3_256; private static readonly HashAlgorithmName HashAlgSHA3_384 = HashAlgorithmName.SHA3_384; private static readonly HashAlgorithmName HashAlgSHA3_512 = HashAlgorithmName.SHA3_512; #else - private static readonly HashAlgorithmName HashAlgSHA3_256 = new HashAlgorithmName("BOGUS-SHA3_256"); - private static readonly HashAlgorithmName HashAlgSHA3_384 = new HashAlgorithmName("BOGUS-SHA3_384"); - private static readonly HashAlgorithmName HashAlgSHA3_512 = new HashAlgorithmName("BOGUS-SHA3_512"); + private static readonly HashAlgorithmName HashAlgSHA3_256 = new HashAlgorithmName("SHA3-256"); + private static readonly HashAlgorithmName HashAlgSHA3_384 = new HashAlgorithmName("SHA3-384"); + private static readonly HashAlgorithmName HashAlgSHA3_512 = new HashAlgorithmName("SHA3-512"); #endif public static readonly HashInfo Sha3_256 = new HashInfo(Sha3_256Oid, 256 / 8, HashAlgSHA3_256); @@ -59,19 +59,11 @@ public byte[] GetHash(byte[] data) #if NET if (Oid == Shake128Oid) { - using (Shake128 hasher = new Shake128()) - { - hasher.AppendData(data); - return hasher.GetHashAndReset(OutputSize); - } + return System.Security.Cryptography.Shake128.HashData(data, OutputSize); } else if (Oid == Shake256Oid) { - using (Shake256 hasher = new Shake256()) - { - hasher.AppendData(data); - return hasher.GetHashAndReset(OutputSize); - } + return System.Security.Cryptography.Shake256.HashData(data, OutputSize); } else #endif @@ -97,8 +89,6 @@ public static byte[] HashData(string hashAlgOid, byte[] data) public static IEnumerable AllHashInfos() { - yield return Md5; - yield return Sha1; yield return Sha256; yield return Sha384; yield return Sha512; diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs index 08e9e507176..5f97ca8d3d5 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs @@ -637,126 +637,246 @@ public static IEnumerable MLKemDecapsulationTestVe ); // The vectors below are generated from the NIST ACVP projections. - // https://github.com/usnistgov/ACVP-Server/blob/85f8742965b2691862079172982683757d8d91db/gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json + // https://github.com/usnistgov/ACVP-Server/blob/112690e8484dba7077709a05b1f3af58ddefdd5d/gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "C9C81034C5481BCBD90DEE95F277DEAEEDA9240AC844B27AF04C5351256B3B2122C0FD22F18D82C82C80875253EEEA45C3F7F2C4C40F321412460025596C196354E14D870892FB2A862E52FDD3E77BE07F500417F29784D3D2FAA477F10406C5FAE13B1B925B1ECA3FF4C8C3AF2F7A14CD30C301892EFBF0DEAE245DFC3816F32A6641C208E800E3BD3CE678013B70D0B588174E6AB0E03D095F009EB301497E6E36EBFD215FBFFCD78EB9D8372B034525CB41EAF5CBA3D5F2F434F2F6B85CB011E97475F5252D6407C92A0467286646E8CC49F669E6C6579ABFFD28F4451241BB559027F37BEB0E4EC110519C5D3C5C8F5A39A67681188F9E173FFC1601D35F79DA24462B1A4FF5A04EC9C4C5C0F4F276E4807DAB94ED35A7B1F99D78BA5F767F9D6FDF1CE4C01B696FA10F49CB500CDD0CB921665FEE23CA153AB9E823BA88B944240FD6638D261B06FDE5302CDCBFF66D2E55AA6DE9C14CC177752513BEBF6C4DC3BE8C293285DD0F643A11A31293419B34D4B18B9A46223964DD7B8482D96E27449E85EC16E663D6AF2B85A1B630B84CCB87CCAE6DEBD515A5A2D9B05BF0324670284EA5F1ABE69BB4B6EFA261712A28CC520CB72881DC7DD788AAC865BE8B51F0BF414EA7B8CC9F4473AC2D03B73FD9E9A7CCDEE38C7B170FD5A34FE562ADFC41E8E45957CE426F6432001238CA36B5162D79FB3C9FB6A9071E453C8E9CA05CB52A859EF21C8051E8B8DFEDB5370FA9E57A45B04FE383394F72407BA397CCA87E017B32D22673F50E6E1244A81DDD6B381BC1E67099484DFCD087E7BDF479A8AF559D7893671802EE10D114379480E4DC11EDEC1605A81059C0D40400B3032D50620F3236A28F068D07FC7EF14121FD4701763AE2A8E4731EFF8D1C103EE4DB6B89FE4ACEB94C5F78A7CAAF5FE2D28831A9213964A8782EFD2170F5B2D966C49181BDA6CAC6A22C7A6D65713DB7DDA24537A711B06E7B0BF975C22F9CF33B5A7D6B5E3903AFD353326EE33D755DC747D76320FA8587087B9F5D106D6C3792B4BB25EDB2ABBE2699C7FF3D3B8B65919E508A5BE06F2D2138A1BEB2BB136F", - "57AE473989DFACA8266BE8C640B4CADE4DA7B02280E6C9D67612AD4B975381E9" + "70EC19B39348974173A550A5C52A248E191D46640799A4365F3C254757350B65764984180A9ABC9048679D6A84C61B7405EC82A403B79569C024CACA55D79BE23C943C159DDADB17011820C7D88D54071FC8AB142727BE747BBD253A26E92071DC34716F5037D1988A889302621A8465D08ABFD2215D97575D730C9495617EF3B69D0C7AA79965CA985BC147797D9688116A20F9626BAB1997FCEAACBFB439D655A566B0A4BD08472265439C00CE487955EBEA094AD00A6A5AC6FB9359F3C11A6E4B3B6C714F70F8A7B8B6524572B34B758DA270753B697415A964170374548B9D1FE43FD80C62A4D951E28182F2848B044A8352E11F5198547B71215E6287DFF13A18287148277883926396D9A07C0B0139577E4923AC41C9C31F0B6067C88B94CBB9921513ACF0AE80D7779D72C666B256B72A777B56A2D12007797B7BE6657650EB42B1060AADC5157FB819EBF707E51637CD8469645196765A2EBFE8483D62C5E2422C27BCA84E5A0F69F45609928A7E51948A9464D5093CF463A39C26447126C684160F3A4298EA0B5B0973A15403CDDF286BEBFA587FFBB5BFA7692A404ABE3BB14014AEAC418900E4588676A5E7A21553F50037262E3DD6253A8BBD985A679F638F709545AB322F6DE71192FB60C0A368A3B06C8CF5267D792D6C2518EA0A27855635E3E68891C141123A1F8C80AA5300B151AC9AE4342334265C457CA8809891EFF12B398A8465F25508836EE3075C898822BA7675AC359D80E85FF84112C8502932016E24531FB24AA0F744B8252B3D89B4A41721BFD779A826AA46F00720B9592A12307B27EB2B5502987AB477161B72F31BB8EF2C2F4EA83823B72CB16532768508835852A701C3522A7B71DA1CD8B5CCA512117990709797C8AAEA3B300B79A28460D22A2C3527CBB8529AA667064FA2039E22AD5ED740BFA353EB04B74A9C9328266561A76A12EC2C33766697DABBDE92A712B81712D2C4E1F335AA642774441E917650F8D92278A8C0444214A774B7996463527756935171D9FA61D0B50454F74ED50831EB3138DB7374A35387BBCB23E40388BB9228C3A66CDD2222524D7CB8DAE2E70FE3D97847AC35824F5D58B54DD943A440DBFF421642", + "54301038DA5911366D16C417BFD96AEB85C5DA4AA45AF32F88A700BB9A973AB62684A052D793379B3C2B253B01A4E512AB34C8D8A76F5EBA5F1B28451A66632872C489F3CA606C6B36336895C032386BB35E98B43C8136350616CCF82A4C24816F4354B7C197940A62537BB36F2B8DE32A6AF6CAA100845FB62184B82B29DCE2662CA94D93FB027DB3C8EF858D4223540E79AD5D204C99637FB66718CD04782E149A07354D6FB2C742A9849506BDDECC0548367421FA2B8599443C74192D6B4B67CC5E16F8880087AC578ABCADB5492CC1AC6916CE73AB2858797134676260B22B28B4A8917C5ABD876EDA706CE381AA4985827D492A736652DD6C1DADD10ADF045DBF416158B0384A991D8501BAA9A714B82788C263C16858C81B978FD353126222A46E1587718872BB11513CDA3A88B6547BC464CD612548E581DFE106382428BA8452A86AC6ECB50B7B3C1CBEA571513C63B8741A2CB82C5055CDB2CB00CE9036C220A25C1BA21891B520D435342136D0C15AAFC12DBCC810E9C256D397A3D23A6287282AAEC038649151886A19F9B583806839EE86A12D131FB3E6A1CA1C9CC48626037B5F3DA74C8A025CC61A76078B07D00AA6DAD32C4147CDAADB4DF644A8DBF4222C47AEEF774BDAFA5A48258BDEA84E7B8B6A5CA09243589EF7F1C249A2B344068FC8D874C33B6C4C2782EA86AADE7C10EFDCC93FB993147A3B636127711195C121C7506759389373F896843991125D5A0AB8FB34595166A9109DC2D19AE2738444716C9C21BD06DC8145458ACBA30981A95F8E141BD17B17A3F645E9B63747E370E8D873937A858048614F0645F4B461EF769D2A696706C2811E756163E4746BF00CFFC556AD7A2F0804A6BEDC6A59B1546727C602A99397C50FF818721D5319F63B058D03BC9DE57C1DB74FE14A0D083C25B17886200633D230946DE0A148781735555CCE797040BB479FA733C2A808EE1CB9A285CF863CBDB47172F3A68EEA614736C73C71FA4AD82C6CF13C5CD3179AD296BF3BD6815D13CBFF75A3A99B4824B7560227BE0BD809BD43AED7D951ECDB7273719560DCC0E8C13F70EC19B39348974173A550A5C52A248E191D46640799A4365F3C254757350B65764984180A9ABC9048679D6A84C61B7405EC82A403B79569C024CACA55D79BE23C943C159DDADB17011820C7D88D54071FC8AB142727BE747BBD253A26E92071DC34716F5037D1988A889302621A8465D08ABFD2215D97575D730C9495617EF3B69D0C7AA79965CA985BC147797D9688116A20F9626BAB1997FCEAACBFB439D655A566B0A4BD08472265439C00CE487955EBEA094AD00A6A5AC6FB9359F3C11A6E4B3B6C714F70F8A7B8B6524572B34B758DA270753B697415A964170374548B9D1FE43FD80C62A4D951E28182F2848B044A8352E11F5198547B71215E6287DFF13A18287148277883926396D9A07C0B0139577E4923AC41C9C31F0B6067C88B94CBB9921513ACF0AE80D7779D72C666B256B72A777B56A2D12007797B7BE6657650EB42B1060AADC5157FB819EBF707E51637CD8469645196765A2EBFE8483D62C5E2422C27BCA84E5A0F69F45609928A7E51948A9464D5093CF463A39C26447126C684160F3A4298EA0B5B0973A15403CDDF286BEBFA587FFBB5BFA7692A404ABE3BB14014AEAC418900E4588676A5E7A21553F50037262E3DD6253A8BBD985A679F638F709545AB322F6DE71192FB60C0A368A3B06C8CF5267D792D6C2518EA0A27855635E3E68891C141123A1F8C80AA5300B151AC9AE4342334265C457CA8809891EFF12B398A8465F25508836EE3075C898822BA7675AC359D80E85FF84112C8502932016E24531FB24AA0F744B8252B3D89B4A41721BFD779A826AA46F00720B9592A12307B27EB2B5502987AB477161B72F31BB8EF2C2F4EA83823B72CB16532768508835852A701C3522A7B71DA1CD8B5CCA512117990709797C8AAEA3B300B79A28460D22A2C3527CBB8529AA667064FA2039E22AD5ED740BFA353EB04B74A9C9328266561A76A12EC2C33766697DABBDE92A712B81712D2C4E1F335AA642774441E917650F8D92278A8C0444214A774B7996463527756935171D9FA61D0B50454F74ED50831EB3138DB7374A35387BBCB23E40388BB9228C3A66CDD2222524D7CB8DAE2E70FE3D97847AC35824F5D58B54DD943A440DBFF4216429146E2AC9383962420545163D6F82456E1B93E22A1B2E6875ADA12D4E194AE93EF5C3485EEBBE1BB13C560480DC3471CD950EB300CF2D18F38CAE7575B133526", + "9068502093766BB27635F12F3569794C54227CB1828128AEFC5B715CDCD1E9080D59FB218D17EA0D212D158DDB5ED0FFDB4FA9401F4F23387D32AC8B788CFB7A319114425138744002648B07D5216A3EFB4964BC72E98A6EA2939FAF372CAB44CD5D8A929F66C41D644118ACDE5DA2F09B87F8A1F41F55924A7784D8552790CDF256958E35324381902D9A006FAE02933B017A8E55931B6A0CC8CE3B5723D85DE4C4585FAEC0BD80986224CDAEA443556EBF8BCFDE162C258B9E0AB00C2B9DE0190384C61988BCF362BD0493D40D276FFE4873811EF2851204626342921BFB6A75EB6079F58C030AB1D9C1844078E61C29DB88B5FDC463B7AD3F770E1CB8B526BD9B9A5AFADADAED0368BEE0FFABD9ADFEB0FBF6E6DC7A36115BA47A292D454D7A31F5601BD8BD5435B2EF464A474E37B12B7794F356F905FDBEB248B44003F2B43B925CDB98017A68A15B8B90E2D6DAB1B72AC2921CA92F55B3453C2865DECC094E77EC1E70F99A14CE22BBBF7D3C25F1ECBF96478D84DB4EB1F5E077777214CDA31165C2790172EF778435B56B712E3C5C6B2FDFA3B40B45F7065731EC1E33A8FB300F9FD1EAB14A77E5D8367329E0F834A76E889EC2C8F80E5C1098055F2D517EC381A01F37B1AA3923894D90E1A25A8F55D3DB782ADCD644A1B8A168BBF263C77F34B1A3388E76528FD4F91BFDD7D6499EF99CF663964421FFBB6C17CA9456A2E6A3681298628FA728D3FCFB3BDB65A22E7CFC962FB83007F249D543696A8EFBD9A3DBC7C090F2C82B38E76ACB653F18E78407EFDEA120AE61CDCC8C28CAD984D776B69FB201BA3E154F3C87F53CF84DEF777E50BE420DDFB9734065B8D541F983E69E7FB2B48A186BF8338F3234A0B785B2BA63AA875B28EEE98843C48F60BA500E93067F283155A21905836AC33CA8B06790DD800DD000CC42171775A07F704229FB6F9E5123ED032148DD0EC616530B98A68BE3DBAD2A5D24FFABEFD6D78F4484C8A9969DB7480F54A3DDAB445D3C6C489A9E296B612591A027D624032CD1B11452FEA69A178006E8429BEAB1FC089098BE7EA3D73518F3F5E7B59843", + "32FE0534E517EC8F87A25578EA047417EC479EECE897D2BA5F9D41A521FAEDCC" ); yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "4D18E11B61F670F19330C7893B620DABD0E01B1DEEDEB2AFE73921078FFCA2DF210EBA11AFD214632ADEC9E136A35B4C90C418CD1C3A4E7895FE8400419118BBDA76486F26336646905A633C0E5EFDF8EF0DDDA6BF759DCB2873A9F4F9894A8B075FA763E07F96EFB540332E34BF8273861D0CAEA2DA268130CCE8433C0D457F9FFB2B9657A6FD277DD93157FFB9DEA6EDC2D3C30A069C999A49A45D59C2C4BC152077A8F063B3DF095E58F366A724342A4AA9E3440A867B98CAD924D5DAB546259AA48026E57A4A8E5B8FC1B4FF0D29B5149EC831CD0A5E6FAB4DFB9AFF96B2B1E5E8444084089C88A0435B57DE995A3A627D17CCEDD937C765DC72BC1C04B689030228FE9F127D0363485A53EF4F8800FB39F6DE6733ADFB77D2850EB2A26B30E2DB37F1EC5B4A40979CCD0D7746C7085285F6470200611094C0C83C0327E6308880F9D846F0B51F297660239B3F381DCE91179C3E58BDFA9BCF86A6EFA0E8A5BE21DD9166C7508FC4CC634E7224F27085CE2A7572EB21AF4BDF05680E8397F6989A3899356294AEAEAB57C9F039F4123E84D1A2CD4F660615699373662EBB9367A2EDFAB31801CBB5E0900FAEF108AFF7F8819A40BF5D794067BB5F72E840903B9A318FA998DE5F933B5DA834D3E2A0A4DBA54EA8F538DCC6114826AA1B5CB32A31981950AAC2D0CDB2E23DDD155D4890CEC21F56AD686179E1E51D136D733BFCBB95EEC363F1BEB25151CA019002451613C7431D9FF6E00F7210E641C9A53CACDD54C9A90EA394C0E88B547B6A637B98D8C894009A18D22774D979DCA660CA1CB3557326D2A24719549770E7C533A17C4B18C8CE590ADAF9FD4721D7D74CC66D1C252D99C5082522900813520080BEF39C3517FEA9D0FE404EAB5BE97F8E4444FF63BBD87123944E0B6BF91B7732FBBF0AA877F507A8A5DDBAC7A96525ECA11B3BEBFAB1A9F88A4C0D80E85E06D3EF9A2CF32BF4D186FEDD7B5C6D8664CC8F2F8B8C7E999EC42D36064CA0D363AB3B1B14A41C09C434F8591735285EBE4BDBB11AB4B16A25205B9CE0A73938F9C97799A0DE80747D56D98D7E5A6231F9ED", - "22D9E05E0D01B56BB5042AFB69D497909F66B47CF236E9C77FA06F9D81A16AFB" + "770AB5FCCA728F659556C212F9925F28493CD3C2A60AD743830769F9B387422AC46385C88F4A10D8C43764F5200E810D20AB9A7AEB5C8B100CB751C55B301976D7BD4F0A1DE7D7CFBF0379CC6B9844B16749B8C6659824B65C2659A430914B322289B88D51324772C4A507CBAF240436AAC23950088E41973FCC487F57BD1D14321664AFC6EA2B66403C881509BE445933528A4F97C2A5B86F1CBC08816484F9432241A09E16D6B6C7068F0356505227216127AF9506250E59ADA3AB4611D7BA4A999621241A3D8C4FE0E7CBAE2492B6F44E6AFCA27F33940E3233F5A382549B9DA2C52B9BC99A8BDC1E541B274987A5BC4A272F330F725856220961C659CD9BA534716C5A113B53CD243D5C907FD6E1B2CDE69090B40314B7CA85F2185F9401FA758C3FD8AD91441A6DCB88B7350B753CC06AE5A1FBCB4DF61CAE1DFC7E60C28C7787654A068DD06821983AAED658C110BC19C2FC61E76CAA65D9C0914887A77571B3E63CD63A437028BC03DC8F69346585D023F01465E430220607948619975FAC993703CF60055D9AF28EAA1A2CE412322D11497DF22137380714B701DAE205EF308E2EB8A1B0B09ADB896BB8AB3F34F9BA2695056B7785FD51ACD043CDC1919C6B0335D7E7BDD1C43693582ED5E71D534163A48C45796B43E98BCB3DF47E075B8AE3E96A640CA659747B287C4714113DDCCBC83D37C54022CD321409BE74C331900CB17A72DC27BB6D4401D974B4E236B82F894EF5DC9A7A29091AB475D584B52D9672DDBC8D63B0BDB51554709041CC07CDEE435F39463C04BA0DC2B4C085AAC7822AA4BA50CD470A75C53A7C1318839DF4086D8A8D3510780081112453134F15601F810895B287195866FC237669F5B212C002F62B2130952B99BAC4E0AB002FA915520A715A41B1D541CB54CB7DD0291655F14FD2D0B3D802C9D6CB569FC815B69B1A0787463104A30AB34E7BD732FEEA3C8CC8764FE199947513889942B7C110482C9A1477348C3C3B491060A78B8299490E4DBABD22B054929BA77EE31922E1439D15B530A0C307E72C2F9C568622301DFA261C885A6F66399DC79E593486B11FF236B8367BF6864A1A596448FC251898A3C89CCD0B551131182654", + "3B5879284A33A6204C06F84BF91843CF9B23CD8256E3D23BD1012325686138F40E435275298A614D30950D98B00F59AE6A04BBC37510D4DCBE738B90530B455B048DF4F4AF191B59DB8A3D37C83190D425D40014775B507D43A2E2204B9AA6B6241057663A782A411419F0A0E1E8A4D7F5995B197114E832C7FAB5F2D69923D53A46F07C403038C29219EF228DA1746ED27978D9723D09EA6D6F32856D8B5589382AF4F32D2DDA0EADF342ED3248EB0CCB7B9424FCE6432F8A3892A24D610B9F35B7A4D63B918203BEF239C07277433D8122EDA503C3D596B7C670893051286044EA919BB4863AB6A7CD8D43255C099CE1DB832B109CC24C1B15BCA2F5383F03CC7263775AD39A90DE6A1E1CBB4EE8683295353FDE05478CFBB4C5249500FAA9D35B264E36494F009D8CEA06AC096FF3965DE5980B8E8485149B6912BA7B8E935341755AC67499647391A181158F3AC719F3B36CA0624B6C6F26800904609759B0C5D4270ACCAA01159C4235685D1B079624576C73F498A3F9A37B5090FD6010960C3EC9D7A1D95C3749DC3E225B800D2B8F3B597090F0B83CB315B7A43FB69151AD2B2EF21C8E3D6028A650716BD96F466BAEC316A230232B59A97D371C3DF6D2476C51C64F48271EA38AAE9C8EACD1A0F9318DFBC273D382CDFC0043B0C47B35834EB2069A0E306A53826C49C7A69AE3442947C37ED01F55E9411146870DA50194E778CAF71A7561429D1AC02AC362FAD196CE1331BF2A00001DA290F2B136B92B576C2831717908682412462AF101C3ED3685180112D41A73BB164553F9B79CA71F0932693A630E4209BEBE7BAA7AEA295150B1B827716F47464204258F414BDB6C5FFFC42249C782494A4268F60BC5C195AE9C1EFD778CBC15AF2003B3DAB7336AF5037BFB4EED702EC887AF43EBA616414914B08493D53ED9F89EC2805EA1B40B634610B458236A2ACA1610565350234E9B23BE27166FB8ABDB441138F44E79D8541C3AAE85FC553FB884CCA95E6C84325DF29E112B6D863444A52721F5A5A6D0DB5A65564A545633CB121A927136408C16763191EB10270E6A1604B486770AB5FCCA728F659556C212F9925F28493CD3C2A60AD743830769F9B387422AC46385C88F4A10D8C43764F5200E810D20AB9A7AEB5C8B100CB751C55B301976D7BD4F0A1DE7D7CFBF0379CC6B9844B16749B8C6659824B65C2659A430914B322289B88D51324772C4A507CBAF240436AAC23950088E41973FCC487F57BD1D14321664AFC6EA2B66403C881509BE445933528A4F97C2A5B86F1CBC08816484F9432241A09E16D6B6C7068F0356505227216127AF9506250E59ADA3AB4611D7BA4A999621241A3D8C4FE0E7CBAE2492B6F44E6AFCA27F33940E3233F5A382549B9DA2C52B9BC99A8BDC1E541B274987A5BC4A272F330F725856220961C659CD9BA534716C5A113B53CD243D5C907FD6E1B2CDE69090B40314B7CA85F2185F9401FA758C3FD8AD91441A6DCB88B7350B753CC06AE5A1FBCB4DF61CAE1DFC7E60C28C7787654A068DD06821983AAED658C110BC19C2FC61E76CAA65D9C0914887A77571B3E63CD63A437028BC03DC8F69346585D023F01465E430220607948619975FAC993703CF60055D9AF28EAA1A2CE412322D11497DF22137380714B701DAE205EF308E2EB8A1B0B09ADB896BB8AB3F34F9BA2695056B7785FD51ACD043CDC1919C6B0335D7E7BDD1C43693582ED5E71D534163A48C45796B43E98BCB3DF47E075B8AE3E96A640CA659747B287C4714113DDCCBC83D37C54022CD321409BE74C331900CB17A72DC27BB6D4401D974B4E236B82F894EF5DC9A7A29091AB475D584B52D9672DDBC8D63B0BDB51554709041CC07CDEE435F39463C04BA0DC2B4C085AAC7822AA4BA50CD470A75C53A7C1318839DF4086D8A8D3510780081112453134F15601F810895B287195866FC237669F5B212C002F62B2130952B99BAC4E0AB002FA915520A715A41B1D541CB54CB7DD0291655F14FD2D0B3D802C9D6CB569FC815B69B1A0787463104A30AB34E7BD732FEEA3C8CC8764FE199947513889942B7C110482C9A1477348C3C3B491060A78B8299490E4DBABD22B054929BA77EE31922E1439D15B530A0C307E72C2F9C568622301DFA261C885A6F66399DC79E593486B11FF236B8367BF6864A1A596448FC251898A3C89CCD0B5511311826546E56B6967EE923E5733561D5A4BF940CAAC4960BF60CB769A40E396BFC370F094A00986D708AC731B420FDC11FCB071BDA0786A23F80269341AE270B8ED6844B", + "30991222B8EA47530F7C703D85BF4357F61F47615539781920EFFDF067172E32EF1BA77B21670ECA074C4B2401BB591B21CA0F4BFBA9F8BE4A26A9DE2ECEAA8303A91073C0C91205DAF6DDB17D35104969C5036BA722B176F6A3E6D92E1E5EDDAD9A6A3561F7E5338BA2B163702E297F9C6F27C5BCB7975139DFF287B739D2053BBC4307946B89DF3D9C963379B932DDBA015A6EA396E729996F7FF573A0C24040DE323E60B95B2197C89127661DB35D44588E132742B62949EA45D3E8527F0B2B71295E0943F1FA1F87D3B3EF11F840B59E2BBB10AA22B687FF23D22CDA109D5CE33F3527FEA041579793530226009D48CAE3E499FD0ECCD036D04B8DA21F939908E53F5BBBE41DBACAF3A7F9F5839D479BA0909F0DF0B2C8CD7AE8B11F160B16EBA19656744AC38D9AEE3A31E698380B3B9483E3A5F3C3B3767C519ACBB515706B1F192B16AA7B1E0B8178F28C65CAB578368DE5BD0DD5691B659293B3B212A5547E60727F69B33D3938A301572FDD931F5F71E7C647BF9CB4B3A8B294E2A17CF504319278648E59DA78F0FC5BBAD5ABC37551C30AAB853CC50DF796F308EC99D56A2348954EDAF7AF6E4D62FA6B1BB6FAC370226F47F1A91E2BC6731875C09CCBF8E635745DEF1A607F15BA774E7A1FCE8822C07916D352BF24DE6218350C5356D627411F884623496620500337654DBB8048D58DB94BCD8BF18ADFF7EAFE9DC8687156F426379FF0D57B880B8F86FD94861CF865DB231B9ADF9FCC53A7D8E5BEC45EF2EDEEAF2109F35A365C1287AC81D18EF302C9313B357870DB914E2E8300440A0C44E3940FAB6B35F1BC4BDF9B7A54EEC634897F1F715A334E553F2AEF6ECCD13966364CB942CA7C91A90EE2ED924DAD7F7A0907A56323BA787967F687E1C8BAB45976E20AE14301139E989E4257EC9F87728F4AC56A5F0588D96908FF7DD901AC4FBD8AB336EAC865377DCE7C22B4E8193F17769E1C1D6A2365D21715F014E9634834EEC80E4F6C97FDFDA6559BA2F88F81CA57A03AED25A0D818E7823BD08713E1667815A5E4776ACE6FB5658053E6DD38A01AA0AA9819802BD83E", + "6621D11567D58EAC3CDFBEB9C69DB0E7AFC4C97C252D98B4770C5F6AF98C83DB" ); yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "58A1D50BD43788B872FBEA3B765FD9CC911352CC7C4A6DF1C37B16B33EF4E58C4C94E4BCCE87E2F40B3FE6012216C49F0DD147EED2CEECE1909C626659C29363CFC9C5CCC147FA5A4C54A0755F9ACBD5EECA6C058E3BB27B5F4B762435A2F9C4C9F3F1BCCA10F49CF79AF6407ADECC839137936922E802803B906FAF2C2F61A58EA70256A8F344810CAB862A5D205D01D9454731143461FEFBB15216E3AF8E013B8AD62626A9B6BA3EC8D8E936EE95FA368FF8B65D0622DBB6EDE36B849066019A57FF0D858B6D6B3D577573688A7930440AF4DAA2EE22478FFC3230C2BFC28982B11DBB475C77561D8A1ADA11E5A79DA2ECF8519C2532B969BFED42B66B6B2052DC1D02B11640AD354AD11805D26CE1888A9B1971F8C0345AA5919B722F97FD2F13DDEDF82F275774928AC437016C7F917C67352984B0C1B9AEDC8078329E8B51DDE09FE46DD5056E0BB12C42FD7690ED529ED13EA628813D4BCF524ACE4A0C98856B0216872D7A3567392F4DD37713115A03993618E3CEA8D9B6AEFFEEBBBC27557612648BE6B3EDAD1B97CC99516E394C9A4888D5F4063F2A37A8B32C422195CB2F9E7E17D79DB17FAC28FD7EF0B327E6101B5733479FC73E4AB9EF654888715EC4C4E1FA95F1D4D6DD1BAE0AB249C371F6937C86C6CBC77BCB9A7F0B7AF45591EDCFB73903106001869B46D9894F7FB5FFF7A5079ED46CB0B596BEF936859D1E7B32820C2138B5546AFAEF00274EF86B179D796C5624143E8F500B8D9AC2EC4607088F97D74FE8183DE58C9152A1B7C510F7B00D82A0E3F8A0463D00AA168E238E0F19E6A14041624409AA4FE212D10664E6CBB0FA5D910A8494AD5054C69961444C3A34DE8BEE095F2E757F9AFF846A8AD0F6D3090A29789BDD5A59782F80CE081618A407B58C9E2AC05866AF57CFE915F261D18BFD29C7308383A716C75BFE357240A93AA410941656D62F0E1C3BE6C4487594E00838523E1B88B68A68C7BFCE22EB805C91E6E2AB3E0369EB4F077B3064B2106ECDB7FACB419631E8128B1CE21BFB51F52C2B0841160A4815E0524FEDAC9A75D014C47ECBA9580E7FE9", - "6D7A3AC0A410D5457233E862F2BC5A4ED3A5ADA47070A888AAC44599AA6A6E5A" + "22664886862835E6188D53C21FDC5EAF7849E078832E004CE79A7BBF122E6E59885608002C170077E98440039870E03FCB890D94001A98482EE6644097FB2BF39A93DA8811B951C6B905229A40BB97727EFAC92D266C4AAEC5623C17C1982A25D4859E362A030D191BD9E11D5CEB145E7482FFDC38ED17AAD859BE642072F55B4EDAFA4AC438B3DFB793A910BEA792780A801E70D2AF76283B60238DEE9A63011C343A586BA54CBB0C77CBBB3C8470C09F1A9C57A42436D3ECB89DC0CD711591FC674878A8317BB833D8DB10D217CC02883A1FBA2CFE3770F46721A7C9AC0045BE9F14487CE6992CC0CB1871CEADC3BA0627CFEBEB974B457D3B7953922CB0F5134918B006CAC669FB0B180BA00FEF56912B99A2C23B095E0A1F65F5611C879D4B519FB7E27153284725749C8D321178BB83C33AA9B547129E780B6C958E69192090FB3E2D69AF3B44A923276B4D5998A3349E5E291291B613B579800B12BE0805063755032A219916A5B9807A7A74A0A833F14F2F940465D970EFC7B7F8D93AE6D554A61085BE277DB5709AF4F1AE3F331B6C8900B24697978B7F69F1B3800B3606F23D90A683E44995F4A1451FA4322E03BA4E32120C5B6E6F8218B67A42D2A54467D672297B4F5CF51131180261276548F1ADD6C985415C15C3D00D83108BF34A6077EACCF7789865341B9594AC3C3781D15336696325C811842335AA43E2146B9176EA251ECCEC7F3E18C8E7F11CA7B09AF0CC14995515D80AB090711520D9BC8CD7353187BCD7D2BC4FD19911E11D904959617B4A30EA844E6292CDE42E46D2A013635C1C38C2D42BCFA68C928B6196B9EA75E6626DC7B17849205838B4C794511DED5B19CDB76CCFBC175F6B94E4E5CC5FC3C940C836C7F86BCAB3BAA860CFC3F1C8C088ABC684A243DCA306B27C2200AD1A31261B4C3C163B99E3022D8F79C9B4989AFDC32F5D93134FD57AE2A7B8381319E9FC2266F457CEE24440307417429AA259CF7DF5865A290404D73FB638BA6341316D8AA69FF605FD23453C34BC015B915D723815285FC200966C03CA84828A37579C86418D5433748669A56C447FCAF3F7A27F8BE433449CF232282A0FC0F55F6387EC0CDBAF615987A153", + "65BAA3F5C74319F488D378CD416C312E8B5FB189A3991741B4035E1E15B261E350004A4DA438725888AC54BBAA2C9406E303CDB2D9765A0352A22A28BF80CE51CB4234397119B3C5AAE2324BCC0FF6620605373366A474621A949B90888A12BA91FCB68CC9C42070B2AFCC54095236497583DEE7947A3258A6D33672C2B1FE8A02EA9CC34A045C91C5AD3AB72973888C46B8CC383015DC12476551BADDE250D2D84E7B06B7D5984B55A6918023C41EC9648CBC706BC61EF3C041C96822265C092DF204BFA25A9A16754B165AEE58607F2CB9BAFC05F548164C96483A846C3892A6553422E99B1D0099B946FBAA4C320D8187BA9928C574B448613B18EC7BA7AD5C4042642FD04260F5E5600E22AA69051642D0A2AC2BBF5142B69A69B4865AC9FC8B25F71B93F8CCC2C601717D85AE5267116EEA467F54656999CDB365076CEB052D4B4698B361C0B9B02B7BC10129972AC64B1CC65EE0AAB59D401AB41A245BF10F0D58393587CED798786EA87A56F48121E3CF0420BDB438A4E292CB33B6B371D8850D290C8C93627D2B428566014A82AAFF496E809BAC64538A2A52B6FFAA0852574D8A648A5CE81A17471EABF3CBE2F34B6E54C01CE079CFF4AF0CC60F820C64BA30755B20CD06420BCB9156055624599C1F8B8292A668468BE0836FC47383EB8B74E2118E918FC499C64E146276B17E5E015BA85863D9920D8A299F90CB09C178018B895CE6F0828246247CD0B9C86B4F885350CA6167E90953E9397B5EDC0A71866C087A9A8C1A6A3E895BAA78303337479AC256BAD692FC0A9ADB58C2A152A9E382B11956AE30263E74AA7BF1D79B3B98800B7C82E81A0C3AA2CBF4A8CC1D13B3ACE8B3502361ADC694E7684278164C810642771B04085122DD408228606B939550892B01A05B347B2135B5568B4E13C250BC1CD14396A3B756450BC864D7C9346CA4879178DE1A0D5DD82E09F9A938B40C37C4407DA787DC7149875C3E927BA166528054001FF103BFCFD2C1AB933C17E10F1F12779AA44207C960BCF7330D415832050713B438C0482651A5B10B850A828964EEB26196A84AF4AC2922664886862835E6188D53C21FDC5EAF7849E078832E004CE79A7BBF122E6E59885608002C170077E98440039870E03FCB890D94001A98482EE6644097FB2BF39A93DA8811B951C6B905229A40BB97727EFAC92D266C4AAEC5623C17C1982A25D4859E362A030D191BD9E11D5CEB145E7482FFDC38ED17AAD859BE642072F55B4EDAFA4AC438B3DFB793A910BEA792780A801E70D2AF76283B60238DEE9A63011C343A586BA54CBB0C77CBBB3C8470C09F1A9C57A42436D3ECB89DC0CD711591FC674878A8317BB833D8DB10D217CC02883A1FBA2CFE3770F46721A7C9AC0045BE9F14487CE6992CC0CB1871CEADC3BA0627CFEBEB974B457D3B7953922CB0F5134918B006CAC669FB0B180BA00FEF56912B99A2C23B095E0A1F65F5611C879D4B519FB7E27153284725749C8D321178BB83C33AA9B547129E780B6C958E69192090FB3E2D69AF3B44A923276B4D5998A3349E5E291291B613B579800B12BE0805063755032A219916A5B9807A7A74A0A833F14F2F940465D970EFC7B7F8D93AE6D554A61085BE277DB5709AF4F1AE3F331B6C8900B24697978B7F69F1B3800B3606F23D90A683E44995F4A1451FA4322E03BA4E32120C5B6E6F8218B67A42D2A54467D672297B4F5CF51131180261276548F1ADD6C985415C15C3D00D83108BF34A6077EACCF7789865341B9594AC3C3781D15336696325C811842335AA43E2146B9176EA251ECCEC7F3E18C8E7F11CA7B09AF0CC14995515D80AB090711520D9BC8CD7353187BCD7D2BC4FD19911E11D904959617B4A30EA844E6292CDE42E46D2A013635C1C38C2D42BCFA68C928B6196B9EA75E6626DC7B17849205838B4C794511DED5B19CDB76CCFBC175F6B94E4E5CC5FC3C940C836C7F86BCAB3BAA860CFC3F1C8C088ABC684A243DCA306B27C2200AD1A31261B4C3C163B99E3022D8F79C9B4989AFDC32F5D93134FD57AE2A7B8381319E9FC2266F457CEE24440307417429AA259CF7DF5865A290404D73FB638BA6341316D8AA69FF605FD23453C34BC015B915D723815285FC200966C03CA84828A37579C86418D5433748669A56C447FCAF3F7A27F8BE433449CF232282A0FC0F55F6387EC0CDBAF615987A1537E35FD4ECF80F07D398BD1A4F057647C17838F8427212A33DC3D3E7052AD61DB62ECC47A3A06302A8383E1A465EDCF1BF3523A84F5549859A8CA5C0905DEBA3E", + "596D8F70598FC6837434DBC18E9891D67735460FE00248E49E07EEDCD2A36C07B37ADB63AB0DD98294B799CD8CE664D09F567A7B52C2BAC89F32366101983529D97586951B9EE52A1B48B51D87F47444D6D3A0F3F5A7063B621C6152ED5FD7A1B06903CB88D2817CC000ACD3C81A6F236CF4A268FEA9388E61EFE62FCFE21D93B8D872E31AC4C84AA8F6A66C419BD9D03EBD11A00BBB3AC07DC806A32783AADDE4B41FA8743A330CA590F5E2076F738A147999D8AA983E67E8D8CB663EEC7A693CE9E48016BDE8511484EEB22232142F6778B0AC3096F14EE5C0131C966171B3CDA96F815D8A6A4668B20F65593543B19656E3C7315523E2FBF3936D050DAFF6E260CF196A2CC83D1C5A8949D1B38E331083565E8683CFB4485D256B7E5CD128FDB516745DE86E402A67DF21FABB2B64E804225ACC7D0435D83261DB47EDC234BE5497469740C2160C793E84EB061D8612093B242D0396588333F4A3CAAE8A456F7D8F29A790CF7569530EDAA4FD2A93F9CAAE4FC4C6CD1D873153351D082B3C9FDF7C644C36D168485CB8C71E96258A3750A89BC3E4EFCB2C81130D7B2CEA9A3277F3919C193B69677DC2BD290F473DE11562974D4AD9E4CA19598E63CF0442763B1A17E00E58207FF2403FBBA79B393C885BCFADAF31AE41FD124CEBCD1AFE38A05CD7B03CE692CC4984C5EC72EEDA9ED85F8575E96CB06569B938AD6E8E78316B3FD099504D1B254D8BC1379B77D61A83D47270FEA6E2455CBAE336A2AAE8FDE479FC405D2F1AD2F54ADEC49B9C2999BA2694C42F88E8AED706DDB9CFD9E9A560FEFB52ABBEA30A09128ABC1780D8099736AF4D4F208EADEA47A1700F2D8C7765C497ED9E23E3A73EA0159F4F7BFB137ED5E6239737743323CACD84E172CD0B451D7F3232BBB6A61AA267D7F5A06A285A2FEEBB13705C824AF5E760017604AB15FB2D68E21A71198B78A6A7969012403AC2DCABED2DE26D65FC5877878EB1456F9F66DC09D66F7F66C127828E1C6E92D8BBD50D2F15AA16AAE3F38759250AF9E02EBBE9DDBEB16F7523FBD8B1473F1D2A3AC7C7FF8EBE0A5D8B764B00D190", + "0F138749C455FE4615FF58200C7D4CE24FFD8709C305C53C26AA9E340E8A73EE" ); yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "7F0B3336C74E01C6D3965CFAEB2FC8E3F76A7A15289E2A71E4B29F68B961786699DA603AAC6C27346E7E2DEE36D07BD4075007654FA3A38EC2885C204B4037FC247BEC1A129BC918A7EEC0BDF69DD181918875E6335D6803D882B15119C135738D636EE0A08CACF8434E968A0F4BC510FACB6A73E5F51E82A90DF199BA40C727772F3212918E7C7FE5CA720768C4E40EFFF2C341B50036EE286C6AF559026563256DDFC5E59CD4C9641B3F6B914970544128D16430AE1C0635E498818E7032C432306FDC41EE93E163867FB5FBE6FC35729FC6277D10A83ABF16190CE4450C1558FBC807F578B2CFDB10987E1CDE0D1417475D191825A4C31A65961E2C5894BE974AF20757A20D00ECA9F6CBDA704BAC3B94A1E8212D05DE26F33F26A1EA3F47E498BF0101A517F91069977425850847AE8B2D1F832C0987E8C44FBA4A57D773E85D8195CB92DE2FD8D6FCCA20EE700001295AE314C2ECF75CD90B6EDC2B0D206A00CFBB20AF2502D3FA64A1AEF7EBF982F9CF6ECEF15C83ECEAD7D0A35680E4C3984AE4A66F45910256932BAF2BC39C1DEB6F3CF1B4F96CB631AB9F2077C17EF6EC801044DB8B69AEB3DF1B983C3A473856994AEA20FFB0E004255E7A069217A44C42C8637C7EC8D921C8A37ED0C49515874ADF22650E64C569BABDAF493444FCDAF7F2CA4BF456ECB017A74F1C8BA79E1F5FC8E3F37472C4FC1AE1DCA976D418C775E029BE5C1781D4982C29AD8B4A077D05932700D821192066BC987445B164CDA9111954CA18FD4AC9E19E97A7193054D8724A8FE449997F157D4AE8F5C987F34E849EBA3A8055C945B6423C915544C4C15B9D3B7AB4698DAA792D62DEED7DD7FDDC73AC378CCBDC2479A0B7F7616405F23A9B98BAC787282A2812D0B4E27C1230FBA11D765DE5766FE51047E411DD9A47B4C762F013B90FAF727A70BEF3E4699B0991C36A0B86A071DE39AE7CCD7ACDE7C016BA396EFCB41BE92B9935FA5C6A154CA799D3D6DF188FA33DFCA6092B05F1F24B05D5890523E538F16BCAF6E64DF926BB26C06D1E2DAF5E597A0EB06F9E6357F3828F66262D530BF09C24EE", - "B532BF7A54A929B96481284CCD33558EBAAF080763A327A2F1EA81BE52A0B171" + "2F29C94A9C9351A321F262343BB7777A8B46CAB624E3F4BCB5704258B462F9EA711146AB34E748A1F08D000249FD73655CE748552909B3AA5546B54A72EA5980B957636B05EB14AA616C1B8B5AA78A5279A46B23B513132AFB85C963409E40CEFCB74F71C75298A670F7C0632C302444C7CE74F643E27B03AF93A76490374632BBFAD0C2AC84BA2BE4579C32237EC701177312B68458AF3B039F431C2658BD54041398D94F39848199C8763A2AB170C421853C7FA19C0A9ED89B665B13CE3553F6C8BA4C745327B3B10B0CABBEEC2D2C11277F359E86547D1E901F0BC44126F3242850AA7A3A00E4FB2923049205EAC160C24CA1B32280B0C0CB788857A54D223548C7505A5DCC5D29D7189595BB5CC070AA23149D376AADD75DE42A611E157C00B797735A3FEA3B59E0EC46E58A0FCB48606D033CF8D75E6592CC89448732D78B30B754F3AB7066F85C57F45E7FC035A7F08496225171373818F765FC02817BAB6FAE432CF0EC38C0779ACE7231041B8047869227DC01202419B83A7B8B87A74468036D9A2CF0C5892EE9CC85F89A32039A0D3A219D0365C600125BCC15CF607C737732D7AB5A27367ACA464571B0839DF379A79880F5B7BFF1FCC4AB69A047166800204C733B3A72FC566C2C280788CFE36A1FA9F63189B0382E683A4ED417D755A20B9895652C1E26B628BF19915D06B8320AA997531E298926F0F268C97C936B1896CC51050411338AC8088CF4A333C847384C9DC766CDB1BA531199C08B0266F1D24331E941224B2617EA9D1EAC33024939041007B5F840100B7E5437306D2A72A3B439E3D355817C78EF28332123797466A0F873A33AA76BC0B42E33C109F3EC8733785C2D03B4E64C3A5A1988C1C4947142CAE75965A610AF5D9849D6056DD9A45E8A8705C04306850B13FA295D36164F486B3440F62951F79BBA12747497C31167BE94D1A9D424373B4B377AE18299C85EE375B0312004D71C107E3ABB12CCA8AA50935ED1AA64477D866BA940C6441D44B006D22AF62960F62478BF978222DCB90E454CCD33BD9AE06F3EB34F5B576C4C9146A4514DD33258A0B6562A5EBC6A8FC1B5F15C9CDDF7EE64417FB722AE52086868BC807BF19B472AF32A", + "D01B6395019BCB1318A6670DBA709588C0A734256B3CCB44E6F2A002B91B9DFBC68E18C1957B3EE8C5464C00215E41907C7B6C1E0C20F62B294E8686627CA3181AA1377C25B5F79355B31BC0C14776621A014302DB2119F9BA4F0AD653F9B4AD562BB14760802AEC8B10348403289C9ADA8C1F39A4CBDA9648589ECFD09DE6AA0BE97AA8F0A13644F23D8E505E1076B415DC078B659E63A50D04A53E680980B2E90241435AA0810CC76016F0010E7CF8B2A9A0B1F0A75CC068CAFB4A5AFCD74CBADA6456D83A4D460D978025A89B379F2294D61BBF0A344611635335CC05DD24BC800C48845930F90538C5854D9862B059F952A25B3D2D6BB3E70141EEA769BDB31F42467C16E6509DF8A0A24477916A28B623A555E47079C61EB7B7A5431085AE7457F696812CC49D0DB242FB42B3A58A6B405289974BC34DF24C8E09C63BB81F109468B112668CBB408AA13AA1F2B4EB79A419ACC2B3C05807679E8EC60951B266D621319EBC289F8709E903478D150448FB00B142BEAC93BADAB7703D5CC4ECD78A05121B4182501CE62E4A3BBA65CA6C57156622CB624F844172B0CD3B376E1E008A25E0A8BF982927E154C55A82EC276DA312C2721570F835C51C131E7A011D26F52A90E5BAB0B813EA41C7BB3BC7FAC789775286B1D115CBB865BF96324FA99A3180B7D1A8B7C2B539411302EA62020611359659C2AE0062B1C52C83B7B94A831EC9036A79025689A70C14C44BF590A914A3325392827F6820B96961E7CB2E88B56A1F706C6027A18BD3AB8998124D8C73251A8CCAB2771A630BA448318562061755B6F271063100C4DF788030113F5A8768EEAC11B31A1F0A81C5D14002242409F35B2725AA68FC4087A22321F122B672E101052C3EE59571A9B71C17976C3220C070C0A4641B73B007CD51A5561BF0AC24B58A1DE1443EB38B794822C4148843746C44E6458FC92F1BF4289E3178CBA74521D792DD297D93D15FED878F9021B8F1DAB90D6259C354CC9B4A383A58800C42547F9A13A4F809F5C05EED58C6C98A878FF432ADBAAE218A9C283CBF45D527ECF8A4B867ACD7576957D1C12F29C94A9C9351A321F262343BB7777A8B46CAB624E3F4BCB5704258B462F9EA711146AB34E748A1F08D000249FD73655CE748552909B3AA5546B54A72EA5980B957636B05EB14AA616C1B8B5AA78A5279A46B23B513132AFB85C963409E40CEFCB74F71C75298A670F7C0632C302444C7CE74F643E27B03AF93A76490374632BBFAD0C2AC84BA2BE4579C32237EC701177312B68458AF3B039F431C2658BD54041398D94F39848199C8763A2AB170C421853C7FA19C0A9ED89B665B13CE3553F6C8BA4C745327B3B10B0CABBEEC2D2C11277F359E86547D1E901F0BC44126F3242850AA7A3A00E4FB2923049205EAC160C24CA1B32280B0C0CB788857A54D223548C7505A5DCC5D29D7189595BB5CC070AA23149D376AADD75DE42A611E157C00B797735A3FEA3B59E0EC46E58A0FCB48606D033CF8D75E6592CC89448732D78B30B754F3AB7066F85C57F45E7FC035A7F08496225171373818F765FC02817BAB6FAE432CF0EC38C0779ACE7231041B8047869227DC01202419B83A7B8B87A74468036D9A2CF0C5892EE9CC85F89A32039A0D3A219D0365C600125BCC15CF607C737732D7AB5A27367ACA464571B0839DF379A79880F5B7BFF1FCC4AB69A047166800204C733B3A72FC566C2C280788CFE36A1FA9F63189B0382E683A4ED417D755A20B9895652C1E26B628BF19915D06B8320AA997531E298926F0F268C97C936B1896CC51050411338AC8088CF4A333C847384C9DC766CDB1BA531199C08B0266F1D24331E941224B2617EA9D1EAC33024939041007B5F840100B7E5437306D2A72A3B439E3D355817C78EF28332123797466A0F873A33AA76BC0B42E33C109F3EC8733785C2D03B4E64C3A5A1988C1C4947142CAE75965A610AF5D9849D6056DD9A45E8A8705C04306850B13FA295D36164F486B3440F62951F79BBA12747497C31167BE94D1A9D424373B4B377AE18299C85EE375B0312004D71C107E3ABB12CCA8AA50935ED1AA64477D866BA940C6441D44B006D22AF62960F62478BF978222DCB90E454CCD33BD9AE06F3EB34F5B576C4C9146A4514DD33258A0B6562A5EBC6A8FC1B5F15C9CDDF7EE64417FB722AE52086868BC807BF19B472AF32AE511FAA0E231976722B8C8DA3A15116AB0407F3C7209D421D97969800A933F9742B5A904C6C1477F268EDD8106D88618B002F3A2D0FBB72682CD37B51F9BEC47", + "3856C757D2A5FCCD231A1669ECE3832AF80E5AE832F3B1314ABFF54CDBB94ECBE156D3E93FC4705C46D0E662468EFFBB514DEAA24C384DF4F0BB2B3442D6C67926B5D4EBC6DE170AE0A420EF7319F3A52B6F7726CD47F743B86CB5AE06610FE485932D9B6EA9CDE8023A978DBD0DB5C5DD30AEC898A042C825F0143A32DE320EA97CC36B1625D652342F716F61446EE2355435A9FC043DCD68C6BA0C15AF81A50EE394CFAF9558C6247A6E83826FB48ACAA574F26FF137676348EF1FD80EACE7A20EF6A5150CA1F094A9C31794E3C20CE6CFA71AAC394072432CB4442C6BC7D9AACDF493949CB4E9F33B1946ACFAB8ED5C7D978E43DF907848996F9CDF2CEAEDCF4CFFDA1F18AB30EE1F68F505B4C3A1CCFAF492944506101FD2432667B4D1DBA381C3401BCEB2FCD93CEE7D506E63D97081D4721A453BB96009CD58122AA3B2BADC079EC0358C6C8051D58DBBAE2DB9EA7A28668A2B2FB35D90A542212C7ED4C149416B5CA79B9CCA8B608062A0F3E8E6801D86C8295BD1BA1A078935ACEF1C9DC52F126E83B79927A361167C4DA101FE8C42C20E3AD167D28A73E22093E12EABC39A1C0B3A295C3049104E1E9772D3A4A76D829D9BAB22958C14C301488287936EADE7FCBF43744E71B35A23DF0BD07D2D89C468CE3F8E1BE589B202D74B2D4DECC09FB919EFEA56166CF385C40E113FFFC570178044ABADE35172614DEDF9FA93D91AD8218655C8519D5871986C16320D845D5A5231DC1E04335A26AAD213341A5946680FE9F22CC7BBEB660EEEC1CE9BBC92D497A9ACB21642F9CB52D19AC26B774FCF8817350E301E77CD294ADDA779672597BAD395F4913A45E0346A41C14C0A473928F89B92A7075B63E7929E1FD45077D0401356705DD9B6B75D5044605017A9139B19559DB18C3B931DD71A532C861AF40D18D15C63531F1545D337BA1A30841CDA6AB7D6EAFAA4798E4E6980F7718EAE92775DD8460569B05440DCE3789E6D743E695B5B1BAB0C9DE9C666C1595BBEDF69E80445DD53DBAEBEA126E45479CD6472D5F97840475EB1E52F7984ED651C07B82D584A07D9099C353DDA", + "ACB0CD384DA7C8A0E5187025297286AD154E9E37448D9D0E798BAE24FA7A6727" ); yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "35F0EFC059699AD0E32C2B349A262661CEBE7DC3AFDAE847B3F30ABC14638B9EB3072F850CC0B7F71672441C12D27A355955CACFAA404C18A2550872CD6458CAFECC77B77E403F05F1E52585D4EF03B3918585C1FA53A154CC120457CE3A2A9DC472F160AE5840222A301F44D5E34B671D664E10FC71108F1A3934704432C00F4E1C244882938FEA598C64BC12234961A92357F4237C3EEE9517C50B4998049345B28D28E434EB47386185439A39C9E8D1BC0265276DA6C2DE621A45D2BCE109612785913DF508198A88171DFC4582BCDFCE3232EFE2D22633AF0EE70A198B72EC0F7D5ECECDEEBEB678273F459079E810BF95D1510FACE9C27A352AFC513EA369A770E49ECA43C286B460FECE7B0DFEFE74F32FBD0BEFCA954130A15DBFC4E714DE083E38FEA4FB7BAB28FF7034A97C6B50F0BD77C76B039302D5A0376022A7D3952E290054AAB9DBB9E196874BE23E9FD7B9708AABF38B22B41024D37AF2C6C38ED12B4196ED79B99CF36244A84F7AB94111016127837CC21842C1AB14781D318519E4C05CA5BAAF7A7332AE26AD67F6298A295046C432D52785A768C4FDEF981974C299A19CAEC9AB1ACEF3B911A3653EF5DA6D9D15F0799A7F08CCE77629BA818341037EDAE829DEDB6B905A484A5916AC78AD0654B506950DE6FEE550056AABC63764F996FCFF57A66B44153AA02613D74003ED5AD2216BA38B951D21FBAE7CBB5C422559DF6CCE9B8F38F2BE909D55851E4CE80A97E5FB83FAF63016B810755507A88297FEDF0450E13EB961B26F1BB6C885BF39DADA5652FCF227645A74C44AF060F2B219D60B2BC536732CB6471138EFC377EE6421B529FAFE5E49F44B69376E49429132F21313F6706D7F7030BD7049F199798F78B727895AAAB38B9FCDC7AA70D80475A9A40ED9F4023DB1ADD41DC406333238C7C81361A0F704B0F9C295416F6F06CDA2154A531424A51D5C24EACDB51F21C96A0183C4FB177FF4BFC48DDAB3783EC041E920829C97B3A37DA7B7F3C78D29A46762882665203761AC906E9FBC1E788FA5803F05F9E16642372DC463E79DF833C72C510844EA3BB5", - "707365FDAD892AD8725A50D5DBCE635DC80F6D4D6B5FF28CEE1FE361C067BB32" + "21E3A32F34C0D26933A251CF7AC2C8588903E4E8AAB2956AED328687D59F3B0179B0F008B9D82E30D62F979891E077661FB02540535B65B8038EF647AA977B7EC28E737351D871A128D939162A8B06B596CCB112C9477134D00FABEC425C063FDAB7092940A02D56B677C7B5C6791352871B72B8B7D1539525A46A05318D1451BDD8445D93C7A42108109417052BC6CB108896AE0837EF0337AD349ED682578CD083BA7125EE909BF59ABD2515875494AB1D25A2164CBD6B346A8E057AAD77C3A524086801CE61772197B7AD01D18B12834ECF18394F689A74CA4192A86D68F112300CAB592B2C0D2488C2C55392DC4FDAE417AF076FD068424F16CDFBD36588E4AA96955D6061960ABA9BF9C588AEB2203F3083D9B101AFE366B26AC896D78951726B4143AB39725CAB14CDFAC93A4FB2BABAD835DF36118C00002E2634D954A871264876B8B46549367EE14EFD78037DCA255AD5463C83A5623544144699F92420B5891DE80280B7590E556AA87EEC3AD010261852A3F437C7B40455E09BCD9C514126281EA31B43DDD3C2E1D67A845A87B3A38E7DC41BE5C32C28F2C4D5F17D839773730717377AB992710362CA38652C31B034532A1C393933A11A8B4D6BC17A35B9B0B9A4621170B0106134C045947651A121E3455A79720CFCAB6A725823503442F068C9F5019FA1A69C763B07A66FB30B45F95B796B802E09718381D96C28D487A69C55FA602E48823F8F49A9ED69234A341D399403623C65C4507AA83A33AB10B1830B93F270574EE6146BF75A82731B8A8B83C823C514969623004CF4ABA8AE086F949926174B40EBB0CC6EBA9382D61F2FD01BCAC78E80EB1136386B9DB54003964134873C5A8870015C0AFC364CFBB52429243AB82242E1F990E6E285A20C3352374BE0035124702EDE831314DA724900BE6A86811FA7A488F6695D4808DD0081D0648D2551355952B31447721E915ACB93AB8AA4B394130EDDE1C63E9B4440B21E5BA572D4321A69525A698865BE90B983F0118DF62769C78521049DBF2B2953F3631DA706114A7641DC11D95004D827BC8548A720A2B05F0757A1858E6FA5EF180041D7A2F738F02464C7B7408302EC5C501E0226552EE6DB83", + "51A822E5747B76120A780B2F0476232B7B6A621C7256D001C1143569A2ACED1B5C1D43B171C49AA4D0423885BA985738CA8710F2AB9463410D18D936B064443C1C7535BB08C00A2CBEF22E5995224084CCE04460950C3252D948A732B52F8A174A70C35C829223E9854415212F724A481882A7368197BB0DA8560C6A92C455022145EA0DD7292194E35371BA31F9C234A8D9AE62FC2D004D4CA4A5A5E82C892094BB5E27BB749C8AB4AB655E175D0090319CB620EF5BA883F66DAB93789C74C8AB820000CC472D57A33BB98D0467CC0DF7153D2C44E490111AC4C97900AEFE9B7CACE43BCFE622E08AB7CB567BE17A98083934CD134738585547583CBF2281C2D37F2BB34F7878B91AC4629060AA0C1B7E1F891B166310035625254893FAD88CAE845049EA95C8910F6039A91A31ACFE006ECE2466D0F989B89297FDD65066DC31DFAA6A43091316581A60B68F04E347784C2B3BB1723E9B6C8C9C74907421F6D0A98E936432086E51A5708AD237DB0247D48B724AD44834628DA4781803584242D8871248C26058A20E855BA2793D8AAAB743F065ECD84D529531D64A775B62A4FDA65DF4FA7E02D91E85036D8F328B002DA02D1823DDA830550578B5CC0B04B3CF5BA48C3FA46BC5D8126932890A690925A66423E793B5AAAEAB58690963B08B10A7A892CC6AE094CB27704ED1C673EC4845715FF9639375E92BDAA4BE12517AACC3B9441971FA0038371297799B99CAD9C0E303BE39938CED9BB1F23CB9B77928351636B961280C626CF512477E1046C907C13D214172E0986ED0C20B70A9CE03181F00A886B5CC72E09ED70B95E0CA154D3498795485A4319D02459DDEB7B08F38C3B3A545B11A59217283DF46219F722641759D7C8565F163C27EBC61114434B5472C1F66929843BAF2765DC328614CCC6EAAAB558A0AAB5F6A3CAAC17789E523B7BA389DF92D465C403290A626620A819C1AF3528DA871612EBC1E1FDA68AA312E13934F36CB42F6353F798481B77762BB9600EAD4825D2110046522B5CC1894982E5A254AD6F97BDF186060284A6425AB1DA53756296892A1733CB95521E3A32F34C0D26933A251CF7AC2C8588903E4E8AAB2956AED328687D59F3B0179B0F008B9D82E30D62F979891E077661FB02540535B65B8038EF647AA977B7EC28E737351D871A128D939162A8B06B596CCB112C9477134D00FABEC425C063FDAB7092940A02D56B677C7B5C6791352871B72B8B7D1539525A46A05318D1451BDD8445D93C7A42108109417052BC6CB108896AE0837EF0337AD349ED682578CD083BA7125EE909BF59ABD2515875494AB1D25A2164CBD6B346A8E057AAD77C3A524086801CE61772197B7AD01D18B12834ECF18394F689A74CA4192A86D68F112300CAB592B2C0D2488C2C55392DC4FDAE417AF076FD068424F16CDFBD36588E4AA96955D6061960ABA9BF9C588AEB2203F3083D9B101AFE366B26AC896D78951726B4143AB39725CAB14CDFAC93A4FB2BABAD835DF36118C00002E2634D954A871264876B8B46549367EE14EFD78037DCA255AD5463C83A5623544144699F92420B5891DE80280B7590E556AA87EEC3AD010261852A3F437C7B40455E09BCD9C514126281EA31B43DDD3C2E1D67A845A87B3A38E7DC41BE5C32C28F2C4D5F17D839773730717377AB992710362CA38652C31B034532A1C393933A11A8B4D6BC17A35B9B0B9A4621170B0106134C045947651A121E3455A79720CFCAB6A725823503442F068C9F5019FA1A69C763B07A66FB30B45F95B796B802E09718381D96C28D487A69C55FA602E48823F8F49A9ED69234A341D399403623C65C4507AA83A33AB10B1830B93F270574EE6146BF75A82731B8A8B83C823C514969623004CF4ABA8AE086F949926174B40EBB0CC6EBA9382D61F2FD01BCAC78E80EB1136386B9DB54003964134873C5A8870015C0AFC364CFBB52429243AB82242E1F990E6E285A20C3352374BE0035124702EDE831314DA724900BE6A86811FA7A488F6695D4808DD0081D0648D2551355952B31447721E915ACB93AB8AA4B394130EDDE1C63E9B4440B21E5BA572D4321A69525A698865BE90B983F0118DF62769C78521049DBF2B2953F3631DA706114A7641DC11D95004D827BC8548A720A2B05F0757A1858E6FA5EF180041D7A2F738F02464C7B7408302EC5C501E0226552EE6DB8368E20D6B8B724847EE33153F8A80C0C1E6C1EF48CC62258A9C317F45CEFE99731D01927CE0920C048F5700432F3C5C7EF9AEAFF97BCDDBCCB14C362C701F896F", + "768C849DD542135E428DA8406B93A10BB55C8A062A1E500E8B902FD6275557F3E29395112F7581F7826333A4FFD3D49F660B8AAA4CE0DD38006671BF3877383F8056684A3C64B356029122643ECA9BAFD86CF4F82A609588A4ECF8AAE1B541089FB6FB147E7C54E58EB9CA8809F1702729DCDE7628C948BCB4855E55D425893DF2815A016832FFBFDE9C0DE95B2B0E2720E331FF9F92474213501D2B8D80002ABA34609C08B5B0681B1D2668783005E75BF224939B24FC5F5AE399FCC19B9688C06F1FB98E4A78A5C41CD14F5023992CA8EAD1B83BBCB49FA51E1B269495F5D5FB4A6692319FF09AE80C0FBF959B77624A1753729B0760F0BFF8C7B12922E7872B3EAD813E68251014CE38C983EA6FDB01BBF6CE94343966467A56495E61A2F793BE805AA54544D6447A7310645311FC1A8233E3EC1228F4741182055A58162D381912CC5F7DA0E544EC448414E8AF3F45937EAC1646DFE90B13D5A8E50B25F692526B886F41E40A74B9D139B64A53AD73987B0B7105792C8E17CA5F4C8F46C976B7069C4BDD1F97B41F7CD4A97903882FD137B406EA0E1DBE67BF21F6437893948BFEA806A390237F59D573C78FA0472497B1B0A2E343AD0ADD3DAEA44A655EC1096A77BF7FD422BE04E56BEB8E41403011FE6B92C848283933D68E444EF6E547D568B858F108F17C3EFBF71102ED89E4F3335A5C76951C60325389C37A972D2325DA3A048203DA2CB7E2929C548007B8A9C68517AF654FDC851DA9DD2EE53993795E48095935BC6601CA47BA8FD3B06B63559E10CB42BF1C4499CC9B8F13B93639478A5C424F607B0EDCD1AE0A2FB2FA77B923B1DA1793A2F71EC55FD58F4615D73D86F385FC5D96B19F1A53A8C5158E286DAE4D1A1EB82A0044AD4C5D051F94A0609E97312E83B0AE7D2830D3C3E12E939DE17BBF3AA7B455994A85B2578BB73E611A53A805641DDF9567C65432194C03D7A362E9052E932287DF0BE93F48DC7FAA6ED702D8960D6B6A71421FA676B15452E3C897D06A33A0CD049B0901C5613385D889857499BC873353BE56FE55E4F31F010B2F251ADF948F97A754E994", + "AEDEB99B87C330FE324A79E9AB6814AF48E6B028136A0464B15350FD91220A8A" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "54F533124924D97239405178EF508707A7B735513873A50AFA0649A54C1EB96A7A8A1A5952727304F7A2A5F8690AABBABE4A5C2C02389CA299F23B655A038C24585E8916C3B126021C137D4F9C823DF346650B940DD956047650C5D606E7827C1001355A3087D4B28D3D8B6BF9B508DEBB8F59F517322107EBF89B23536450F13AD54A169A643A2BD72D701407DA1777F26B71FD0376540BAF962705127C30C6D28FA584A1B07158E04B0C5A603776D6AC77F99435EC17F55803208BB0CE30B998A615F2D4669BDA329208A35174A04B91A28330385D609F22185DF20CBAB9C520EC9279B41207D8263A8DF366989216B0971243ECA22245C60197471EBCCD96B73E4308B8C9E37203D15D228395423BA3EB63756536B913F4B5637C6A566C1A2D96B94960B5ED85CAA9CA099B6264BE515A46B85D7E3216B9F97AD917AD3FB59422B093B4160C2BCA5AAB1B8A6B02C523E574648588F511CB5698342144472A968250F9995AFAA655DA57A13A9B95F8376F05A336D6A58B388DBE8052C4C3BEBB4BA8937211DF961DB1921203497200243231F09D88CB9130BA1E2D561EF9F266A4C18AB7497E1DF1266BE6583A4089DC1C8AD97081E1A95DC5D4141184CB7A5491954105F8F42E23E59618669040F569D9B1105D027DD054A810CCBE1D392B06209A1219B775C10A6A5B43F8444A7C217181DC3915811DC5C2C7E059182E39A8FA4635F3867BF962479F71A705011D3862A038C0AEE9F2540F34C91B61BBAE1CC4E0B714EECB39F3E88049D9180A542F830C0855722B4ADC1185A037976C298E945120FA2E9D440F1F0AA783D67EF53AAB4311552387A9AA2A2BDA892FDF6A1EF8CC11E8674D765B9359B15CAEC31205E502FE2A446968A397DB273E6C3A9F9C9CD5F0C90478597DFB3451D0389B307028B057BADCB6751C5FAF4A9AAB94850AB720BF9112A8D40DA0F30BF094BA85842BA313BB1670C2EB157198566DF4435415FC681F9ABC7B0189A08B771836BCB76B8280D191D9F080F391A0928C21B9993333AA3C67E9C2E412942A204186A124BB016B27359FF64378BA944818084EC2A764C79EBF4243683A2B216661BF242E56F8F2295399B0A1B0149FAD31AE40", + "B86B90057B5871C81C77E4554A5BAE897377AFA99A49EB94D0EC723E526B5815BD73E1BF4DA14A6ED130D8A6CF55809B348CCF94E2A6B0A8CB84E046EE72C23DB47BF3566848813065BC2C91C99A47A67E0837A842C94296428A396CC556E1446D7C58B76B831B65B63D9749997A08DD0897DFA8B36923C366431353213CC4C18D3B963FF0637323169B64D5B22818405753B5E5A12C15346E8D554D0509BE3F2C4CC06262009451BB3B5B9FF45D2EB84A6402BC75395AE93338D33B6BAFC301C424CB1FABAC82C08192B0A4615288E2F8364C79B83663CEB609AE2A7559343C48B3A95574A3638B8C1AA5E4134885CA881775437A05AB25943EA75D3BFAA2EC993C74574365761BF409C15EA64833720EDE1146DEC322FFEC5186BA71392AAC3454C93C5526D204B199108CC1E321AF3833244C8FC0C8CA802CA31E1A587848BE1247B260186F5F7127416B950DCA863AFC89109A379E863A8673BC5FCB632834C99766CAFF332B9781C6FF65BFC2581A3816295628846D926396EAC04A667A58580B4CB416D13500CDF48B983054BFE49063C3B202AC40AD79319CE606BA7901A6A684145CB944E71FD0D2084AE300EA45BBFE6C5B862A07F85BCE378418388365D119B9D8904A10B7C2D19192D24AB3511233B3AC2B32E011D959BB4F8C73D6CAA12AFB869D0571696609966BB5346C0888C6B0A2288591E6B5C5E7828C26AAB3726DE9E17088F10A9433997C498CA383270321CDFC047305240321B8ACCED733BFF52740147E58E516A10A89F518C0EEF87B57C32472D3ABEA4AA5435C5F97D73936D5A8A868865E53221C703751BB616CB73CED8668AAC5053D06BF277602B90C4DEB643C556A80A3400458901BE121598339BD9AB65C732C1A98FB66DB81A29DBC345A4B8F5A672A7047B8C98062B4C025AC3526D0C3416C91A7C4A6A231D8687E9880110308705183DDCB9352C1B7F3C98FF0082C01F1BD71552A1E7A6C0A77B40AC603B27BB8020A668773583E9C2048BA337E4A2200C2049FDA2AEA23260E2272FA541D93AA43E022BACDC618F022397300C3050CBBD393530886B554F533124924D97239405178EF508707A7B735513873A50AFA0649A54C1EB96A7A8A1A5952727304F7A2A5F8690AABBABE4A5C2C02389CA299F23B655A038C24585E8916C3B126021C137D4F9C823DF346650B940DD956047650C5D606E7827C1001355A3087D4B28D3D8B6BF9B508DEBB8F59F517322107EBF89B23536450F13AD54A169A643A2BD72D701407DA1777F26B71FD0376540BAF962705127C30C6D28FA584A1B07158E04B0C5A603776D6AC77F99435EC17F55803208BB0CE30B998A615F2D4669BDA329208A35174A04B91A28330385D609F22185DF20CBAB9C520EC9279B41207D8263A8DF366989216B0971243ECA22245C60197471EBCCD96B73E4308B8C9E37203D15D228395423BA3EB63756536B913F4B5637C6A566C1A2D96B94960B5ED85CAA9CA099B6264BE515A46B85D7E3216B9F97AD917AD3FB59422B093B4160C2BCA5AAB1B8A6B02C523E574648588F511CB5698342144472A968250F9995AFAA655DA57A13A9B95F8376F05A336D6A58B388DBE8052C4C3BEBB4BA8937211DF961DB1921203497200243231F09D88CB9130BA1E2D561EF9F266A4C18AB7497E1DF1266BE6583A4089DC1C8AD97081E1A95DC5D4141184CB7A5491954105F8F42E23E59618669040F569D9B1105D027DD054A810CCBE1D392B06209A1219B775C10A6A5B43F8444A7C217181DC3915811DC5C2C7E059182E39A8FA4635F3867BF962479F71A705011D3862A038C0AEE9F2540F34C91B61BBAE1CC4E0B714EECB39F3E88049D9180A542F830C0855722B4ADC1185A037976C298E945120FA2E9D440F1F0AA783D67EF53AAB4311552387A9AA2A2BDA892FDF6A1EF8CC11E8674D765B9359B15CAEC31205E502FE2A446968A397DB273E6C3A9F9C9CD5F0C90478597DFB3451D0389B307028B057BADCB6751C5FAF4A9AAB94850AB720BF9112A8D40DA0F30BF094BA85842BA313BB1670C2EB157198566DF4435415FC681F9ABC7B0189A08B771836BCB76B8280D191D9F080F391A0928C21B9993333AA3C67E9C2E412942A204186A124BB016B27359FF64378BA944818084EC2A764C79EBF4243683A2B216661BF242E56F8F2295399B0A1B0149FAD31AE408EE623755E05379EFC338DF128DC1EFDD786FFA4450DE832547AF7A83836D8C7692E3C7B26B9695F3A7AF331C70E24D80142D4BBC6A941FE4DB07ED38E7B6006", + "659D3ECEC912EA365B95A68E368FCAD3A2CE9E5B6032687651ECD4DD8A32840559CF71364852EEC28540E55674690C540507A3781BAFA7BFD7207D4039F3C02A612BA8EC09CE4921E180DAE0F9603959AC2D578958E61F1C46A4C19DFF316FD1DCDE63D29811B4A60136E015208F322B487A47325707A38F4D11863252A9A4C82B94198FB56A4356CAB954CD4C4685514CA69ABB61D9DF45540D194DD8B673300E13C55455207129742E8B1E9667290590F7272B984B489D2F2DB671DD02FB1F499F47A40DBDF33DB8107794FB68522A5F979762E9BA687882E2C4D5AAB3B83CC513518AFC6A9418B1B435FBC18DB182A6A9674AAF9C683C2B2450892A142DD3C2C1391F77F8A57DC79510973FB5654F379BC7F3C37C6A5B203C4172D110A9975D71A5873736A44033F67B007B571A970EAF8369327B50CFEE57A2815AAD5DEAD72A65522D4815EB5BFE72B033160B0CBDE31930A5DB1506CA17F91F0168D64246072D2A5A3042E3D0BD3C625F798C40502CF528A6763EB25800832719682631E3D4A000C511CCD99D3E3C905CEF5004791617D13586B74BE7830652F363A8146B6888DB5E78704319F3A8A0B8BD8209023E22D5C4628ACE2982A20AE1001AD5A6363FC3B34F42B91558A18754FDE4CD4A3858D37341AB956626D8667E139022347171B01AAE07639E0E1C8E32EED8F9CE6D030E8740F907BF73C25A2BA8E9654FDA35D26E3832545832A58E2838EFD798283C1F719D89426D8FBBFC440D8C29DBEFC315B5BA1592139660A5DC2B4CCE72A9A03B3007B0DAFF89389C6620800635EA00DB108AD9D25A94B13A05732E591C140121B636C5D1821E8D4E5139708670F8BBBECFCFF023C0950060730D0BA0D893168A8EAE3629507D8C587373745A22DEE52F670445EA770FF27C857914DCE69C7B57FE9C8964830B39644B5E485A538F0289A7D364CF80296CB36DD23893F6D29B04B0EC0F04F6758A5521C3E5FA03D0F415E53C5D94466B2C655605B2DDCF1286DBF6360A4F6D8FF6AD4031F04E8A46632149D1CA458DA6453AD3DD09069A1ADFE61DE1F8B86B24F45414B16759", + "D2354A942E97CFF7B5F79E6DAC7A9B178E61F889241228B94AAB2529ADEA11A1" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "62623E4E59A01A27B1526C594A0894863610F757151C847410A5AF63E95D91B925CA1791EA788171A4940BE89E5F6A50D554ABB33282F057AA1630359B80AFC958B54C612902618197B6CDFA0C6720F36E070824AD372C499895985111C756739AA8ADD2C21940920E4D3379362A16BDB20E22A6BB26B079845BCDF32A20646B480D6C9ECB871CAF0A38F98662D3A9C89E8ACC78842F9C2C76AA79840E5491AF6428409271E6349CAB281692127B3985C547C009DA497D4F4424DD8109D52A476D440E457762C664683E8364C26C0EBBC827B7967207690C8AF5BA38F4215D71652146434A2B42CD61804D77BC61BAAD539124AB6B414341A8677A8DF0A9666E26BFB3300204194E24F350BEE636575C069272BB6FBB34A5433D6024BA6643B02625C41F055FC049BAE48A7D754681829A852C802F53D34E6BECA36852CF62C02D3D4A9D92A1856195A0C6F6727EC3291FC8CFEF7BA3838496FBF89815B32CB55C4DDF075322377AFFE4C1C6739130015D53E9272CE826C63252F032059286391164B950F921BFF53ECF5767F0B6A5A2C2724FD47F378261D5324380646237355276A0291A0A085389C210F5A5A9380322D2BD8C97ACA6DA7C326A8F765C054BE323395AB9383B7847C741E6EB1FA52C5E78D3856ADA3F19DB9C5AB914A71A88FC049445C3241050BB65FBAFA969C1B5E47C3E988D9CB022836780313A0BD728AB51627FB8D478E2C62163F996E14A0CD52859FE32B015129EC6581742A6C48B95953E70CCB73299CE847ACA77609789AB6496023491838CC9C0B321CFA8DC29655A86ADF8A149BC390959776534726134016C9B1B562C2EAFFCA6C9A53546FC7DA2C222E9545AE6C79167706073C0BF41CA0A8FF18C2ED1C4955A282A79C57E71097E67CB8A930ECEE0037E4BA749FBAC51B06890736CDD86184A08528C308ED659477BB721AF5CAD9D7477D9EA7FDBDC558CD455EF4B07AC746648A384794AA1BE7B22B9A507B1DB6A6DA96CC6146471F22F55D7C0FCC106BE7C5B30E634E381873188A46561981CB972B981C51CF3C49B2961B795AE260CAA1AE67D03717EC3A23819F5FE2CFFEA19119C220C5832EB7FAFBF2279D277A8A7D1030FD1F358", + "3B51977CF371CBB75DA68C26934237638C1F28CA097F1AAF8A387E669041DCB329DB043F416B64F6EA35CF0A955463459709C75FD349FF3B87D0218F6600812E3B9C08446D471905C26B2D512BBEBA55229CD6558561655B2C7480582A54EC8E404796FC8B508CA58F048235B0E91F9F682E22FA1BFF713266B2CDE79AB271E8824FAA25C1589DE2A07F2BA81031164388A16C10A4786E50199AC023C3A30DF26489DE288A715141299BB9EB0CAF78202392B01FF482754468AF6DE863A708465247093D201231307A455573BDDC356F206B065492EF220186194FCD3621607000C26B7E926551F8107F256647F4F3A2B43136B04459EF1928489C0B4BF12972990BF3F75CEE3082FB88AA3EAC16AE5904A79A9FA52315C77826A5309ED8B5BA1109AA96379FB9D4628317637D864E79243C2CB802FD964176CB47EF234F890560A3BCC0E940111174904602A0B4ECBFED94C475153235955D0AD147E7602739B661839A11A1A52257C6C003BB064AD2AF230BA606462B493A860C02AA62A5727E1263E54680C176151010419E437D4319C118D9A687676605D9437E950FCE770F5E9A52A0F46A8CA57441C2074FCCAE08E5638DBC30413B11FAC00EFB2A337311165393BAB1070AC4A140E2EB12D55978BD1114A7D19B03765AAD34724E8C603B635D5DD3C5F53B7CC83A8811354DFA609DBB0A8FB21553118C41A4437768687FBD8BC00B1983DF56213FA270506A15EBA99B87CB294BC817A23CC76165AC22E676642279E8751475C21B3AA42687174E433886689B171308141E8613E01560062410B8C154F11A5495274204EC75ED373E4E336D7E8BBCB24CCD9AB812CBDAB869F67B19941E10C9AB44A9A3055BA19FAA1812068958C37B48B796F1E869768211BCB9B31F6C49FB27B03AC9098618C9AFA5618F840EBCF75942316E687C2BEF3A163CE37E8016C1F645BB5BD2AA2D4137CF60476677CFA3685E68B188096B9CF3DBBE521C77CC47AA9FB007CF1C30B72876F52351E9A68E09F59A945887F4368EB46741D0C25F27FBBC45C36510496626D3013C128C6051B2D8336B30D77462623E4E59A01A27B1526C594A0894863610F757151C847410A5AF63E95D91B925CA1791EA788171A4940BE89E5F6A50D554ABB33282F057AA1630359B80AFC958B54C612902618197B6CDFA0C6720F36E070824AD372C499895985111C756739AA8ADD2C21940920E4D3379362A16BDB20E22A6BB26B079845BCDF32A20646B480D6C9ECB871CAF0A38F98662D3A9C89E8ACC78842F9C2C76AA79840E5491AF6428409271E6349CAB281692127B3985C547C009DA497D4F4424DD8109D52A476D440E457762C664683E8364C26C0EBBC827B7967207690C8AF5BA38F4215D71652146434A2B42CD61804D77BC61BAAD539124AB6B414341A8677A8DF0A9666E26BFB3300204194E24F350BEE636575C069272BB6FBB34A5433D6024BA6643B02625C41F055FC049BAE48A7D754681829A852C802F53D34E6BECA36852CF62C02D3D4A9D92A1856195A0C6F6727EC3291FC8CFEF7BA3838496FBF89815B32CB55C4DDF075322377AFFE4C1C6739130015D53E9272CE826C63252F032059286391164B950F921BFF53ECF5767F0B6A5A2C2724FD47F378261D5324380646237355276A0291A0A085389C210F5A5A9380322D2BD8C97ACA6DA7C326A8F765C054BE323395AB9383B7847C741E6EB1FA52C5E78D3856ADA3F19DB9C5AB914A71A88FC049445C3241050BB65FBAFA969C1B5E47C3E988D9CB022836780313A0BD728AB51627FB8D478E2C62163F996E14A0CD52859FE32B015129EC6581742A6C48B95953E70CCB73299CE847ACA77609789AB6496023491838CC9C0B321CFA8DC29655A86ADF8A149BC390959776534726134016C9B1B562C2EAFFCA6C9A53546FC7DA2C222E9545AE6C79167706073C0BF41CA0A8FF18C2ED1C4955A282A79C57E71097E67CB8A930ECEE0037E4BA749FBAC51B06890736CDD86184A08528C308ED659477BB721AF5CAD9D7477D9EA7FDBDC558CD455EF4B07AC746648A384794AA1BE7B22B9A507B1DB6A6DA96CC6146471F22F55D7C0FCC106BE7C5B30E634E381873188A46561981CB972B981C51CF3C49B2961B795AE260CAA1AE67D03717EC3A23819F5FE2CFFEA19119C220C5832EB7FAFBF2279D277A8A7D1030FD1F35806D1EB7C4EFEBDA7A51F21044515236AAEE733328776D292038C722EEAA1AF83D6078CA796D367EF6F824746E006FB70C714A96D19D4F1D2F5ED39DEFA727521", + "E931C94E02ED9F04CD60B13068C5A229CAAF01A0D929F62F21804D4297670D863A382EF306540F98C897015E2EF56632503FA3DF924FA333A4AC684466BE8E312EE22B41FA8058076EBD39C1D0C3A0CDFCB6A78BA2B49AF9242943D9D16332DA270017E6EFF53E039DEB7BE6C50FF8158F94FE08C12646D418BB456F53B8A2B80ED0444E9BACA0D88107A7E2D7F69B58E3793D08C0F2FA575136C79A4BD3FFBA2689F51CD1FE37D3F9331CE670A8B9B9F4F15D451CA0D2879B1169F178A7EB7CB488FA1D621BD57331BB72B34A885A818B99B60884A0D42E85D86D66486299B18F7AA4456AD70D2B5CDFD5B8606C845CBD3D9D0A928DB32826F46062132A335EB0195A4AA287594B584E98923E7F2898BF443323A429CA33DA777494885A848B549ECCC435E8B8D3940918A241FF97B03C14D855037E4555B98507050D1B1DFCE68B96FAAF562E3F3307AB3DCC1C822F16C4609BB45616D6F45F48BF54B31914A4EC827CFF8500AFE3294297AD85A8AEA3F3845A9A3D06CBC5FD2BA7D61689D2DBF85765F8A673D3244C27CF148CFD66BF360981E35B9EA1CD022CDA262F4EA81E090A1CA1A3C9A5333EDEA755755752564560F578EE2BC99C227E621C53489C26F3E109AA18FC3BC01FC14BF473F3B9A9368069CE272B2A786C6FB6BA5120E89B3C5A403B9489DD065AFDDD81CEFD11B8BC5C4AFF5330CE8BEF0F5DD17748FA240CA3D83D17EB96EE6CEB39AFCC87BB83FD0DA8E2C8E003952AF86552CC3345D49BBBB363729B8EEA09FECDF7F3BFB1FE4E03EA9A71B45100286E76E33494C0B1C6E2151B6C571C239EF36757D4D46FDAF694260DCE0C040DBE230C6F9BF195D2CD2D7B460EC036FA10153A154D578BA1D8B74A52E642D730218A551835D76103410C433C919732171EA4C4DB1FA9CD05216266A5F14888C8540016AF50D9ED4F7BD4B1214C774CFA9D032A5FC0A89073E3259A05290C7885C2C4FD07DE218AFB7BCE656E54EAC77F34C23E9024F05AE641BA5F72F342DB172998871F94CAE6206EF179AF6D728A442E0F91873079AD49A6F1E348226263E039F448F54DA473", + "D471AB1DE1996DB78AD89F021821A9A2005CE55B6FD74D867123AD814FCA5AB9" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "8D0698292038F9E5857CAA46755BCBAC626E068B493AF1BADCA93D697CB7FAD685D9293244B26818E3B156C9A796DB53E06B736CBAB1DC0B4869668F078107DA976730D5ACC1742B47CBC3F942693D443F30CA1F51E472D98A33C1B9A1E37894C98845A6B369C71611D69173BE935170239594A30F8A7C241BE28DDC1129ADCC72EFD26B3699A2A46829D4A20643C0AA00E9286CB8B2B8370268FCC30C4B1E81363FC968203301B8AE52957D169E16C197A8267D06897B928A2F7915572CDB4650069204C093F18C8061E1B79858349D831F9C8C53A93891999A739790777683908D2634C3DC53C3A03349C274C16A1BC03B0658A6A230105F63236BC4AA147DCAA566294E137480BD516019BB52B2514A62C894BC081EC1793C708B4F76F692FC93816565A09CD2662B6344C472C5FE141A417381E4969528469E2EB873E8871A5774A583246253F62874197E03A81BA8E1550E6AA75E70AFC3978E401B6DE52CCF898804EC102EB037C98ECB20C9AB9218783413025030165E13A44CCEB71BC2322E55F17309E555BF96BEFCE7AFDBD25BFBE149CF7B1464BAAF78222171153DCD3A3774BA059B9BA586536F5EC63635F17CC3C48DD07975E063BEEF96C165B82831384FD8440695286CFAD51E3AD2891CBBC96DE5B563B20D72D85F921647E5BC912F4B0BB75C0C790694745AAC2B9C3B2C5409F9D505B44952AEB6506CCB1CC2D506F0BBC3BB442DD85758AF658DF10C6907650315484C27798D7EC7AE577037B30A48DE13B377035EEBB27A0FEC6CEE366605B40604B420CE92705B9B83E1F93D5AAB9C2FD668E3839DF11A31B101BE639CC0F5D05878E32F351680EBA50F021717EDC5835FC7C20A72435BD91BFDB0C4B68731C6566E8F1C7F1FF10DECC14EA857B008D5C37178826C280FAC788D3DC54B0115BF0D9018890B2378628CA158BA91657A576688AED610CCACCF96E6B5884328C091569B12785C4C054CF83C42E06D40B6BB763B449C00C3A7D9581FA3667F22BFC1A750B907C87BB14C3723C9A880743ED5A181B16D8435B4A4C98537E20086D89D28AB3327627AD75291B87561B97631DEE6FCA7F77A1792E99587DA9456B5B98A53F73B4A4DBA89A68C", + "10575428C648AD91083CB07F76AC26A36540CAD99D2E9C5624E8337A359F8B5748C10C7D035085B0F429A123649BDA87AB285FA96237FCF449CA78361862B10BE3C0377957150A12D32B1D0B8959C45734F91C4BE9A0ACA88B1CA4D0C7BDA00DA618475F6C34D668498DB75DE569303259BF20411BFD566E2DCBCFEC4B055172147AE747881B7076136178831A06A9A2256886C35AC35B5C3F2C2C38CB4117D4A1187803ACB412003BE96052EB1174965A172890D6B034A0EC94D06A368F819284A547391149C34469B61BC8D0F29A62F0847686C15BD9327C1A67ACF0C5E9141CE34A768213002705CCCCB971EAAB55332A42EE472E0D6263178C69067A0AC52021DC4C798FE8A1ED893F34A2B48B405540C086204A8B869B141C186D8B3946070AA5CEA055F8F420705B64FDC13EA580CA57A7ADC23659B7EC1D44AABEF7A9144F93A1E4411A47922CEA0BAEF1151C8369C3857C17420769ECCA02E6B162D7865B7DE37EADD75DDFF75BC2125988D83F3CE80A1331878B277712234BCEE101F723422C7227B536BF352131F0A11DC56304EC65928AC436343B7826268221F4A49AA52389674D8B780E7EA72F69B5443E622B0FB9106532CA87B9A16C7387DA2BB41A643A9287162A90803A10BCAF68309C2B3F0EC8770CC09A2020C8A2DBBCAB1A192A734961F5BCC22B7CF6CB314C6B9FFD5332D4C5028B11632FC66A2F56421D7C8A07656F5888701C9CB6E4FA29EA692B0A8C97B34797CA83B09797A356A28EF9E3A471D82517FC56A306AE8CB396E8CC293BC849A443A4273C02F964C62EACBCEE86CF988A9E75164154A4611773885814107F37C5BCAA6FBE3A4C2FA1723B670E5838289326B182365BD0CACE1C60BDC1C35BF5F3CE653A5EAEC6052A1C14868191F4B30605605BAB8B06C876741AA74F4CA8CEDF719F8817A7E4C536F2260CADF0683A92B136E03B90B51218A826B44584513B131B7133A5479EF808AE2A186224B085AB1197883166F61AA270762238EA76E3C29E8FB35F0D023CF01421699B5DB739227C12A1C462ABC9B0BE92E45AADEA1456B386B1203D2B94718D0698292038F9E5857CAA46755BCBAC626E068B493AF1BADCA93D697CB7FAD685D9293244B26818E3B156C9A796DB53E06B736CBAB1DC0B4869668F078107DA976730D5ACC1742B47CBC3F942693D443F30CA1F51E472D98A33C1B9A1E37894C98845A6B369C71611D69173BE935170239594A30F8A7C241BE28DDC1129ADCC72EFD26B3699A2A46829D4A20643C0AA00E9286CB8B2B8370268FCC30C4B1E81363FC968203301B8AE52957D169E16C197A8267D06897B928A2F7915572CDB4650069204C093F18C8061E1B79858349D831F9C8C53A93891999A739790777683908D2634C3DC53C3A03349C274C16A1BC03B0658A6A230105F63236BC4AA147DCAA566294E137480BD516019BB52B2514A62C894BC081EC1793C708B4F76F692FC93816565A09CD2662B6344C472C5FE141A417381E4969528469E2EB873E8871A5774A583246253F62874197E03A81BA8E1550E6AA75E70AFC3978E401B6DE52CCF898804EC102EB037C98ECB20C9AB9218783413025030165E13A44CCEB71BC2322E55F17309E555BF96BEFCE7AFDBD25BFBE149CF7B1464BAAF78222171153DCD3A3774BA059B9BA586536F5EC63635F17CC3C48DD07975E063BEEF96C165B82831384FD8440695286CFAD51E3AD2891CBBC96DE5B563B20D72D85F921647E5BC912F4B0BB75C0C790694745AAC2B9C3B2C5409F9D505B44952AEB6506CCB1CC2D506F0BBC3BB442DD85758AF658DF10C6907650315484C27798D7EC7AE577037B30A48DE13B377035EEBB27A0FEC6CEE366605B40604B420CE92705B9B83E1F93D5AAB9C2FD668E3839DF11A31B101BE639CC0F5D05878E32F351680EBA50F021717EDC5835FC7C20A72435BD91BFDB0C4B68731C6566E8F1C7F1FF10DECC14EA857B008D5C37178826C280FAC788D3DC54B0115BF0D9018890B2378628CA158BA91657A576688AED610CCACCF96E6B5884328C091569B12785C4C054CF83C42E06D40B6BB763B449C00C3A7D9581FA3667F22BFC1A750B907C87BB14C3723C9A880743ED5A181B16D8435B4A4C98537E20086D89D28AB3327627AD75291B87561B97631DEE6FCA7F77A1792E99587DA9456B5B98A53F73B4A4DBA89A68C79BBB888549D8E7F789D27A3513B899264806953E9650240F1E5740BBF9B6598839C74574CBD32E7837877F7020480A15F6E6AF143F3C078AAA0DC6D72BFBDA2", + "3AE5A2271AC46827EB9B46E6A6AC7AD0D338B2306CD812CB80ECEA078687858E575BD61D4B08BCE51D473D11AAC2C047A346225F842775611A4446CC43E924ECF9A6409B6A589134B5B4C46F8478F0994E90BCABFB361935B4A944CB1D5D3AB38001242EDEF3C0BC192496C2FA6EF67DB276D36512A867FC9E6BDA9191388F3798A4D1D7A4A236F1F026DA54D0BBC0691DD867F424770A1A050C26D8CF80C8AF88780262F73BBAD0727F6705048A32D02CB536137796A6664F03ECB0FDD76403A8AA6C7B39C62A1DA2981A6AB36C987ED2BBF6088C868F15B55955329B17FCFD4EC19B69A7734610EABBEB02491E786EC1AEB85F743593E0880FB0B997F1A81E484802C39D4293FAC089886EC4DA1020AFE810CCA5056CED3AFC8AFF69E1B8DBE05B3A2D105CC55ADB632242541AD4241104B1D789DD6496FE7D22D2173E409A18BEE297F30B9EBB76275FCC07988D464A6B3912AF1136BCF32EEB1DD35EC7CF179D55A0EF4C4C2BA9740BE3A24F33EE1D1B2B7881A71FB9DBE7F89CF6944519B14C6EBD4288CCE624C59474E861249802337B1C992318DDF75ABC03E492D5BA80F3A6AE2D693EA379DF7773B5272E3BB432E0AD4B56191C8ECFAC229E133FEF9B082B3323392BAB98B7CD3BDFD03684F8B4BFD339792313DE77B2A7AFA3BE806B9EC962B825FF6D6CC8E052A33720C9EF3AE81E8207433A3B6E39E90A5B7FDDF6FD4540760FD6DBE7BDA313F3B46B5B4587F57DAAF6C8990C4253182A3DA94AD6CD3414858AC95A87D5C2ACDD0B6C3D48A2C78C4E9A897E33393A257F428B1826B49F9DA7382664447C7026BF5A009C495EE3FBEAA175DBAD78FF7061F7D1D3061E205F2295AD8837648E804271BE3BA05865B767B7032FDA57B1E77097EC877ADA26F09CCC22AE7A2A510B44B24D2A5C5F34AE3EE6DEE769469378952FF5269FB8EED7740D473D8DABA32AF26DA0ED40AD839C3D02A477B1E2F090ECD06BA910066EA8BBB2F32C0A077ACA9E1866C175F74428EAF9C5D0B4E8A949E7C5B8B68CCA427F879EDD2B7E32F598885ED74CB2BF43853F9118DEBBF13CF6D171BD8F", + "5990E7D7C98BA9433133EF4131E1803F83A071D27B5E3B28FC6C21CB6005A407" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "1C83C3DF2509E3C67E58E236D479779EC928C1700F6D4162AC8051BCBBA7AB47B70016A091C1B2A73BAFF47119F2B793B8A66CF4877D972110B7FA3C1860417B34322C449052613CC8005C852B111DB94B06739F2AC286731A3FC96A258727172DE84A5E046C0C5780E3016DCC25910960BFCD0BC86BF50103D5178FA60E6C8B9CF0847257461167265D90C541551B6E672B224BD6711AA31315104E194678FD6B2A8D32311004001149CF4CA3C8154C4976178DCEE33375A09D7B3C447FF4A6BD4CA8CBE957CEA938D2CBA7A24093205475205C4000E439F6E7A40E4898A33CBE30CA3B7286AC49C9142230016B8A7C8F4A402F43AE0B3ABDD977077481510349C09176978C92546A866D0585C2AC12927A0A6D79B1A39644AEDDF6C5AF1013A7B661E875CEA3FC95BE5A172A881D0B63BFB018387108646E7207DEA9B839CB0DB26B48F4E918D55ACDF2338C58A7ABF0D2561F299283BB7D2D8670D094009CC427EB0329D5144B3F0B683166CBF9763F4E58584B6627D4175162484586201E75E0CCAB112F6339AD01B247E4A96C7C769EC5F9B107D9CFF352C3F3EC61E95690999C0498FB16B7C539E9372E9DE99D50756389D63B6691C123947F6B0661E4403C0ADC6364B1516668C175BA9FD8EB462D3532091179FD67853BF7C2DFD5A898648ACEF8AD42B145E67701F2820565AC4D4DD9AF2D395469192B884212F00BC30391BD711C0141814CA95C53B6455C848CBDE2185592B9C84CBA5F43D39F6B6B77F39B599ED9568ECA342D71047C4B55E244B863B2725E8865850B9DC33A4DDBE3AA05D597BCF52901FC54A82635397C992C615F73227A12A6595D5C28B5B6A685CBC335602FFD2184A75243FA639C488BC14BD73CD1D6373E7BAF72453F1EC073F5A6A26D990F48570FD769838361B48313464906B8DEA60FEEB1A139486DB1D7C2F63A6C48D54E5BE76E835026D383AD38952E5511BF02F857699CC16376A425999DEB06895E1812C901CED44835D35BA7864A5CD2D4B21F0B9E6DFBA7D870B07AB401BF23A3B02C11CF00CF7BB99BA500520D846B41B81BBA5650A6F118AF8A67688F81B0D2500048E5A0B5B6037F7A0C2EAFF45D0123620B115E4B92A4", + "9AE711EC12485D079B373C1629772BA9BC0A6B81232F1A5EEC91330FB2BE42F32B5687614C5C6C2D1A42E292A0BA30CC6A51A258D07BC05118FE29BD53F48988A2BF0F2920008A3EBCF28872BBC5DFD8931E987EEA2040EEDC97D6498235E4767C976A7CD1B850F649D8C680CDCAC6D2512CB1634A34809C65940A0B04562AC5655947A123B6B48CF72248C6C47E600B5AB410CF0193E7F4AF5EE17C2FE88EC145971164B5CE6511360311271090514451580BA2E3AC8AD50618FFD508CF250A056650BCBC0B36000FF82664CD633F04E6B85AE02AE6424370F4443D3564F13120B617202633228FBB9C6928741A3715ED5412A57340DB9BA67B0941CA9908340A3048335083BB2A3BA3AA0B50C05D668DFD64A7391025427B48DDB1C4EAA047CD4970A397B1DBD4975A59375642A8558A043FC1AAAB384143BB936261B87310A1F4382C6D465A1C4A46B885CA67EBBF863A134D7B1387D7347A29783C15AC16F3C628A52B5706A123DB49E050374123718DD724008CC24752BC88E5A0EED6B38702B985864A2EA099109B51DF1975F695BA4B7A68B14088DA656B77D68FD848042B262998D4A1F376CF77478B9943A40A031744780B3B346BC1DC9AC5D57367AC98D8DA8A5B5A4C07D9BCB9D7BF30524DC43B0F47439D4D115ED981235DEB3FAC400F1433447EDCB685E69AD3F749D4A54F34E88BB0102C3EE4C6BE8135B993459AEA43C3B941CB4C2A460C3C6EC40A5F2553B3F76D8DD2AE13A46E367A0F5E8B1C31042E5AC45D0DD26FC1257CE3BA7A63B441657CB1762AACEF154D41BC93B3B17997855C78F2B37AE55297D8C4836338B2F9B76D6A84A0F2908334801E6BB9EE2506250063F108AB9B48538D7256EA5797DFB90BDB943109D2C6C8C83751736C6CD1768E24AB724AC709B1CF97A4754A152B187C334CC79FF4A2A721686B483B3085DCAABC5BB451A916CCF48BAD23233FD6729BB2C8E58257FCBA5BABDA6BAA49B23304454F79AA47215B3F51CA9EC429A49C8AAFB55AAA854CD0507B0E6902BA119355F43ADEB583185C0D7FE1925A468B7C583D03DCCC2F7471D985351C83C3DF2509E3C67E58E236D479779EC928C1700F6D4162AC8051BCBBA7AB47B70016A091C1B2A73BAFF47119F2B793B8A66CF4877D972110B7FA3C1860417B34322C449052613CC8005C852B111DB94B06739F2AC286731A3FC96A258727172DE84A5E046C0C5780E3016DCC25910960BFCD0BC86BF50103D5178FA60E6C8B9CF0847257461167265D90C541551B6E672B224BD6711AA31315104E194678FD6B2A8D32311004001149CF4CA3C8154C4976178DCEE33375A09D7B3C447FF4A6BD4CA8CBE957CEA938D2CBA7A24093205475205C4000E439F6E7A40E4898A33CBE30CA3B7286AC49C9142230016B8A7C8F4A402F43AE0B3ABDD977077481510349C09176978C92546A866D0585C2AC12927A0A6D79B1A39644AEDDF6C5AF1013A7B661E875CEA3FC95BE5A172A881D0B63BFB018387108646E7207DEA9B839CB0DB26B48F4E918D55ACDF2338C58A7ABF0D2561F299283BB7D2D8670D094009CC427EB0329D5144B3F0B683166CBF9763F4E58584B6627D4175162484586201E75E0CCAB112F6339AD01B247E4A96C7C769EC5F9B107D9CFF352C3F3EC61E95690999C0498FB16B7C539E9372E9DE99D50756389D63B6691C123947F6B0661E4403C0ADC6364B1516668C175BA9FD8EB462D3532091179FD67853BF7C2DFD5A898648ACEF8AD42B145E67701F2820565AC4D4DD9AF2D395469192B884212F00BC30391BD711C0141814CA95C53B6455C848CBDE2185592B9C84CBA5F43D39F6B6B77F39B599ED9568ECA342D71047C4B55E244B863B2725E8865850B9DC33A4DDBE3AA05D597BCF52901FC54A82635397C992C615F73227A12A6595D5C28B5B6A685CBC335602FFD2184A75243FA639C488BC14BD73CD1D6373E7BAF72453F1EC073F5A6A26D990F48570FD769838361B48313464906B8DEA60FEEB1A139486DB1D7C2F63A6C48D54E5BE76E835026D383AD38952E5511BF02F857699CC16376A425999DEB06895E1812C901CED44835D35BA7864A5CD2D4B21F0B9E6DFBA7D870B07AB401BF23A3B02C11CF00CF7BB99BA500520D846B41B81BBA5650A6F118AF8A67688F81B0D2500048E5A0B5B6037F7A0C2EAFF45D0123620B115E4B92A400F11997BE7A68FE85D93A281B31BB1B612287B9E94659A2480C2278C53FCF213F532ABD59FB62728FEF47CA84C2E93674EB6A518FFDF590EB66615EA7174013", + "111C9A3008F48AD675BF25B97F3B3F7F12793521425025C47645413AED3A2E8A29B7EB5DD46F4B4C8DA0FAA8140B83CAE325066EA3641A6001E475B685B4B348FBD7AFC0B07ABB26E7163E32F3D4B1FA7E7E15AFE168B31F7476697161B6E44374E13723EAC77C3055282D60195AF71E4799576FFC7C59D85684846F05BEB47465E977DD7E45120D0D3F7DA6AE7F43E3C9F958DC26FBC0D4E5C0FC6EEEFD392401162CA36872FE996B213B25814D951AF84B3E19BF14A83E35CD91B4434C5C9F47FFD08905D9C71B86E82E433B6391573982DB3D7BFE8E1E656C60809E1F91A7846732189AF4616D5B4605E224CDAAB8D3E7F0A80792F352591AB59C9B5494842057970E9223B793C91FFFB44A87F999BE7B964B4A0FAA1F3DE424320EBFAEE29EC27DA4FD8E01A85D0839DCF4FFD2494C932F5CFCD3C4C608266A43312E4E8BFE0CABED2FE7608E387F04FAB278A8F84023571F8E3069E3664FBF25ECF33CB14F5945D924609BB7F956FE82FBB3C122FE163CEAA2661D84EDD5DDE9D254C2C8C1F25BC6691E589BB83B657BD88619A88A0A28A42DD4DE04DD762F83FDA21559CFECA8143DEAFD40644B5F789784E5A4E6E8BC592DF66D2F875E531654C3A55D7B2A06F4E3050A83E9B1AAD62D185F3BD400E5964723E793682010161D8B5CA310F87245C678C8C739D2E5B473B409C4418BB21581BA67EFA8069E4D10BA6D0FE8F8E6E30FA322B2E790238F1A51998A66969A50785FCD4215F44FA67EFE179FD212E91BD3BD8528FBBEC7FF132FCD228A105CB8FCB4C08AD3828E0FCE07779995DC8ADBA45F91BD3A9B8D46BF8E837368A218C5104BBB9ADEA8334C758C1BDB17300AB06B1B5442530ADA971C7E55FF053EC7AE0A4F0410324D640E287865E39E511CC957E4C949B21C0CA8B98901AD6636B54D6DC12C86FE740D4AB07198E8C17C7DD28EBB94AAF1AE60AA724BE97401E056818F563FAD982E692F3696ACD79BE0D418289DAB86F4BE9008D1940FD51657045A10BC2B1A6C55CFBC680765874E654FDB543E4D78D86626A407657D2EAC0C1B18B1E9AC1353ECE898F1735EE3", + "6E07D03EC7EFD80F60B384F8A1AC9B19D839802A727ACFC365549A26AE29DB63" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "FFBC558CE050BE2C7B4616CF37604F4D736991179394CC379A87BE8A1952CFA51D35999124A44A2B96BCDA9519E9FB1F40A13F035A926A177EBB37141A3081BAA0A6CB120A35909FBBF5A245C1BB9343C2071A7750689847A246D2306137C590CDCAB6E2A355E00CB6A399968F3B11A5897658B72A3A466E71C339845CC0C9D8C985D63B31703993F24293F70D5DB6A886DB658FD43C7B2681784062739451453256C0350EC31C4E1CD4B06B3BB2EEB19F5BE27DA3E564F92486685660004A3C972B4BF872859EF781DD90079DC343C8B1AD8A4020D90C00FDF0493DA7CFA0B25335482A010A690C648227A3671313162D5259CD0162CDA68F1CB291F844B845D9A5376BBF8DF67B374B4DA47B6CB7AB0C81461CA3FB591FB27A9ED0791988B8352055AD469BA0B66AB7D4A71497128309C45495A27E73B86A32C05A257FFE04453337C66C5B55D27BA88AAA36BD371F17DC589F01C883587C409B695BB6455CAC976A7A48B5136DCE1CBDB8F7CDA119B3AC5B19E622086BA77689D9B351CB1BA144954F51C2CA5B1D475A0582C0B13006AFE2683CFBE59D4DF5CD6A7A7541428DB6F85C7F9C831C412A17393A76B9BE7CDBBDADC38510962078170A68D60719223D8075854BB929EF4671D1970B1629397287372F328370DA198A17CB4D19A55F25CD37C866420587CC2C1AE578C2768047033546563567CDBC1FA8173D53B1CBBBB8CC93908C97F4620BFCB87FE99051E47C08884699F72ED4782900C89814001F7475673DAABDB4359CAA58044AC22089D73915416F81E59DB06808EFE31ABA4017ECF25FBDA730074C75867B6C8A7C37A79670E9B8CE8D3B7FE4879E24296705B424A764BB9A320F7D695A6C43273F7706F8254DAF845BB9A6459D643A94A97453468ED9547C6FB0C6EEF280F6833F85FA63F8EA12F65153B07395C609B37FBA2FAC39416C23C3EBC3A45DC892A68C210B49614FC966A25409A1066A83D7C301B4BE1948BC24565B3810C852489DAA42A8CDE93489A04E2E622AB2003410753D770636F9B06527DA6274C10BF90C7B1B8179F817CF5A4095D627B1F1B433B17079818EA6E206716FB0745D3438F995ACB85239BB378CB0A900A2D2C6C81E", + "D276B7EB86B21B95477AD26C470A942696AB91C570ED5CC531D6704B752657AB7416E5284200BF13E73308F86E225CA057B03D785908B880939D439419972E95155CE8A841B552428DC00FE5AB47A35979F68165960C77A039BB5CBC3F80CC4526D402E53C6F9759B7C7743FA150CE581925295192A912191A3A0EBD215D3188670FF21D845080DCD1B73DA65887D324E6B20E67A1721E078B26CA1BE91A5FADB6BF40C8329C917576CC7C0B20BA187A5075D245464BB3B874A81286359EA66913146273B28866548D13C0A0CB91337685382556C88DEA378AC37104A0279FB647B459C0132A2152F132D1E71BA721CD7857C46F217EF4AA1E4BB484D3D21C2495975E2BA7A0C03B617B318B8773728A3C54575832860CB0968E5E8265714AB6F8659D881183956AC1368627387130A479862492805C7C67E558775B566D1D0521A82C14DD0087473303F8CC93EFD45D14653982C871F807B8BB5362C5079AE5D51FEC1907797C07E48B46A0C73D9087AD8B63972D0166DE89887974B0FF989D7D5794863C710529462B48BFA85605C4F1425C6920AFF484DBE116EBEC06AFD4C406599EFBB8929468C0FEC5B0D95344FA3AB9CB2765D550661AB1077E494B8A88387BDB016C0163414275337896EA797C59467F13E035ECC61DDCF0A7BFA146BB36C7D8720ACA12A22F4070A7004D1877769C3A2162DA0F23F88BBD405267E642B2DBAAFC99A9E9F91BC1C09302E15F165B08836CCE76DA7F317AB6C14C1CA593CE27A7048E70291D4B8EE6C80EE7039F9964608F08940D8651D0FC764C02640B019D8C828B424840FFA00D1686246A93010F4B97A2E37431010A007AB552F8575AFCC64EEA0C01EA791F4066214637AD706864B353F54B30884B2E11A1AE4BEC0E1CDC8939057261A30506975A64858079E431D6437E45D30F899B9DC4C7734BD613A546213D24B625A0B4D289484973C8E0A3C57797514FDC032C0AA9CDDC3FD6F7394112A83D26692499C046D5732ABCC8437481A4D82E599813361772BD519884693C3DC8CEABBC1747F4ABC061725F2714B7618BD04563A15BB140E00AFFBC558CE050BE2C7B4616CF37604F4D736991179394CC379A87BE8A1952CFA51D35999124A44A2B96BCDA9519E9FB1F40A13F035A926A177EBB37141A3081BAA0A6CB120A35909FBBF5A245C1BB9343C2071A7750689847A246D2306137C590CDCAB6E2A355E00CB6A399968F3B11A5897658B72A3A466E71C339845CC0C9D8C985D63B31703993F24293F70D5DB6A886DB658FD43C7B2681784062739451453256C0350EC31C4E1CD4B06B3BB2EEB19F5BE27DA3E564F92486685660004A3C972B4BF872859EF781DD90079DC343C8B1AD8A4020D90C00FDF0493DA7CFA0B25335482A010A690C648227A3671313162D5259CD0162CDA68F1CB291F844B845D9A5376BBF8DF67B374B4DA47B6CB7AB0C81461CA3FB591FB27A9ED0791988B8352055AD469BA0B66AB7D4A71497128309C45495A27E73B86A32C05A257FFE04453337C66C5B55D27BA88AAA36BD371F17DC589F01C883587C409B695BB6455CAC976A7A48B5136DCE1CBDB8F7CDA119B3AC5B19E622086BA77689D9B351CB1BA144954F51C2CA5B1D475A0582C0B13006AFE2683CFBE59D4DF5CD6A7A7541428DB6F85C7F9C831C412A17393A76B9BE7CDBBDADC38510962078170A68D60719223D8075854BB929EF4671D1970B1629397287372F328370DA198A17CB4D19A55F25CD37C866420587CC2C1AE578C2768047033546563567CDBC1FA8173D53B1CBBBB8CC93908C97F4620BFCB87FE99051E47C08884699F72ED4782900C89814001F7475673DAABDB4359CAA58044AC22089D73915416F81E59DB06808EFE31ABA4017ECF25FBDA730074C75867B6C8A7C37A79670E9B8CE8D3B7FE4879E24296705B424A764BB9A320F7D695A6C43273F7706F8254DAF845BB9A6459D643A94A97453468ED9547C6FB0C6EEF280F6833F85FA63F8EA12F65153B07395C609B37FBA2FAC39416C23C3EBC3A45DC892A68C210B49614FC966A25409A1066A83D7C301B4BE1948BC24565B3810C852489DAA42A8CDE93489A04E2E622AB2003410753D770636F9B06527DA6274C10BF90C7B1B8179F817CF5A4095D627B1F1B433B17079818EA6E206716FB0745D3438F995ACB85239BB378CB0A900A2D2C6C81E65325EF7D8E1E3467815EA3582ED63D90E99CD0EF85185D3A2CEE9904F78D67A606479059C3920A06895F8EC369A9B9173059CCD77667520A7D276162AFBD25D", + "A6A2CA5C790E38F2CA43AB92A12A914B2F85284CF46F42BFBC4DD40AE65B1BE7D821F91EBCCC986F3A1669F83E7D6F135A3BE09D0D7FCFF7F883DE86CA2938BDD3780543EE67740E0C8BFD6FB6D60C7E971161474A4D969A5C8A535AFE14DB3C890B511DA945C53F925AFF4F9329C097DD6E3EEA93B12D8DD5A05D89510C0019266137DD24077708E2F2C63FA7CEBD3B736DCF3107F1FD1BD90939788BEADE520E23643F109203523E8237D5AD1D96832188206A50023129DB1400B00CB3418C1D8FF15CB23AD339D669594A3794DC189DE19871667D7501FCBBB880C4CA9C87BBC1A5482B218450F2A830BD0CB084E70B0D123D7CBDA0F7700FC4D2AC4B22DB12DDC590807793A2475AB66E0B8B6A3FA2A80211E1A752539D65223431604E6E583D3AF71BC5CE4FB85A7FB643F5E343418B7E4B92534D78E37528642F7ADC915114CEBFB2A5CC984DAA7B98519523A4334C1289EE33A2E9EA80D3E3F92EC7D4A6D4F4E7D659D1B7DFC00612D74ECF4DE5402962C0F03117E48D0C739314E4C4E233AE779420251EC3FDD6E364F4CDFA3747C543CA9B57711143FE7E16E4CEFAE7C3FF9F53398FE501104B886EE7505D8EDD3B258A56E629DE61CC656B721A7B4A2C2A03CE5A222AB7FC6A2FD1992D88CE5B98B314617BB3B1419E4DEADFFCD7F2197DB0B150EA87BC2EDFA11DC986720C295D3FE4F78F40C00EF835938B0882D4453E71EE63BBB521A79CE857BFAF732D996973B68F587984045418FF929DDE6B6E82F82C910222828AD5F1D31093B9081D592738E16018DC9082BFB233EEF847120D6A846E5A33F772C989D37CB274F20BA7829D0F7797C02EFC7C2260040497F5BE3811068473CC5A5B84C2AA29749F501D03E4ED64E77EE9A2AF125AC8A7C313C892BB3A44646491E2F10D805436C0A02C164C38DA178036FAAE6DDD64585289BAA942CD30116ABC59A9B455D349D09A9AD7A3F59BEF76B26C026361F0731D4B8BF70D265E38818DF36FA623C56254D826FF2AF9C28D519843B3534741C0B6A78CF094A6BE8434FAD989BB33ECD88C98F02E3BF37628D48D1736AE2465A7", + "405E1E3E8A545D56132D85DC38D67A0CF7ABD99D61E7C8A55D2E7260F3D96C5E" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "1F2962ECA97FE4A63D64804B5B259F2025197F0B0EA9996326D24736553ABF113594E122AAC2C62936C1BD75689E240CED9BCE098212067776023A4954376EAA342687195E548160835224283A4606207C6C939376030C91BC3FCD6466810C5FA361488824B35C693DD8FB56DE2412B86A9ADB28384F908B23ABBD28307CCF834D3CB29F3E1AAC65806F4084974CD7037E2B84F645733FD660D3C246076706856B2415B0A234A29A76532DD6D6320BD06AA459768FB067C7B28B8C89258C2354EC5926D23BA388C14E39A63F61D23D705B1B850C58804856934892DAA452007B2ED01C6196995C55C647F3F58BE2D27AF8845C2334AD27687A25E50BB6BC90058B181D7197C5331088B7AC1D18038AA9920145887247C805102B95F57235783A4847130E47566A60469575651F0137608395D010567B7866C8505E6DBB6F6728959C128C382414FA53C461850E7783CCA1B4265008642581A06BB0C410D2A791D0977669188C6231A4A3390DAC1B15243E41D57843C53E309A3DEE5BB0991A85109A716800866259054FE1CC59FB6A96A75C8503517EFB5517E8170376512A53C861FA35AC8C4B5E63756247042690BD67BB8E0C7C9E8F05C5CE48CAB0F1425E329072F87401634211241738C2CE97208C6A6AB609F03EF13387AC6C08A3FA61E53632677507711A25C1FA3454D86D7BFC75E668100D6A6A03086142275383E291097104356A0848724BD95C3CD89CCECE97421BDC67B0FC8AA0E0C2460B4AADD9033CFC60EF04AA6F39566E89793DDC0481109E532566D90525EDE57E8B756FDA7190BB89937DABBE2AF4239961CFDAD37F1E4B5BED5A4CB5637163840716A1CE2F2036975A640B6A7EF308690D66750CA05B9058772828BC458AA9CE47116EF459B01C292010B7449207EDE7AA38AB20F10280E316298E9C86B3B4B94E718B85798D5567C96531A6CF84BC806AB85E156A34447B15FA9FA5BBA5F1087189BB9D4561885B2547DBC5BC081C1A268A9EBEE5CB1D4147545044D11933F43871ADA5495C894793645B0BC472407BCDC5ECCE19F219C98532882381739B94E2366BAE2C543E68116BC30974149E59318DF3336204C22063E4481E688FE2634D790773E243A325AACA07AC65EED5BBB092B6371B519BC01067849E6BA3C5D9B4AF5D073BC84BB472C123F2C72C4B191C85405D63C148B368399ECCC42F208F62E75E14408BEB14101EE4249D2418C359AB05E5A3B60A5465637EC6A31419EAAB9458A285F684404C4A94425FF6806150C7111AD2A77C0616D45CAE9024BE5DE259FFD6C3C0E509DF484F2D219D5F3CB596BB763D4BA6C3521789FC840142A42D510F14EA44B3E9B573A49F9B0879CA5A5E0606639A7C67A7674124E2423339126FB019E00BBB5031A1AB9B3A71190459A16EBB0A196DD9CD5A152179082AFA9436B647A68111439DC325EA777BCA84ADDBD62FDFB61009A54FEB495A166BB35C9C426A678E6E2958BF52138F68711D623B41C7B4A97A241B17B3C37720FBF04BA3C175C96A4CED4C3FD0E4CFBB345A0CF48A7C0870E4353CA02B92A204A9C03A6287BA8E1CFA50B91C2E2674CF93382A72E8B9E0214504B97C18D60351F689392A8E44AA2C57DAAABE4CE52E3CDC2BB436DCBDECEBAE89BD2E392F0370092A66B4F0", + "BDB614FFC9BA80A3BBC1899EC855448E2734BBA74116181D1503CFF0B497C832B75998A5CBA94C76C2CCA25904F574080DFCB7B4E64D5D7547B2C2C5E4CAAE550098BA50BD6DA47EFD10A67C2502A8C7B42F4B2696846FD849706C014A6CD8B828012B4BF41BCE0041E27A4245231B954B958B1400A7721FDDE369C488BE6AF043A8C0A9CD0CBBE132A2F303BB57A4ADFA02CB12717B2EEA905381B110E61A6B506B45392F45313C51756D80B27B9398C1F3F1A74655AC08AB6801F651A1A378DE128F63D4BACE138330025FA3882BAA630C98A070395697D4756D7F0521EDFA065D36A7491B53A371080F97CA1FA0B93E544DBEE4815B92AC2EFB9005113D583A731E17B713A68373D5AF07E32520B1958FD9643B4CA70E601472002141A12424726114AC1FA65801C8659846E8A1D42C53BB0A3BECACB43161C7DB707351485258C4C373754E9774AC09482CE92A24EBE959973A5E12606440777B22471C3EC015F2673EA3B4AB844778EAEA88302446EE790C2E954B29738A90287EFDA113125170488964EA551451955656A788BFE4C58A7AC4A9F2BFA2DB2C91C69DBB332FC4B231DBF1B4AA914BC63C1C37380C2395874EC1C517F0C79DD0B85054668D93CB2922917F9593D49292353C8A0208A26C37738EF146E92A2E10C49904F324AFE1820EFA0AC5E5A4AB3585A097B6D35C88DD57B5AC0241C21A5DE1A581D5416C11CB1AF1B79374C746FFFA4DF658CC6881BCD5C875E925223AE8A56924422EE9091B21BEBE841C37B8506B097E3F3BC20342AE00307745AACED7090547C1882D32C60BDA724CD156ABF8A11DA1BB054A8BAB5C44B474084FA13FE2949310EB64239338BEB36BD86ACC923C4320510220545D8EEC2F77EA364870B58404126B501CAB238BACA52040DA2037D541D574A6E7C30B9877AD540512BE2B41AAF888295B1A38C0CCE4F023BFEA82EC0217BE5A7D6A6515C399ADE1AA911336718524AD916A186FB488DA793D214486F0E231AAB6075C0A04D6406286684D65484B8520438F021FB4C55AFC5A4C35D97F0036480E65A8EF894C938B42ED023A4B966D235479012594BAEA06E6E86DF73C9DFB000F748C8140AB49341B5952F5862EB73E8503B4125997384B11208972D1DA3D320064459B6D714A4151696A843B872626B051D219F8238BFE480182D93F70752319B8AAF7360494038BE5700F2E9B86E83812744989B4921469F8A4B41C682ED329203B00257A950BD5435B224E4699729CE58D3855293C62C44EEA5D2CF96B4063A10C8ACE2DEB53FA79B8A1E77F955A6A48B38119FA6B8106301A25849F9030C86A2889BC75C147C90D6525DC532745391E717C70DB15007423C06E8BAA23277FC896B757536C2BA5A2605397E015A84AB216635B2366C7BF1364CF87D3CC61A31A57A6949AF77AD5990ED54122D4082813754079765C999266C3E961E674C1F7D03F9D258C1976950A120E0E31CF6239362FF38E395935B5E29D40C5BFBBDC63C25855A372C3656C243AA135E8492F3890615CC75B3A25221DB72670E465E1B45128B131395B4F0AE3BB09E94965983FDF6A54AF087AE4F32DD7837AEBF893212306D8B6AC1765758466908A3A641F2962ECA97FE4A63D64804B5B259F2025197F0B0EA9996326D24736553ABF113594E122AAC2C62936C1BD75689E240CED9BCE098212067776023A4954376EAA342687195E548160835224283A4606207C6C939376030C91BC3FCD6466810C5FA361488824B35C693DD8FB56DE2412B86A9ADB28384F908B23ABBD28307CCF834D3CB29F3E1AAC65806F4084974CD7037E2B84F645733FD660D3C246076706856B2415B0A234A29A76532DD6D6320BD06AA459768FB067C7B28B8C89258C2354EC5926D23BA388C14E39A63F61D23D705B1B850C58804856934892DAA452007B2ED01C6196995C55C647F3F58BE2D27AF8845C2334AD27687A25E50BB6BC90058B181D7197C5331088B7AC1D18038AA9920145887247C805102B95F57235783A4847130E47566A60469575651F0137608395D010567B7866C8505E6DBB6F6728959C128C382414FA53C461850E7783CCA1B4265008642581A06BB0C410D2A791D0977669188C6231A4A3390DAC1B15243E41D57843C53E309A3DEE5BB0991A85109A716800866259054FE1CC59FB6A96A75C8503517EFB5517E8170376512A53C861FA35AC8C4B5E63756247042690BD67BB8E0C7C9E8F05C5CE48CAB0F1425E329072F87401634211241738C2CE97208C6A6AB609F03EF13387AC6C08A3FA61E53632677507711A25C1FA3454D86D7BFC75E668100D6A6A03086142275383E291097104356A0848724BD95C3CD89CCECE97421BDC67B0FC8AA0E0C2460B4AADD9033CFC60EF04AA6F39566E89793DDC0481109E532566D90525EDE57E8B756FDA7190BB89937DABBE2AF4239961CFDAD37F1E4B5BED5A4CB5637163840716A1CE2F2036975A640B6A7EF308690D66750CA05B9058772828BC458AA9CE47116EF459B01C292010B7449207EDE7AA38AB20F10280E316298E9C86B3B4B94E718B85798D5567C96531A6CF84BC806AB85E156A34447B15FA9FA5BBA5F1087189BB9D4561885B2547DBC5BC081C1A268A9EBEE5CB1D4147545044D11933F43871ADA5495C894793645B0BC472407BCDC5ECCE19F219C98532882381739B94E2366BAE2C543E68116BC30974149E59318DF3336204C22063E4481E688FE2634D790773E243A325AACA07AC65EED5BBB092B6371B519BC01067849E6BA3C5D9B4AF5D073BC84BB472C123F2C72C4B191C85405D63C148B368399ECCC42F208F62E75E14408BEB14101EE4249D2418C359AB05E5A3B60A5465637EC6A31419EAAB9458A285F684404C4A94425FF6806150C7111AD2A77C0616D45CAE9024BE5DE259FFD6C3C0E509DF484F2D219D5F3CB596BB763D4BA6C3521789FC840142A42D510F14EA44B3E9B573A49F9B0879CA5A5E0606639A7C67A7674124E2423339126FB019E00BBB5031A1AB9B3A71190459A16EBB0A196DD9CD5A152179082AFA9436B647A68111439DC325EA777BCA84ADDBD62FDFB61009A54FEB495A166BB35C9C426A678E6E2958BF52138F68711D623B41C7B4A97A241B17B3C37720FBF04BA3C175C96A4CED4C3FD0E4CFBB345A0CF48A7C0870E4353CA02B92A204A9C03A6287BA8E1CFA50B91C2E2674CF93382A72E8B9E0214504B97C18D60351F689392A8E44AA2C57DAAABE4CE52E3CDC2BB436DCBDECEBAE89BD2E392F0370092A66B4F02AC3FDAD8D8F210A271603D045F95EC94C2A38EF4985F2E72EDDF9EEA90CA3F0FDE3F9D49FA98B44BA6D37FC13524B7FF2435B88410255345590DA7870813873", + "E3C563F0E5A3E2A6FF16EC3630EA56BA17647ED1236BD957021549825E806DE8924E3AF298F5D3CF2D462E31082180D2C2964ED80D3E7D92E5227E01B9B740F1E2D111FB379AF7A92320EF8BAC44A2591C7438B7F916C1508C45106E2EE3629F28FD280D725C382D647C894E60C2B109843D5DB59ABFD52B4B98E86773CBC75C8989239C288A79AB1D6608FA6EF287BB0431391C0CFD73504AB24D10A2F8FA5F3C3F38D9BD48607889E160CAA09818830472038F9F6CC2F7AFDBC45870B434F421743E1E0FD019D5C41101D9DAC014472C4FEEF0A9EF980E7F276CC7F1E1513A64172428A4A091A4C9A6A009EE5621E37B179EBAAC0D122A8BF42AE861EA420473D2C8F9EF3F4EECA11AAF8863BC66310EE5233797134E849A01992149CDF637BE74F0292988572A38AC86959CB67DECF3B3C3BCCCF186F917476DEE06727EA819A51ED1EE6F3228F4A0322032759D74BEF9703BC185A59492A79A67109FD6786130AB0D41F346D59FEAB3F3FEEC1270904B1504FCF463E9B4B40FA9B5266582A8031F0B200954FD080E207C9B40608C499D49FF752D9D1A4FB5F91264085D9E1A4A1A1FC91B5C5B3DBFA5D1EF5FCDF289206F611610B948644CFF3632229AF44D2971E3FD85E88E6936DA82DDD8815EA1A5DD6DD3DFC03259F604FEFC59CD4F9FC6AB4E9D8001A747546455B9629CCDCF5C4058D57C20DB6C9EEBF7C4ECBF76784FC2C9A08B5414F02EE7C93A38201BDFF31068786FBF98654F0A32B188B891BC59D683E08BB2D6906594CD02B232DAE179BD5C10CA0F7323A0016876BD80AE16265AE3A96204665A01758FFA9EAD686D3BC22D92899633520437994D73EEAC9A2E55C1EBCC3D07229B2E5202DAC0285B2BD600437CFEFE98EC02B13977359FE4E51EA9FFCC287C88211BB220A3F0E52D5D97B547B2369CBBF46512DFC304D72EE1664C91BA5E75B2B1D089EA9C02BBB7E390FCB2EE60E56FCAFFC3E3FEEA01FD8D5212783BF71AA94BA94813325A0249E55BD4337B7BD662D6641DEA484962E04DB7B42522837991D1048E9785E3BC297B2106ACA4968DDC1D05BED81DCD061D21DCFDB82D79CE3853E8B2089A8FE150F3F34CA7BF540D8044D8E40CA3EFC66F1778EC0E131F922E28D8B62B4050042064360515B5A88032F82AC618C9356678CC77F3C4B3456C61462232D92094B29A139E975D1DBD2B2E5A8BD6AD7A3CB9EB9BC0C0144B2178EE709B2D8EFDE65FDF3630565FA83910C9C3CC179F4613467294FE778A33636AE26AA9C2EF2D0FF2D648D3F8E2B9E20D434EB8BE0AD4B57E87B92A6D3572D8DFCD38B2DF6D77C5C8C25612EB7A3E0C0791003DDDCFA723841749A6AB9A9A5AFB098E1A82390FEF7A0FED281D7DA116B830524B5B4319F93DB15081136B5B06F8FB289018B47BE3302C193C8236015CEAC96916E39E4E8C032398056DA8C57F7D0F0A0A88B8B91D5D4D2A37CC5F0B8935BA7FA7AC4A0E0D87ED501B6196B7A4014226667F0F0EBC221BAEB63C7947D8677BFD625403F99F74", + "F8497107CE0D948FF5BF6E039E3CC4EBFDF5E9409EF77171A1E4BB2165713A3B" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "6A3A01EA24AE603A99613B63596360748386C8F33EDAD3AD33C5620DBB58FE81B76B960A28C8A893F7930F2583AB0431CB15B6D0EA97EE76045FECB2FEE09BE411B8AB827236C67D65C4B548A43999134D4FA3735629CFBF3314EC955194C8BDAE1B6B32635F27427DF0C8103639CBF7301C4C36B896E853C2377C5C155C9DEC611D1B6BBABB6777B6A95DA79B5456007B30CED6BB4547056C7B08B703A774114B036DC081BC896BED96C8F7C8BEC4EC945CB78E21503F04F849C053A9B7E1CA5E080325972FF9310B12B04BFDDA31AEE5C45E7BA024133BE2B7B389D22D3C9AB4CA34A31FA902571ABD0C267DC23157787B368F1352BA6A0F9D04187AD29CDCBC382DCACE8E31869CC2C7A55097AECC218FA68509D289833988EDC26B23B4CE26954A15041465A7287E372CC6213F7988768D105030DACD01B73B5F2145020287ADB92D63DB8D8E16A231618D4DD97851335C68811789428E8A8280519A81A215774B103981614224E35592647823E633E951646A1912721C0AD5BC21DE84734E285653B0858E5B325699B5E31C027B266E7E82C6473072A9E49B0B8C28BCD163ABCC7A3F3251601B4719F2894F1089FBB37F1F760079C6286525551BE7AC73E52926B28FF3F89A663043CC3C5FE2BC0312C3A0E1206583633F0747013C42A541E5CD53142D19D06B7E930CE1F68485D700BFAC9A71977C37A28CB11C703AA04FE533B58F6826ACC1AFBF25CB7B0A7890C427FE7069120315313C0A45C18C2EEA868243B4F46A03622C911A98ABBD7C2EA3305A5237AE76838350EC1512314A7CFB19549283CF2866F3FC3F429168A461034830BC4FCC2A7259BA6A49B256CA9066086A1BFA64712A7E5EF40BCC758B5A600C2717216839BEBEF900EDFBA4126C89047328A9849E80A596FA930D666099A9978085508F9AE8CD1A1325B4082457045A923410C84A0EF382BEA75420883C4E3E43183E8B9BB02A7030051526055910A835AF9053BFD66B378CB978AAB14B629F88839F3A4A7F985BCFEE440939359C7FF98B668202149045F68418466C45E76517F9F7389A683B47897A608A2F85800F7795BE75799DFD597057FA3F86C84CD52A4140758AE45B51F80262DD56337562A974B942DCD20EA2BC5C52F225DAF5A80BE0AED045A7E812819F646D28B0578D042C8B77C8341B46102BC881A738DDBB43411B43C41813C4C28D75400BAD4902ECE7C899FC7FEEE32C78D70165DBBDD139BA3EB2210EE3C1F6BC2B31C8C73B1A54657346C3D322B243AF797A93E7129B17FBCD3C7B9CE49216472BB6DF1B2F41BA4EC3813EE6DB3898F19643C38FFAF3880101B08DE8370ABAA82D91BFDE31B8F78CB85474A3BF06844A233E65884303CABDD1BB52F23C01512871A6FB50DCD3A2417140DAB019A11BC10176C5C83BB138CC2BB45369FB74995613CCF71426CC45536586A9ECEB63877494C4789E62B33BE19B87AC40357DE584F11B236E389B26A5578232478E56B798FA77E6366EC15046B38B4BEE0255FB6AC0B8B928F9F3849417B7C76A396D0B58DE16C709E58D5C523DCB6C7EF74C60960886926B4F5B472A7D2B419DB06592691B0F7299EE970B8ECA7F74B1258AD17C087C8EA0F1AA37C40C631CFC95ABCC465F6315C54C7531FF559F19B952406FF1BE2C2C", + "DD30BACFE52565345BDB2157888B5694438242E2A2792B5E3696C516F8AD1D893DA3FA1907ABC9F0E627866C30B1BCB4887C7291D0381F2976C690ACFA571184112F11251E38C61DE8E727198515FF2696BC8002000D0C1AD542360652EBBA33F5F8A037F50E146400BF12247B73A7045369272753B2DB9A5B13614CA446634B9513D3A050C155E879537CEC6E93634B3DC067DEDB1A6A378DC9674AF3F09A6726B346F5A1EE069C1356626D7126380745C7B065D5528735B36355A8260F3216DED3CDB1F6780B8BBFA409B67A266F097429C0E808D1F2479617AF9A05712E7731298455611A66C2584C8888B691F23B574A463FA8CDAD2802CB14BF83AA31D5D946ED55097A24CA024696148A3126DB4E69AB82EDC9024C4734FE182E45E8766732750ED443726A578E39484A90721A28CBB0E03DD72931405516F53001D57C4CA4EA2E171CC27AD896F2A8C6A5877C5338374DAC8DF4D762C1D97BC735430B33CF62BBC2D0A0A3FA8401B54C0BB77A46FFE5AD73FC2A5D285A1137052ED028DB79988A4323D0F8105C58AD9FB47BED3A60A8811FA2C55B187AC7DADCC42AC09B2EEA3609A06A68EB47B28025419B9C702BCAF06C38C86C7640629C89D7A486990D62433A66327A687A4CCCFBBEF4C0947966C991573592B78E54E7ABD5A9CD17D6930933936E049121C568CC013D415C23CBB2125F5A3B1FF58FA795B4E16B8C44A94FFCC344D035BDEDC45698A2A205414416A49F4E2A06281C9D254462C070AA8B7974180B3FAF81A7257034B7752EA315A1F4DC64418470EFBA37B228C0E5826C40D31519865D0DD07004B21B0D57872FBA2A00245C2702CF2C8AB91C5A5AF8F40614FBB1279C66C4F2405B4221EDBB8B35FC5EB65707559A29A04939C5990633680771D76E302616DA2A5384D875E5F2C3ACD4C96FA74CF88090B22540478161BBC14B8B6121607239056022EA3947EF661D72B12227889C2E1C266A7A60C014BE19E0328817104027475CBC78CE2C85012017EDDC0F7CEA11C8EA72AD3338498292BEEA4B8A7129D71B1927FAC2A6921DFB87C425F9CCBDE2BDD01C685E3CAE52425070C5C00EC8745FA538E4F96F72D89214E042F19734D7E57952D0833C72276CC93D9991A1AD99AE0CB5886FB83367C967CA65A7AFD022DF404DB0625FBF2C50F0D8812FE2BB1DB4351C7CCA96018A07A6AA62255655A59319AA9A0F130387AC5EB3BA4591A68130523A6D023F57D7801C71BF2237A17FB3590B240FB03037675A56CB85A68EC0C4FBEC98A1C534EAA4C1AFA1B7A012AE871C2EA6B34B3E661A90713C66A0A527676143CAB465205ED21B1E82050343B62CCBF875A2B13D752AA9007426D52661E6E1C42446B7FA632332498B53DC68D780264E1638BE1B24C6323BFF427030130A3091772988789CFC65369C98CF6A6BCFDC99CB477D0D120531C8AF46613228CC687DB38E984C269FA225E61B4B5EDC4246849CE2578BC7519881055D00295DFB560152F435E7A800F5E2BF2299A2BEBA0F0EA63D2B3550AAE2518EE80948E9961BB74D5B5B8C65C2C7C2229158B017B9250B2200809C8466387831C08B791FCA10D2DB3800429B35279310403566934BABE1776A3A01EA24AE603A99613B63596360748386C8F33EDAD3AD33C5620DBB58FE81B76B960A28C8A893F7930F2583AB0431CB15B6D0EA97EE76045FECB2FEE09BE411B8AB827236C67D65C4B548A43999134D4FA3735629CFBF3314EC955194C8BDAE1B6B32635F27427DF0C8103639CBF7301C4C36B896E853C2377C5C155C9DEC611D1B6BBABB6777B6A95DA79B5456007B30CED6BB4547056C7B08B703A774114B036DC081BC896BED96C8F7C8BEC4EC945CB78E21503F04F849C053A9B7E1CA5E080325972FF9310B12B04BFDDA31AEE5C45E7BA024133BE2B7B389D22D3C9AB4CA34A31FA902571ABD0C267DC23157787B368F1352BA6A0F9D04187AD29CDCBC382DCACE8E31869CC2C7A55097AECC218FA68509D289833988EDC26B23B4CE26954A15041465A7287E372CC6213F7988768D105030DACD01B73B5F2145020287ADB92D63DB8D8E16A231618D4DD97851335C68811789428E8A8280519A81A215774B103981614224E35592647823E633E951646A1912721C0AD5BC21DE84734E285653B0858E5B325699B5E31C027B266E7E82C6473072A9E49B0B8C28BCD163ABCC7A3F3251601B4719F2894F1089FBB37F1F760079C6286525551BE7AC73E52926B28FF3F89A663043CC3C5FE2BC0312C3A0E1206583633F0747013C42A541E5CD53142D19D06B7E930CE1F68485D700BFAC9A71977C37A28CB11C703AA04FE533B58F6826ACC1AFBF25CB7B0A7890C427FE7069120315313C0A45C18C2EEA868243B4F46A03622C911A98ABBD7C2EA3305A5237AE76838350EC1512314A7CFB19549283CF2866F3FC3F429168A461034830BC4FCC2A7259BA6A49B256CA9066086A1BFA64712A7E5EF40BCC758B5A600C2717216839BEBEF900EDFBA4126C89047328A9849E80A596FA930D666099A9978085508F9AE8CD1A1325B4082457045A923410C84A0EF382BEA75420883C4E3E43183E8B9BB02A7030051526055910A835AF9053BFD66B378CB978AAB14B629F88839F3A4A7F985BCFEE440939359C7FF98B668202149045F68418466C45E76517F9F7389A683B47897A608A2F85800F7795BE75799DFD597057FA3F86C84CD52A4140758AE45B51F80262DD56337562A974B942DCD20EA2BC5C52F225DAF5A80BE0AED045A7E812819F646D28B0578D042C8B77C8341B46102BC881A738DDBB43411B43C41813C4C28D75400BAD4902ECE7C899FC7FEEE32C78D70165DBBDD139BA3EB2210EE3C1F6BC2B31C8C73B1A54657346C3D322B243AF797A93E7129B17FBCD3C7B9CE49216472BB6DF1B2F41BA4EC3813EE6DB3898F19643C38FFAF3880101B08DE8370ABAA82D91BFDE31B8F78CB85474A3BF06844A233E65884303CABDD1BB52F23C01512871A6FB50DCD3A2417140DAB019A11BC10176C5C83BB138CC2BB45369FB74995613CCF71426CC45536586A9ECEB63877494C4789E62B33BE19B87AC40357DE584F11B236E389B26A5578232478E56B798FA77E6366EC15046B38B4BEE0255FB6AC0B8B928F9F3849417B7C76A396D0B58DE16C709E58D5C523DCB6C7EF74C60960886926B4F5B472A7D2B419DB06592691B0F7299EE970B8ECA7F74B1258AD17C087C8EA0F1AA37C40C631CFC95ABCC465F6315C54C7531FF559F19B952406FF1BE2C2C55A5817F1A9B11AAEC3112029860E6400D99E57DF796A8B775C8C5060D4C3DF45BA1405A293656507D39C8FC3990BD23E6735715792EFF440A9BEC79C7F5FDE9", + "690D3DA51B1D22BA09AA62B4FD6EADFB4C587C34FC434C62225B9D132DEDFA5774B4ADFA213EDB328DFD6056CEE8F96EC1454C85F8037021F22879FF0BD7FE1386BF272021522F774F10C4C9F7A53E18E3A7023DEA1C3BC8BC76EA8FCD2BE2442A655F2E34F3F102919B4C336B177B038A0CDE0A2A49787E89AB005999F1AC733A04B867D557AFEC7502368CF8DED96CDA58FD0C0426767AC2EDF808F8A03B45D72B30D354C9792FEF5213E7928399F09E2DE540F4826ED72F86C02637738ACF28B28CBC8D45D5A7A0F4AC5A1B7CDA2FE6AE3872C6985E61E259311D5201A540B4351DA0E794F3BBAAB916E2603633741A7878BF61B3B344715D6DCD614ECDE5EDEDAB3DCF4DB03582CF12B764179ED88FCF5FDB0A550522468E04A5FCB297EA78C1DC6DB4CB868F7B1D0B195A16CADB15C28DFE7D2ACD9C2399B6461ED22D000F3368E88BF12F32BFE6B749B4665978C297314DB35122C7D04738E38F7B4CD8246FD36B93624CDC7F0BB10FB482479EF1E1FFB2F85094C9806D160467832D604FF7945CE2D6BCDF15802BC2CECB90FA3F109987BBB377B4E0B092B64F712E3605B3B11E3377453538EB28406243C9C182858650F70CA9AAE1B8E00E3699D2C47038F2AF7076CA6C2330542FE680D79C463F60F80192F85F6BFA0AD455712840F0E25DFDE29CB98A68FD2EB4DAE3C536967D5C4615788AD70A5451ACC78A5419979EB35F83E2DEC8A9EF3DF19A73225832FC6EF76A19159E38DE1BD15B6931F4D47C25024AB2DFB0A800EDB9E070E1FB3628B8236AD227AC3F6603F1866C4CFD669F992C50C06C1986868330C4889B3A9F77DEBC702F3A6337A549B1F51FFBB7201B04287DFA6BF3144160DED6206B5AA1F9A03CC0D56FC53EE55C8CD9A23344BCFBE1439904A3FE6A225D3DC16BF0BDE2B53F90CC0064C4A7DA29E93A84585161D6B367063DF1AD2639E94F0F61455225AA72C294936293831B7F221D209D30317FE4D68507822BF667C8175F23ACDB14000715D26AB3303C46D2E9741F03A73C5FF80B50E2750744D747E295A6DC2D6B9C5D12F0D711267F46E61D25388A5AD57F8ED0EF9CF99311A6A14D0EC5AA5BD8046755921930406B786BB015F4C5B1326650CF8A6EA2FFA758C4F3250F235CF4A824807BFF10BF54910A610B1361B156980ABDE86D087FA133CABE34FC5EED86C3332B86A84742ABF33144B8B08E3E22C845A5E0C2ABD786DA7A7E01DEE4558365857B384CC3F398D74E157CCDBEBF8ABA82AB7804303ED27E280BF68AC3122F6881B3F75C0F5BBB69F6C02C4712FF8B9D1822686CBC441A4C81BB54DF79C90E32A2C5464C0453954DE231AA0D01A0FBB868B4467D1AB6035A9F0C85C1C4016F586B7B6E653689331949380A00CC8ABBB265089606F65E324FEE9AF4CDF02B1F6685AFAA05E2DC9AA17AF7E8131D1F1E3D2FFDB9592C9C57CCDD619274D547FE2285A8989DE7926C654DCAED5613CB4DD4A2E0BBF9BAA7DA1A0F7628C924927EC3C339A38E73C219CC79EDB4904F97", + "8B6AA77088CC998C2E6B42ACA57DBF3FAB786DFF66ACB017B2ACB48FDBC73D07" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "11D14D803290BB20BD026906B869C1B8780E3ED23F3F4ABDBDD3873BE9191CB67E8C5463B3A21C5B6C43699450C6B4CA2A30249EBA1D5133887E9A4F005C4724D46533A4991A12AA905588A484471F76AA7F38512ED20B4EEC05DB8734E340799AC23546D9C8142C276A46B58874AC6F5641C6DB2A2981C45C310E2171C3D6B793CF4B2B6F0B30E012C2FF3234D07C9105D9673ED3C9433918F70738E10A9F3ED7C4CF506B1B60501BC833BFA3A001C36C9FBB9D9B118CB444B575A768F54379E8C25E4883A209E3B68E141679349CAD62771A0B855F7722C27BBFE4B54F5E553DC4485E18A08598C32AE057C2A241273F116366FA943039B19F0B817CE6691533120A60ACCD62ACF6B5868BE05CDC9A08EF47CC1CB3587A82B699334254F6796C538465120824BB2FAB3172AAB904F9768693306301627F87382E8D77B3D69A22CF878E7998B3226A14EC19AFC88445A7243FCF8308DC8B351D402AFF98B14840ADBBF50F49A14F018A95E3871CF7C75EBC1C26717C20F8BBC87CD2900DD6518129789CF83D9FB0664B966BF394BF213A0F2FD7C0DB493A13A2B8B5ACC5B18929CA325F1C51B037148CA0E8A401587D570B067FD14B52620D16E4BBB74C2EF1E7B4CD74B15DFB08996AB83D8396DA99049477450C93B24C0530AD5B2E9A305EC6B63A09954D1E961B2052A6FA49C4A55CCA4DA1C4711383552CCEA53CC572B6481686B71F12325C03809A36C02BC0835D28768D42C942E97A9AF1C007312FC0560EE1010938E146FC9C07A851C7E07B655EA2A85E777DB3526F0882AC8B011879A015CBCC81F2BA22193640A5A045D5B650250992995CAC5E9058E8EA5ED1D41F8F479E4509025E3CBE83F567E2932D2BF33AF773C5BEDB8EBA9A2240C530A7EB61380AB5AEA96D1F04AFCD0ACA9F04438C743CDBA128F7F70B7C7901D98616B6C49C5CF557326552F9B1CF8FF019BB38CF527B84AF4055EC180CCD5066CE96CA82121E0CCC3C61232B10C532359ACC2406CEE37945DA11CCB0A69102AA510E55195CEBBDCD77705D2BBE77F37B8657655048ACF06519B47B2FE469891C8303939A3F4B68B9516B38430A6216ACCEEED049FAA44FE2D17D6FD15797630CAA001595CCB3934195B1365263D861BF4B27F1C70A500BBD82054B8192417ED0626F077AE670B23CA37F8AE64B8DE49A3A3A70C081CF581041846861050088FAE35F44037549E5244F385B88997EE5FA70094B4FF50B531C87AEF1308AF91731056742F96967C2206B076A1FB219C243A74AA0E607CFEB9604D04ADCA3904DC397E1777D3B58197EC54D37795CCBB4CAF23A5A546672B0C2283AE7AA5C914009A511EDA293CE06AF182A606C23A5EE4458674170B20712C58C8CA87CAD4A8739B1E32092F9AFA24B8DE6CA70040AA769F9258AD144E1CA8D635031FA70A710B3B717FB65304C7B23C553067688C8658F94154CE79083B9A1BDBCC335A525912AE0466AA9B9E3D926C21A25FACC56BB738949366CDDA31CF38551E104BAD04C3CD3866DF028AB7C067AEBA10E751C534ED886FB5C4BFA0051FA7B23D50B80C1A84851847D427009767796592A79957B25806A613E39078CA8C30EE18688704FAFE5879DF63A3E78FEABF45823C3A23E8A4FA58FFACA18FEE9253CBFD62A05FF71CC07", + "195006A3550B231C8348E6B3B5B386E9E3108AEBBC8F83630606586EC28635E58878809A5A53363214AA48C3508C32929090280C366CBCE2971332C96F05551F06814F340B5490BE545448EA603BDB945B5B778130CA72AD490E3FDCCD1904487E1284EE392941970D44CA314F38BF6A22414192A1372536CF1C559A48A5A89011D935781CC54E6BD43F8CD3A952C6386265971212C21D8B6BF0CC0B72D560DBB79C0092BC0596BA5D5B70A1C48C7E474163B00CDE389ADC881BD58075C5C43D22A28E1EC51023B27024249C3382A25E26C56DD651E92B45BCB96F8B41C671C4730847253A15C1C2061A055603397C394157570848A88D22C4B1FA0808F65CF47A7CB5B06E149900A1DC9E8C4C58BE1B082AB3B99AC34EEF855216F4B4D9D276A687636DA8938056AFB764C554D07A9A7241AFF51B052A475E37521390906A241B73F71F5E8913357C8257392B17430CF76154AB6CAA1AA255771954CA3CAF731748D870A99AA4097183BE1013C9BFC7CD78B8C77C4412D69A518BE91C2DBC72C2656A2FB18231B958714513C51C71CC002139936F64B8C6879C78BEA352AC82691041C526CC97BE790D07DA9ADE6B4DB28953A233B0B7F0AE0E08AEC82256B70A51BF893C1D643E6629011537B845050257184E36B3A90B008382528F0FE268D36453B08894115B3C10617F4A8A3C63E748AFF07B60B76179572DEC958531DB5C903C2EE826C18FCC40636B28E5B37C0B47349C4409C599614D1B5E664B12B95B71C46A2DC76979B23B889673B0CB860480598984A78BDDEC5DBDDB8463E7941515B804159D46E8B51E24139D557A5E8450EB84A3898153568609D382287651003528237325B291D28BB4356AFEF1A903D9006BB24F9AFA4CE0E4A490AC32FEE2475A864E2B74BCBF780827CA2F94D855E0117A6444BB31B4383B2566B2140825025375AC17DA535031456E5EF95CF7E95355D11C7E3C113E589342AACCCFE5761DC21837BB8E51BA9415C2AF3F352B5AD57CD9288DE0643E0EE75D9019C3E7C8BDA6B6645BE63E206925554B34B95B34D33C05DB5970FE016A6A51C86051B6C364A80E832E0156AD688A42E73A6D20420CDFDBBA7B70C40436668BDAB6A014CA920B2A4C34595C187B20D430851265C3C858213C57B29C01AD822373A231598633FB027EABF40C7C15884813AB59A39D18735E64F4622B384C73D433C1505183249044B61857846F9A54C3D3A213FAF2CD9A33194648375FAA08A05AB96E52464B91083E60C7366981F8C0181CB8B4A6342A08614A4123285C8595EB1B1F2B1398EE670393117A26103B41C7C7282166B7E49F745A936981AE9F0BC73CD74F97F6AB133250DC081DF88B1E4771A39CF3BE8F64CE721B5A828528289AA5D4EC6FF0463191D3BC6221124B52C405E88E96EAB49B435BE9415A91A68117C5650E53613A78AB2B0915A4FACA6545B9628999A3A46AC5855FF2406613101B36A13AC31B55E8D118F4056074C78275C80D57D9798819B3F8368F19826A728A9CF05CC637690BC971A86186A97A2889F976BB4654A778258D91D37E2E7B13B584817B6C22AF49207997BABAABA5B7F8665A710574A22EA42B4736E720E57C470A274211D14D803290BB20BD026906B869C1B8780E3ED23F3F4ABDBDD3873BE9191CB67E8C5463B3A21C5B6C43699450C6B4CA2A30249EBA1D5133887E9A4F005C4724D46533A4991A12AA905588A484471F76AA7F38512ED20B4EEC05DB8734E340799AC23546D9C8142C276A46B58874AC6F5641C6DB2A2981C45C310E2171C3D6B793CF4B2B6F0B30E012C2FF3234D07C9105D9673ED3C9433918F70738E10A9F3ED7C4CF506B1B60501BC833BFA3A001C36C9FBB9D9B118CB444B575A768F54379E8C25E4883A209E3B68E141679349CAD62771A0B855F7722C27BBFE4B54F5E553DC4485E18A08598C32AE057C2A241273F116366FA943039B19F0B817CE6691533120A60ACCD62ACF6B5868BE05CDC9A08EF47CC1CB3587A82B699334254F6796C538465120824BB2FAB3172AAB904F9768693306301627F87382E8D77B3D69A22CF878E7998B3226A14EC19AFC88445A7243FCF8308DC8B351D402AFF98B14840ADBBF50F49A14F018A95E3871CF7C75EBC1C26717C20F8BBC87CD2900DD6518129789CF83D9FB0664B966BF394BF213A0F2FD7C0DB493A13A2B8B5ACC5B18929CA325F1C51B037148CA0E8A401587D570B067FD14B52620D16E4BBB74C2EF1E7B4CD74B15DFB08996AB83D8396DA99049477450C93B24C0530AD5B2E9A305EC6B63A09954D1E961B2052A6FA49C4A55CCA4DA1C4711383552CCEA53CC572B6481686B71F12325C03809A36C02BC0835D28768D42C942E97A9AF1C007312FC0560EE1010938E146FC9C07A851C7E07B655EA2A85E777DB3526F0882AC8B011879A015CBCC81F2BA22193640A5A045D5B650250992995CAC5E9058E8EA5ED1D41F8F479E4509025E3CBE83F567E2932D2BF33AF773C5BEDB8EBA9A2240C530A7EB61380AB5AEA96D1F04AFCD0ACA9F04438C743CDBA128F7F70B7C7901D98616B6C49C5CF557326552F9B1CF8FF019BB38CF527B84AF4055EC180CCD5066CE96CA82121E0CCC3C61232B10C532359ACC2406CEE37945DA11CCB0A69102AA510E55195CEBBDCD77705D2BBE77F37B8657655048ACF06519B47B2FE469891C8303939A3F4B68B9516B38430A6216ACCEEED049FAA44FE2D17D6FD15797630CAA001595CCB3934195B1365263D861BF4B27F1C70A500BBD82054B8192417ED0626F077AE670B23CA37F8AE64B8DE49A3A3A70C081CF581041846861050088FAE35F44037549E5244F385B88997EE5FA70094B4FF50B531C87AEF1308AF91731056742F96967C2206B076A1FB219C243A74AA0E607CFEB9604D04ADCA3904DC397E1777D3B58197EC54D37795CCBB4CAF23A5A546672B0C2283AE7AA5C914009A511EDA293CE06AF182A606C23A5EE4458674170B20712C58C8CA87CAD4A8739B1E32092F9AFA24B8DE6CA70040AA769F9258AD144E1CA8D635031FA70A710B3B717FB65304C7B23C553067688C8658F94154CE79083B9A1BDBCC335A525912AE0466AA9B9E3D926C21A25FACC56BB738949366CDDA31CF38551E104BAD04C3CD3866DF028AB7C067AEBA10E751C534ED886FB5C4BFA0051FA7B23D50B80C1A84851847D427009767796592A79957B25806A613E39078CA8C30EE18688704FAFE5879DF63A3E78FEABF45823C3A23E8A4FA58FFACA18FEE9253CBFD62A05FF71CC07B568CB4D837941CB1ECAE7D1816414BD4C3087042FDE3920616002F9CC6F94FFE4F7E02022A7002586990349F68FB68A93A302E8C21C6A385719FD8987E9B902", + "6618487F983BA7883B55EF192AA5AB0132F0489334F6756286643E4C1C33CCC2C395B90BE43202FC5E00073A35C3D08C378FCAB6E2F0CE0FCCDF4F684B55DAF3032818712E426F3E1F57BBE813D67E515E7C343673464322E7B63E30604A10156D1F79ECC57D05BDC55EEB7AF23C9902EFD4F3BBE2A79A1A9CB421D0158297F5840D02AD286C40D607059D3C926647BE162B333973D6F89B6CE4028C7B3482EC6BB2A6FCB97EF59BC1556D2940675C587EB24462E7D0D0584C6FC2E9FDBAE3A7BBE6CA74D6D3BEF8E05F308A7F6A51AC1AA9556ED7E8A7529994C41B34F36314CDF0AD9F07E1ECE10214CFBFA656D1D492810A66ECEFAC960D1377DD1DDA18BFDE0E8363A161B621BA8C37AF3EEA65491F40639823B555134D92DD622A367EF7CC5408F2CE18EF9B170BA2FC62004FB76B2545A54F68450CBD9221CC89A6413B0B1A80D3C6C039DBD1EEF85F4EDB018CAAD07CD17E33B44CE418368000FC000A10F82CA4F0EB860B46CE1BD10CB706DE0263660EB0BCFA0737700DE36E2C2F349AB8DEEE35DAAA5B983215D9E8B801370B93FD116A404BAB783C6E37321C8AB86EED41072315CE271DD4B52BBA7D968FEA1ED693BCEACAF6E20F3F4AA9FCBAB6E7D16D3CBF35B6CEA86CF6A1A88AFE50AB490F35936131F45425B94AAC5A83D16164D348089820E7ADF5253213293D05DA970A1B40506C76E65EF4A59345D00DA5461D4E188C9EEF0DAB41E7684E31F3E20ADC71D6FFD89552931FC634BF91F465E38DBCAE1FBB491AFBF1530DAEED2C68984435262280E831C1E9C9F81AA0C80D91BD57ECC02A1873A27EC3F09E99656687997B9E05460A061F3920572078ECF4BF32E6C42E06AD27EA06425D09F58907ECAE51834864ACAD3FAB372AFC0E1A789A1E98C27D523C2F5068E88E5372FCC8FBF4E5E7ED766C561CFEEC2B6D1AF29607CA7C4BCA48365A15B0C3C6BA585608DC6898FCF4C14414351C8AD2AB6FAE6C028B883E27E968A27ED79367EDBA6B1155A3010D42A77CA7EC2F2525936648671D95011B5BF019BB5466C881AEF38C75E1D6CF775AB2336CCEF8346D6B55B58F7F63026E9C9DC38A0E6E2BD550DB4CACF6433DAD6294EEE825928DC71ED003A6859C16CDE0835FBEEA446394424FD517E94A7D3730EC9029357A54A4ED34EB62A94A58D99097C5161CE5CBC6CE312AA625A0EF83EC51902A4959CBCD9A056DADDF7E2B26036453BE57984C65D68859C00DF8E1C1701595CA2DD5CBE3FF3150C67FCCFE765DFEB2A20B7BF1732FD083C14346FF2F7501DAAF6F6B77954A59F7389A7469F71248A2C70C02EB0533A099167713180A74EF90D5EF3F672BAF5C47735CDF9A025D114A062D3020ED12F0EE1C1AFACDBDBF08A3E5473ACD47C8D45B3F250560337BA924EEED08D5D6BD8AD684ABD18B442F8AF9E125F2486CEB81C950080505A0446995B79606D4706C066C6ADE8EBCDADA3D6227890DB24DC7D1A33BBCD1722F8FA7A6B5E8CC37971FAD3F878D2CE215A055779FF5522E9CBC95B7", + "29759A642C4D0267BD5D96C81449F6F9B315FAA45C1D5E117362D4F096D5276E" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "BE0412D99A23CB207074F8A203A4421678ACFA3A225FA5C560055E8D380187EC6845DA3BD3611FD6E917DEE3CF2830C52C026BBA8A6A31578B942484F0079E88B2AC05D7C453D73D3716BEE80C698A323D2D5331B046B86AE007AD40CCE3927A75F4894432C7D235B4B6610A792920D5F0CBEA389235784EA91BA02BFBA238A79FA2ACB6B2A91DBA4BCD0678796D0BB4357B4BDD849762F4A7CBC69D163C7874C9ADC92B01EAE8AE616461CC89ADF41C415E484B94BA43FCE7AF7B520A598B35429809C109CD7C048B9C67C70124B597C1979A7A31B7156CEEF849C720B39406A32D1B639D18A1D0E462699181B9523FFF361AC995BF1127A4E5046C32F1A1E102CDFC431B060975A7437EB765BFE9A486CE6A52E3E33CEA47766EAA9BAFC819F248B0520313EDEB524CC6BE7771C75E96AA1096507CB18E9B101CBC21132A7337D78C0684E07C3AB8260E2070A3825EBC625F8851CC3E653011DB01DB07CC6B350A68652E31AB630FD373B75A1099A72C35441B9B6127B99469F95B503C663C9B3634A212936B3023FB4B50E8186619B00925639F52453979DB24D2B8CAACD61094D1B14C9597DF53339105C1A6D89BD6D626BD6C5D0E1BABF903CA8B4B48420A137B729A2EBAB17FB434EE258EA5F4CF9B9B1F58E85E343292981C0D02C4003F52B2F37CB3E7CA65AEB8A7F2EAC05634457581A9ECDC487223691263B696F8BD1D685770256AEA5A94DB60AE05A501835848E2F8CE8BD7CF5D1365E6120E18D456366B19E9F1ADE4C552050A02CEA89B8F99BF89B36C08232E13F79A25310934E23FA4ACA724761E12B32322F2744D93A6E4B0997B019C6857952369035F284D60D70581C593BF4B5749987B2E569941860E1619AD1D524469E987B7261F2274739699935291656D114525400984865B91895EC6C39EC54925BE2581D24A62D7B2785C2C697FD61C14C28D1A9568C9C331E3D749BA6597D9BC94CF391A7E3AA57C52C7ACBA8A6A85941BDC59CF57CA46336B25FB9BA93CCF8719A0057969A764399EF2CC3A81AA1C4534E195151389432BB43EC54A2DB2DAAEE068921A6A275333AF3A66C22E924C9CCBCD298663D6C4048BB09E8785387F8A291B3C15E72CAC44C6360EAB290F633FAAF4B023D000B03371EC885EBEE4684ED39A3BD03A390A0F7FC72F5E9B8574A23098404E7F4620C7A8411370B2AD8813DCC91011670FD3A29C088303725CB2425C783AE71539C75F96C1B1B395BD936C118B0BCA994627F32A6B53A187884453CAC606C39B81937670FA915A36F44FDF00D0AF0CBABA707A9FCC3672123D4EDBC1E7F30692400CE8E83E198A5CB692CED4363D7781095E12961BD27AFE1948C8F7259E336A2531082A2978C72BC67AD30BCA086C51A7BCD57B7B15F64E332C1F91AB6015105893917102530459C218DEEB58F5DC9DA5262B7D8A3159B43154F8597E5C57CF37400A2C560081B098DC2C20F6B5CCECC6BCF5B96184B0F7475076317C2EE5482ED83FE058108F762958E610041963937930C3AA3E6985423A33A07E77613F7236F0D9911AF49344A15D77C02A68F19C661704EF515871659F050251BF4CA9074A1A2B1A028FCB92E8053DFCAA319334C6443FDC1F8EADE4EF0C36949A1D36B440747C8D27DEF2FE62C033D6C17CBCC8C6", + "A7F68B43898F7383B09F0C6EE0D97377D454D528132DA90AC55819A461B58424BB95C7C00A246F04F8B03D3C9D62389AC2B45DD6D43F32072C86E03812909650C52A0104A42696C5E1F389EE4A8775A9A063737A5AB41D8C0C0B8C49C822D7351C1A63BE677D49018CF18311775926746520D650C1C31C0BDB6B570C96BA6B06915815C0FCF6B32F583E80C2B7A84B805ACA39F676426A463E59D6C904042761833CD4C0C0336B00D7E158DC774C5C58BD71458C7C74459682245A03B3C8B8522B7448C3A98432C48495E51E7B401EAA8669707C16F36B72FF21623838B31B496D56B12C0747587325A59509379D2706670C573F85ACA0F426119254D5519D759232C5087B84520F2459148DC6A86184662BC368BC2C83FE0CA7BE156C67C05025A1161BD1380DA39BCA2C99EF727B4DD90D99C21209B573803953129C4DC82A279ACA0A73833C5BE189187546519C2E17EA895CEC1EA7D46594297FF43CBFB7D54466B21F1DD4B72116C10B6198553AA0273CC6F38CA9F9011985012AB4F44C7DC13B00A10F646456D9B29CFDC368FA610C49F1BBF75B5759480A43CACAF99C8BBCB5873CE1CC0D091F6282CB6D1A9FC34459AD0333C88A1C7FA3132DD2B415F809235A101162120CE0BB53C435EED595E01273622CB6A33222477634104A64909A2CA19956D0E0CBDC6A8A611128DF161217856737100205E1B1E9EC844C447E4A4BC538157D5EF37A81F3BFC0F347CF14BD3F75C18F53A777CB0D381B0AECCCABE4005515C911A2C4C7123447DFC93964262FF05A45D969551240BAE60B41ED698AF8E5193BF409862759599C598AC63460F991D47A18A7E7A101964E756603D3A4747A10179CD77FFC1614B5B15D028B7F5794BF7E46B09DF68EEA6744ED117EB241B59095177314194E6C9BFB3049AF1CCE267880E810A855BC5A30177996C22CEBFB58A93331395C52C0809813A2600EB2CE358473DD9A25D8C149F515A5CE10335E0A716D1A09AA817ED6959E18B79ABA93A7CA25562E458A294B767AC5BC860756E2393DAF0507F185C7DE839D2E70885885973B561A660A8E497C0999F99D6C7C66AFA2C1A098A5088685F330969B3526D09758CC8964E3B543DDA6177312507730AEB98C3EA4E4C9478499DD676D2634A7BD69BC2FF8CAEC434BE2F58428334B4014255C4654BCC3A46B737E486C424DC019EF071FDFC817AB7B35362313D7787C73EA9B411CBABB5526441999C6E9ACDBD581987A4A88A421FBF42691A36629A37E7ACA126A7BC68A9BBDCF270F2EFC8E12C328B39A6C80D24496931C012769559A8042F0C2B81158AD77493949987295947AB5CA8EB13B2D668990291CCDD0703FC046C38301CFC350EAB92B9307A685D9BC43E4105F8BB286745E60A4A37E6966F2F7B558F8427DC17A122143C12271A276A0C6D28FF8410C236B68C8CC75D46B403F430716192A47FC7A8BC2CD11528870F7A5AB52A752609D42A05250538E1CC07B4E278CF2977D14F9BB1BA701D771915ED65903BB5CDBC5C1FCFA1D4B04A43AA4B48D946A5B124E3789AF2C34BBAD31A17839653E849E2B917230824887193568FAAC42F533CDF4B31009950EDB065CDC498536A3101876BE0412D99A23CB207074F8A203A4421678ACFA3A225FA5C560055E8D380187EC6845DA3BD3611FD6E917DEE3CF2830C52C026BBA8A6A31578B942484F0079E88B2AC05D7C453D73D3716BEE80C698A323D2D5331B046B86AE007AD40CCE3927A75F4894432C7D235B4B6610A792920D5F0CBEA389235784EA91BA02BFBA238A79FA2ACB6B2A91DBA4BCD0678796D0BB4357B4BDD849762F4A7CBC69D163C7874C9ADC92B01EAE8AE616461CC89ADF41C415E484B94BA43FCE7AF7B520A598B35429809C109CD7C048B9C67C70124B597C1979A7A31B7156CEEF849C720B39406A32D1B639D18A1D0E462699181B9523FFF361AC995BF1127A4E5046C32F1A1E102CDFC431B060975A7437EB765BFE9A486CE6A52E3E33CEA47766EAA9BAFC819F248B0520313EDEB524CC6BE7771C75E96AA1096507CB18E9B101CBC21132A7337D78C0684E07C3AB8260E2070A3825EBC625F8851CC3E653011DB01DB07CC6B350A68652E31AB630FD373B75A1099A72C35441B9B6127B99469F95B503C663C9B3634A212936B3023FB4B50E8186619B00925639F52453979DB24D2B8CAACD61094D1B14C9597DF53339105C1A6D89BD6D626BD6C5D0E1BABF903CA8B4B48420A137B729A2EBAB17FB434EE258EA5F4CF9B9B1F58E85E343292981C0D02C4003F52B2F37CB3E7CA65AEB8A7F2EAC05634457581A9ECDC487223691263B696F8BD1D685770256AEA5A94DB60AE05A501835848E2F8CE8BD7CF5D1365E6120E18D456366B19E9F1ADE4C552050A02CEA89B8F99BF89B36C08232E13F79A25310934E23FA4ACA724761E12B32322F2744D93A6E4B0997B019C6857952369035F284D60D70581C593BF4B5749987B2E569941860E1619AD1D524469E987B7261F2274739699935291656D114525400984865B91895EC6C39EC54925BE2581D24A62D7B2785C2C697FD61C14C28D1A9568C9C331E3D749BA6597D9BC94CF391A7E3AA57C52C7ACBA8A6A85941BDC59CF57CA46336B25FB9BA93CCF8719A0057969A764399EF2CC3A81AA1C4534E195151389432BB43EC54A2DB2DAAEE068921A6A275333AF3A66C22E924C9CCBCD298663D6C4048BB09E8785387F8A291B3C15E72CAC44C6360EAB290F633FAAF4B023D000B03371EC885EBEE4684ED39A3BD03A390A0F7FC72F5E9B8574A23098404E7F4620C7A8411370B2AD8813DCC91011670FD3A29C088303725CB2425C783AE71539C75F96C1B1B395BD936C118B0BCA994627F32A6B53A187884453CAC606C39B81937670FA915A36F44FDF00D0AF0CBABA707A9FCC3672123D4EDBC1E7F30692400CE8E83E198A5CB692CED4363D7781095E12961BD27AFE1948C8F7259E336A2531082A2978C72BC67AD30BCA086C51A7BCD57B7B15F64E332C1F91AB6015105893917102530459C218DEEB58F5DC9DA5262B7D8A3159B43154F8597E5C57CF37400A2C560081B098DC2C20F6B5CCECC6BCF5B96184B0F7475076317C2EE5482ED83FE058108F762958E610041963937930C3AA3E6985423A33A07E77613F7236F0D9911AF49344A15D77C02A68F19C661704EF515871659F050251BF4CA9074A1A2B1A028FCB92E8053DFCAA319334C6443FDC1F8EADE4EF0C36949A1D36B440747C8D27DEF2FE62C033D6C17CBCC8C60DF10A55B73E721350FF5FFDF8C9717103B3F242F12FCF292DE0CE75194E2E59678218BE4EAA47762D1ABE76C755C76249BC0DEA1C5C1625531BD1F86FA0AFDA", + "6C69EB30D9636EBA9EE14BC92EE730720D39E189AE3ABD96367580845A82F27C6C85F7135BC2471553CF1B0E0F092D87AEE9AE24649D6BC910A6C6B432F20993E562C5A1777BD801A7F1C05FD3A9E8DF57A187CF2637F99C6E24B5DCEAA64DB892796803DE9C1B6EB9E297440F7051D668F4781764F84CE499D6E7F6E4086C1F9B862260630E1B3E6C4BE52EC4FD99670A345659E4D865E5DBFD19D6412B4C9D31003D36EB9A1DE2ECD3A495B9E5A44D51BF85610EA867C9F4F1F09E10667A4919207628B2FD91330BADFD44CF491CADA6FA9AECDE5E20CE8AECC2986647F2656869E6201D851AC8176D98DCADC5ABD396B0C4B468871D0EB9332C264AC7550CBA62F77655110C4D15DA73A641F67A7821D7C7EA81CD4DD1BEFC5CC056883E74EB8DC985CA193ABEB30865A59C86167DFB51F96891D604577572D61623950D5CBC20F2752E6C65662950F7D69C4E6D883830326539DBEE1A1E683D74E1B261AD1D825D57FABC3512A405B172BE7AC22479E4D2F834009337726751CA617A95A6E915E50755FD644D600AB670EEB5F1CF097CC521A7EFE8A712E52FC91634EF0A3B87B91370444661674D9F1D0766DE59CEDC70CE0E78EC062F7A50DFA575897BB4A758FC7D49A92C6CDCA5020C0408A7830106529CCD6CBED34B0D5CA2AB68F27CA869ACCFF363BD546CD6EB6ED3589BBAE0D7E3101C71D63220140CE0146DC2A038B4C32749A4B99C3D9666688582984FBCC82F79FEF746180D05B8574FC42BE26E35961E01F2EB634CAC23BDA5D798C7264223524A040C9EF7D42673C7F6B0F2611467580EAAD9FFCAE0291962A98EC23C7351D620EA02723A6493E6354ABE0373FBC77DCDD022025F8C7F94C3476A0E400AA7414F6E50584E14B7DE84968F47083CB228924551191FA1031FEE39CF9A0494A18E34FE269F980A15594A6F68499FB01BCED9DAD187DB29842D928755F618D08B3F44A243257D7EBECADE361D47758A3E3B6E06601E4F409D2208F36397300978FE8173082851DEC328325BA05676848B9198E46966EEFDE2DC72417841E82F9848FFF6BE528F147648F881CF9718E6B1F7E0E20C6A1B37C5EED42DC6B982CB2232802CB71E83123DB105E6DD068BCBBDFA964C9955B2D93B7776EEBA03C5650C631D8F05AD84AD7D8190ACFFBA4977607AB8CB19788BDC7323A7A1D91B7AF8BE6A4386ADB47BEA4B4D93C01665CD605D5677B9A2B75A7BEE386FB1DABA09ED209915616BC544167B97C9E23DE77B757D5B98E63CCA9051B6D882313B4477D10B04128E6FBA7E1EAE23FBFB64C8D091EE233FCDEE91A0EA195CE511C3DF4B24C17B9D36389EF5CEB3BEE6D9A50ED35E3BB72E95040851A4AD2910CE6EC35A17AD1715DA7BD121190876203457836838B0415A53F62F9A6C4CB2B1B8E811FD78023FB5A119214D192B813E9B82B82574D36A5DFB1EA9A03D20ED2DF12A04944FB9BA283E0B290BA7370B5098A328AA70A1455CF166EC6A6DDC0704FCDE258E1F7363B4A46B4AD1B6E749D7CB8F", + "F5D303C2E38227359BA4A64727A9424DE88D41EEC961697385529C4587980D62" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "084E32F1DF38B6A73FAF446541B746AA3F026119FD6D53410FBA8DCAA060AEE99E5A325ADAE77A4157E0F6372B5F34D24B05C2D6BF9589D9CFD8426C73464C350757DD655C35F577664CF2FDBDD1C8455E0271185494D6D2A42DFC62B61367B2236D6463A3A55F225BC7E66FF42A9C06BB419F7DF5F26A343792B82A81BA6F450D2D3F91272518879D283A6F4C1E4C58918CA24357FC4E38799635BAE556BD6D47082E71874C7160DD5F12E2295C39E1E148ABA3D58AD86998FFDCE98E79A0E3CDC3D7BAB4EDAD60975A494870B12E0DC53D33A33A645ADA5743E3B65F2D0F9BE54E2CAF124199584FC1A0DD9008DCB372D045FBA0D1BB1FA127E0E00F6FA03E0B8EC677371FF9B1A135696F7D79344AB7FEC2D21C2CF832B3A8708B2B80865F68A29FB86A419C135A69C3BD431961ECDF12DA631FAD16017A06BB8D1F04A9412A7CD8FA1BCE38E27ADABBCEFB99A0470694C5018E7FA4F3FA53FEF1095526B6644E999A645044F38C1DEA7BF8D9FE0E778A22486EB754FEE50CD6DD4D144E622B0D0856C008A657F4CA32A3FCB06F20A9AA75F8DFA15689B225EC64C790FBE895457E2C5707A43FAA8A5A4D5DE16B0434FBD55B6306D96FE74A5556CAA56A7AEEC92E6DE19DD83CB874D6A1AE599C0A24C5FFEE10170521E300D67EB35F5286F70D1C9D36BB72E43C81B3EFF19D2DB06B18D45C94D6B451BDFD23BA368374FB21A7371A93887F5AF30CEF230FE6A7F31B65CA27E7817195A812FED07155F0F5279F8ECBA5842292C194E03822F73CEA74BAEC375C578B5E32488AE8001E00D09F379B0E033804AD124FC0785E5091EB1679E927DEC51A6655039EA7C87657D1158DE0304881ED4F9C18AA2E8875D5A9A78BD211DFB2DF89C442B89C78BDAE7187044638DBCD6F9D99319FBE52775C4FA2CCCA0B39099E687ECBE334FA75842879C73573833510E41FB453ED8EDA633374B69B9E2717ED824F8B7DFEBBD2A5F14BF9885AB9DA241D2ACF97FD00CD3CB4D7844859579115F994AA4D1595502E646F2226E66712715D7751775220717A277FEFDEE5ECE96AD4181B953B617C4986BF839B6E79DE379425814D69885FC45B050786F7B559AC44046C8F58478CCFC2C02D7ACC699FE615226701E7F4D18567E755E0C1A3C3EEFBF51C45A6FCEE3FE0CDF24CCA87120BE2A18A50E3DEB4DB7EF35BF2BC8A5C0F5990220E73DECF7CB00E54D2D4CEAAF996E920A7F8004271B940B8F7A79C8308D9782758040EDCAA45C5337DDD2149DC8EC8B5FDD50FD77DF961C5ACCD3852983FFD42AD9C0AC2800EF86CADADA670CCCB280147E89F791E4FF092DC59016F0763AC38E23F2E4F9737812984F0B2A674C5E5AC764CC65B70BFD0E9CE2E4C3345FABA845BCBF48C8F785E04B50D3972BA5108E32B5AD3F32095C48CDDBB12E597A18732FACEA5DB9F2F980DD220F58C1AAE13A246F5C9783AEF2EF1494EB9C6FF7C197A02A4D58C418012867A62D9591F445D99E88F90FAF629A8C5FEF87BDEF2DA8D66CC588DF252EB", - "C4E4EFFE05FA703BF8D2F1BDE47FF70745EEC5A5C039FB7B41A45622F14051E4" + "83E76806808ACAAA120286650F965DEDBC6E00E13563B5547A345981FBB177A6CD6598B358F56C3B272AA2106FC8901FEC0633391BA78DD344D17A219C3AA103A8B078BB3451D690D81AB22B858231850672A92270D95209F01123E6620B043F8B64ABF9252087365E51B8789B76995EE0098CB2AAEEA6760935A9390746EAD04270B91CB08B87ED1905335895D766CB8D229AE939A154A0680C583FD2D0CD71009D8D26A9B6F90C5A463125BC63ED2165BBC12AFD5866518110C4E809CED8932F5149EEA59FE806091906CE6D53AAD7045A69A74540C738B4E948FB470073D35DC6A536475AC8A037A1DB842D742A2D2A41C708C9125EA746D309981B51719CB31A7BA412DD11AD1C1C33C7810F016498EDBA6938D00BE7902E20AC9EFAC7C8E0A22FA5EA711B0ABBA13BBE5138A11244B81AE04C65987B7A5428430980BE57575881260B1780DAF3086C94AEDD0295A793414552B2168300A5A9B077F82FB8A2B697C7CAD06078184896C0D87BD5F8A6A967266E051A2E984B335A88D59285D06775B7F25C48F431A735BC9837AF8383365D8CC06052416B826B3A888314696B7CF67F20C2345CF1113A666A1A63B878610D24744FFD9B8F8A889F3E065ECE25827E137E33E56956FC60CC2423CC6AB8F272AF00179D98E014BE1A2D6DB202399B272CC33AFB2B0F1F502636CB1CB74279D66884F0169E2FE334F268ABDCA372B36084A784B34AD0998BD742263B2119C65527F61C11816724D577B1E77A911A5D9C005F10106A7E8C6292716E27B55EDA339A7A88C62AE166FC324BCB8529C4115969E1C28237977D70C950B31C50D036B0B5584273CCF9B87250666365029F3287429C69943E488C053240B2707EF6CA58D8C840766250853A4BDB938A258B004F0705F0DA8D2D97C753884319D7A2CBBCB357DBCC1134039D205BFDA3306F61C4E28C1271112353B827A2A98996135DBD76B04D4545DDD4B111184B2A787B326A3C0466159114A9BF6C801780BAABFBB578096B73245B3EAA17161530DA777306BA614AEC5D60376288AC7F0E66A4989B93920C37F18A2F91F045DA13A2E7777FB3922A48E9211962A4E9A47BFE467B707091AF86BF8CEB111EFC9745BAA22300C447C28181721AC8A7B51C9470A8F999B7E2268ADC327C160A3F42CCA0C9094DFB65BBAA5CB0153F85225E5C83AEAC55932F19B6A9E077E2BCA1E0221EF4191DD53940063799BEE5B0A5336B6D8324A1A6AC5A865071CAC33C6930974C0A54675BE7392B8227C09EB59706442618F68FCF5977D19C06B5EC6AB8D5C3F5712B96F20ED16A1E170B40219B003A5A453E5B58AB92A786FCAFAE855D3FA66724125D069251CD04277CB1B2065728E7B4437A9954CF711616C25156353194D336F75080BD706ADFFC51D1F7163662B0F84B625226249D15CF7C33206F5249E7325548149421620852F2BECEC6BA28476935BB0F27E181E9508B9838A51DC68EBC70653ED8B5E2D68DD9895F5223A418C49951B5CCCA8494D86AB2E6D773FBB55884E2AC16DC9418100A774548E4A95AF4265772E9A3A082CED78AB81CF15DCC1C24F7D4889CC606A137B29C31A1BDAC4FB050ACB1D28D9C07B3D9973DB9A763044A6F13AF75A46DC7D480380940F9D688DE684BDF867C21EF4BDBF50908DB04", + "37782D0B89341726615D95246DA633E2BCA9D71B477B77150CACB7BB5A0ED4565644A2565EBBC4AD742AC5718F3A63518D3818A3FC31DC5552EE033522622AB75027BCC39C741B3524E51A26D12C02628BC363AA0D908330B356A412911BDB8042768FACE36B02E5126DEB6592590AC5D867EF937A2BDC3A74930C183411342AB5D0E77031859F3877A1E71B9C50200EFA04730D5A223760A62BD4B1F0615A0EA902492404523AC1F485253CC10BAB97503808C565808DEB9B3176532975638923678002E232AD68666539407AE1CEF8129702C8B58E69060DB422C49B67426214F7DB20C2FC857F52B174D6C93BE90B4A58811EE27E453382E12918652CA9F0313A8BECB7D8D7C9EC4830142539BDD92582D00234503D6FD8CE12F806A5381232D6BF0F0391EF8A1B288038FCAA98956C546AF47327009CA65326521A553F2A4E3983B052B3420D20303D378C6AF110B3451CCD5A4AE4AA83F7B2C20BC27542318690FBB2F542A3A51930E04B9FB6109C15F72B825656586C8B76F54F5382ABFE34CF91471922C9BD2D600003156C621579A0C61626A7C2D0BB7AFF95863A89C3D4722916397601630DE0E158AA9B5974A95107E0ABB6A66308123241275613C210495CAD017202508464847B4BE8792D4DC9017BD94FCE873A30C0A587A16CC7941413785AB6969CC90C47235847AD4CB1769835F195871712AA467C5DF1B30D06BB907C6519CA4AA3DC9884262339D4441C078049995BAD49FB8FD95219EA3CCF17C17F97213AD862710A60CAED990D5CF01919764218D672D9B5050AF0524A7AC67B8A38A4FA5C755050F9431584970BF6775F2609559F3807FBCA6EB67B9C67F6B0A0B4B527D563BEB415AC4989473758E31BBDC8F517911B1E431B88B7E871EA33A052FB1D2536032C561DDEB6526E652E1DF338E9C179539C891421AAF6067F550052140B89E5942E42337A1DB8CC3D88760A1498D5F407497925238A79A0B469FB2BBA70D93195F4017E0008FCC65D0635C9FDBB74EC4C4C50455E1E5B893D03764861964A9C3703FBC6A6FA557D34AA5C352D67C370DE7608E83670A48692FEB4CA17B842BCC8AAC7B0AA4546A607157DD2529182703E8AF6818E836635C428E136BDEED6678F962B1CE847D993B5F7B57370390B74261909A3963264A21DD4886A812A44CA2CB82A06EBD7C1280CA993F542EB36CB656A140471195A56C750073906B6115DC17A93E79D7E6037883349EF3B0469E984B8D63BA932BC592A09643B7C675567B676B25E46AEBC61265872CE01F61F75E4AA086B82B2F51364C3065CD880078933F606B114DACEB97AC9B535115F8166B5E9C1E23C1BD6406534A0209DC96063632682185E8E8C6B86FA3B073AA765718C8E42BBCCC16D1137270374C12A076295B0B61060341148BD64BB5553D2AE933274A034CE5CD62DE96118947877A934A28AF22F5F3410722C22B4839DC72AC2DD8222FCFB918A81ABB2422B30313484292695478F521396114A8FF0FBCCFE94A028743A7FC34EB9DBAD283C891E6A18765812FFB658EA58842BBB1232EAABDB332BA111BE36100745A842F8F3B19809C2E3C554BA3B312042C17F298FE7C1910E6774B934C283E76806808ACAAA120286650F965DEDBC6E00E13563B5547A345981FBB177A6CD6598B358F56C3B272AA2106FC8901FEC0633391BA78DD344D17A219C3AA103A8B078BB3451D690D81AB22B858231850672A92270D95209F01123E6620B043F8B64ABF9252087365E51B8789B76995EE0098CB2AAEEA6760935A9390746EAD04270B91CB08B87ED1905335895D766CB8D229AE939A154A0680C583FD2D0CD71009D8D26A9B6F90C5A463125BC63ED2165BBC12AFD5866518110C4E809CED8932F5149EEA59FE806091906CE6D53AAD7045A69A74540C738B4E948FB470073D35DC6A536475AC8A037A1DB842D742A2D2A41C708C9125EA746D309981B51719CB31A7BA412DD11AD1C1C33C7810F016498EDBA6938D00BE7902E20AC9EFAC7C8E0A22FA5EA711B0ABBA13BBE5138A11244B81AE04C65987B7A5428430980BE57575881260B1780DAF3086C94AEDD0295A793414552B2168300A5A9B077F82FB8A2B697C7CAD06078184896C0D87BD5F8A6A967266E051A2E984B335A88D59285D06775B7F25C48F431A735BC9837AF8383365D8CC06052416B826B3A888314696B7CF67F20C2345CF1113A666A1A63B878610D24744FFD9B8F8A889F3E065ECE25827E137E33E56956FC60CC2423CC6AB8F272AF00179D98E014BE1A2D6DB202399B272CC33AFB2B0F1F502636CB1CB74279D66884F0169E2FE334F268ABDCA372B36084A784B34AD0998BD742263B2119C65527F61C11816724D577B1E77A911A5D9C005F10106A7E8C6292716E27B55EDA339A7A88C62AE166FC324BCB8529C4115969E1C28237977D70C950B31C50D036B0B5584273CCF9B87250666365029F3287429C69943E488C053240B2707EF6CA58D8C840766250853A4BDB938A258B004F0705F0DA8D2D97C753884319D7A2CBBCB357DBCC1134039D205BFDA3306F61C4E28C1271112353B827A2A98996135DBD76B04D4545DDD4B111184B2A787B326A3C0466159114A9BF6C801780BAABFBB578096B73245B3EAA17161530DA777306BA614AEC5D60376288AC7F0E66A4989B93920C37F18A2F91F045DA13A2E7777FB3922A48E9211962A4E9A47BFE467B707091AF86BF8CEB111EFC9745BAA22300C447C28181721AC8A7B51C9470A8F999B7E2268ADC327C160A3F42CCA0C9094DFB65BBAA5CB0153F85225E5C83AEAC55932F19B6A9E077E2BCA1E0221EF4191DD53940063799BEE5B0A5336B6D8324A1A6AC5A865071CAC33C6930974C0A54675BE7392B8227C09EB59706442618F68FCF5977D19C06B5EC6AB8D5C3F5712B96F20ED16A1E170B40219B003A5A453E5B58AB92A786FCAFAE855D3FA66724125D069251CD04277CB1B2065728E7B4437A9954CF711616C25156353194D336F75080BD706ADFFC51D1F7163662B0F84B625226249D15CF7C33206F5249E7325548149421620852F2BECEC6BA28476935BB0F27E181E9508B9838A51DC68EBC70653ED8B5E2D68DD9895F5223A418C49951B5CCCA8494D86AB2E6D773FBB55884E2AC16DC9418100A774548E4A95AF4265772E9A3A082CED78AB81CF15DCC1C24F7D4889CC606A137B29C31A1BDAC4FB050ACB1D28D9C07B3D9973DB9A763044A6F13AF75A46DC7D480380940F9D688DE684BDF867C21EF4BDBF50908DB04620C3BA3112D18C0B347C5A0CFE56E720693645641009674E2E2F6E5DA0447A798028E8157DBAAFD5B9370227C9D876818A9A4F7D23D9567BF413F3383F8F1AB", + "F58D542A5D03DD8D622D2D61E9CC759873479DB67359DAB471DE0C6945505EF8EF61734E84EF78D5A36EEA0FE8E6006B0741C415A225834C644AFB29E4CBF207C24F7760024BA27F1BFAB5A9EC712C3A81FC2F232736BA2CA69AA2F9CA7AC17EEB89A193493800951C71812E4E2134680B3BE6FFCE9508C791EB19494D86F9192990D0745AEFED3A83B24A6E7C8C2BA6CB536D2710C49D2C3122D090B95E57C8E1DECDBAD54BF7CC1E76E79448EBAAD77284E35FA03567FC692D2D8E674D7D805899BD00C35615FAC52298BAE7D87C7CAFA3734E95FC8C7EABD0C3224BBDF0F32B61491C1C060DCDD2492516CC4419DAD6AFEF3B96A1504A9F0CE09F1774E607F3E9AC4484F41B7AF8BE402EFB12680AE98B71557562A8C1D3486C5998515D9BF87CD173F5A79BA90EEEDDFF7E0F323D8920C41A80320CCFB2157A0E9148FAFDA7FD68828E5B612B373342872F3FDB0F77F2339D96BB49D2F5E172E0523C04DE0E3C80C89F5640B84FD8B372AFB3319150D7057A9293EA36A53275FC778BE736F468AB4FDDCEF2CB40D42AB8C834B5DC08C1E3B9E7CFEA61373A46595FD2E3DCC164C7B5212F98D3AAD9FE7E08585E0111265ED71F94725E3E4D9873487C407C74B03EE254EC8D9B041D817E6E9D0827626438822595FF14503D0257F04D99352C5BB09DEC0696804260516684308C1B7B60D86A27F724D10080FA4A2B70C90090C9D3DBBB2D681EA2EDF35A73AEB3A77E4338C5631E0842AC53137379E8A653291CDE9CC3421B2417A0C59A1A3E4AF60F455FB01A65E9BCD415B77D6486495D453BA9ED0C79237313D89019FAA1BF89EF849A752389CC2A8D1E677DB68A4E4CD81A2CB9F09E0531C11BB6FCF0FAD67507A86B174F45C033B1988C6B433E9E66CA7CA69A39446FFE2B219C9A9B3CB808C067E781765991665FB40B5780E307B39C370EF01C6000660827D5CAD3E1BBD28BCE05AC0443A2806EFB93CCA9C7ED3C18FA6D58C99C5E6B6AF785636384643BD2E24F6A705012AD7A4D2E6B94CC9908C086F13515C42EFC4CDEFEB2645D106AE385D4014B983DF6A099438954586928D46476A2E70E36147B8F57DC498DC564C62CAB6C00638895D864438E8C3FB075449A7636BAD20A0C8BD433BA1C6B4E3E8E42ABD6AFD23CD6D76A4DEEBF898F699094F1E2EC5E857142C0EC0FE724F040A02CF191D2DDC0A4880D89A0ECAFF00BFD2E26588180EC93B6E3ACE0D45573CBE0B836A9547D12F00BE77B059B0F73FF36827033795F877CD347ABEE7222697440A8EE6F9F9D4747C7DF26C92CAD12747AC6442066CBEEE4B072F5E1809724B462BDD86309A08C96E23D8BDC7006129C41CD1524E9DB13475F8DBB58B9F8EE722FFEFE0628AFD711A1A66CC03F7A1D26A321093179877A1E9CB223CD688F65772C1F550C86FD9025B58F6A1DC9CEC65816EBFB2CB405526F797A500B52EA73AFE592E7A63BE79D6E2ABFE03D528154C0E8D277C844EFA398B346D96F41376FD969356114854C1997D53189404F499165", + "44CC405E3BB0A9F51A180A86213D036ED58AA0D226804E717B9C2A475DE58E75" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "471773AF71058A5ECD58972E92A786BE8154871AE947C83025005A4F3C8D7B3F633D715FCD058431BA2CBC7E335BF25EC01A746EACC15C7538D9D1595719DFBE7E7D17305A476D816FDF3939968B97934607A592DD9EAF425A80BE250A3220763DA9BBC5E757530CAA2E188EDFFDB50DEBF6679A7C9D6650BFF7B4FBBBB7C857CD53F71C7DA5062F0329836185F5D01E8906E10C0617EA54D2109E7B13ABA51C645289EE592BAC10269B3F18868DA72839F2456FDD32B53A67C4B7BA0D67A2BF0547B0DCFEB9C626BCBEA28E90BE3A71B01F2236380F0B752A4A5E0AA680B1682F49B1B970489BAC43CFE84A2809FCDFA1BC2BA7616451C0BD65C6B5402C6D479BFF759183D0C35CC89A182BFD90B0EC368DE8B26D5995E4BC95215445701BD5F31453F578F4C5B1380E4EEA53155B9F7C73C349E8814EFBDBDB667CE7B1FDC34D02C9672A3573EBD65B1903C79C6DFEF23445DC732C4B694EC2C946A78FF7E7E3AECA89A3DA169AD7A0C9DCEAE31DAC66EC0BD66208084576C059E1F2E5F38A033A1B5C1F4B0A4F76145E29B9C47A889A47D45534640651EA4285447056FFF0167ABF1C49D16560A98DD3E2741EB246045AE365B9507B3DFEF050E43503C5A847B3BDC77E7FC87A00B4CA0519010AF0E4719965CB9F80FA3FFD2E8A149332968E81E4291F789C77B16098611E0E229227B0911757F57F4F57B9B26690191310D0714251E7460FF94D1E93B004E8716F7AF19F3F675158206662C55007039FD6F23DD54E600A39B352010CED4254D53B66A85E4B94AE985A53471F4686A483474A183F5E08A3BBDA7B1BD7708DF06800510AEB111B12ECD5C8F080D4FD165BB47F3EF6DB08175707BDE1AD3AFA560401A9F4F1484C091F5B4055F55D5394407BACAFAE553AB2F0D9A15BEFD9BE05A08614A30D55460051572D2FBFA5FD8CC0F8A9E1BA77B37570F12E4521853FA1787E6A688D5827B852FFFFEED93C01E96EC979E3288188066708339964F393B627C516BCB9460A5C9FE44F42C02432D9CD4489138F773640CD6A4D8EB188073BF95E0A40FE9BB6D49AB19BFC1BA31CAF36C2FC6535B587BC6164598B3D8E1C17BFE5D31C4D3834993DDFA54D08D1EC5F54D2A7A2FF3F11C00259D5352D94330F564177B2FB1F20F793A422F487FB6ABC7A3980241BA64BCAB5C1DE337C4A28C787B89603A581CE90788E43DBE566F1BE9CDAF70DD5C2DB269626028B5A3D6CCB1954D04E83312EB1FBF9E56F29F7A873C41021F9FE67B93274DBB03C2713C843D8B153087929E5B393971C9175FCB8D193870DAE1FDED1DF282281987C0617DE7AB275AB3782EF2EAB8F736B3F1181901AC21BFB6BEC1A071B76F622293050F4D632D0C538CC636F9E1CB6E5CBF611DADF9016DE70569CA8B31D781396F4490520A287E5BA155B388A2486BEE900397DCC033EFC09DEDF6A0581A0267176EDA21948CBC024C9B798CD2AA56A0F121E46B0D626AA2913513F7012CF17D9CF4488B193F921BB38EFFB6D67D158F16D0F616FDE", - "8EC48F32FADDB6C32DE93112DB405CE8BC525BD8FB9004999CC8AF13448D9B0B" + "DE1350105270BA1CC905F9164AF44D1F68215A0A333BA4BD03AA6A2CCBA60D0B7E74A4A41E67BDDC74A118246E4845789FD430F5BCA29CDCA9A1E47E0B4231F66A4FE9029D69337415412286BCA0B8B38BF14AADC7197B137C10B0B17E2A40CFF8430D80218F8BFA28382A026BEBAF083816335B8824A47D01647B1ABA5A8D8C2A952CCAA3042AFA9AB5216683DFC83D03419BE4662ADEB44CCBC327F038A3E2AC709372C5BF747321545319832E741223AA7AAD9827A288B5691EEA37DD785ED1222F0743C664CBB4968A3C3DD74AF0D31AD26A2BC9ECB93EEC968BB669EB76B9005B7DE9E561C0E6C75FD6074999CE1AA79A9FD8C128B853DF72740E0094E5E77F84996BCEA450B802654F555F38D11999456AEE817456C41D8ACA024A0C6D31786D738A0A387488E24485B18236243875A9241A325850A668718432B02B91A872250CF1CA7BB3D68618450DB727916961578C50AA5C8A5BE8873E8877C9A241B94B35AA6B57421C5CBD7500B180389EF7F326B27B63E9DBAA5CA8AED215782033595F79CD255BA823CB39D110AEB1307CFDA33D2B193E7D578AF73B8888B601700B1E6E742C2520C03DA05901C29993E4234552981C69CB232BA5F2E229C5231D840B1F8F667590B89A9B0C00307602932302ADB80913A35DA711A4EE5C5FCF682F6B90486FA0B728638B98606C3DDABAFAA169B3565480278F6B4B64B07AA03F0902F409772EE242E191291A06B50987CD58C16AE5983B47EA400C53B295FB8E3206ABF1B2CAA9C46C343A734027C6F221BA68B42C6BF44D806C7A728064E68BBF35F7C01383CB25EA906126623855A31A06891EA4C231300DF5933BC312430AB61F0E536E5E131EB5251C8309047F40B36F34277A31161384C90FF47ED956B0F3B66A78550FD0BAA32EA71BC4F883CD2165EEE44F81E47FB9807BE8973625148EF622B0DBC443403C0410007C99D67316A517DBE202DF804FF1133B32A9833A2116829525FB68BD2E6A7E938CB409E3878D13955B01B93D3A74A7FCAEC6A7AA6752C7B0B0B1F8C70D0A33383A3C3ACB233203628AEA70B6EA6451082B7C6EB68332324AE411B31F120A10781DB456308543771310A2F851ADAA125BE7037DBB186EB4CABDC89BADB4012364DA1FD63BA58CAA9112FA2FF5AC3642319E7A96C9CBC13C00A288DE398D55B2A06CB71187442476964D902B422B24B62674A4FFA9794009866C46978133088696A084D60A9161003B0A3F6174B7CF5836F7667AD96959F3514169183DF200CCF6F541C3AC4066129990ACACF7AC0232279B21752639566ABFA703D853741C2628C62896497B575978CFB7DA37C026B1236B0F1EEA03450736AE73AD20F8853E33B90F40CFC058BDFCFA00379A2080E0B81840993C2505D9CA5A3E59AC1377C4C176BC7EA512FEE7A1D85406A3068ECF91B0F67C79B424958421AB5E411476015C319ACFFF692D67F92753BC431B9CAF00A6B000F526D57351D6A6A63E76AA5B50212A23C64E562E8D66C7AB30843D503FBB8941E064555203ACB3C8864D0A427BF1504856688074281C66C3A7A2B0CF582E2C2293962C2022A0A26F33529E963D7C72486B24977948730CC9A89FEA714A49426669897842F4E23D9DE1575014671BA3801285563213A3FAB2D00F0D26CD453D", + "46819AFC7C032A80BB830361F0547C20CBA4B440ABDEC723C003B269B22B6ED84F159A2D691AC014E3CBBDF41F6E6B57031ABDA1C6075D786B957A95EBC65E6F6B1257637186703E5BCA5F80560613FC3192A40247B62C1D8C3A15F04D36C125B0D74EC6B087A1401A69B6A00785729C582C1194195792C164A65ECBA8077B7847DA022B1CA105D07BB68A58846DF8010CEAC960A783DC48A46BE33394402A1DB589C50A0445759632A2241AF905FFB059DC0C8D9B589A1ED30ABA265BE5D412FBCA0CAA52C662A009D21A9F00C7B4ACFB09175107084456FB92A74E903176777CBAF05A7083344823AC6A8477636C4E6AD5739189A2C1A11A21C9B4D70B6D40C37BC7B6937A24C20DA46D64877F167CBC9FF5C0B848B5225B7F24D5A76B0A66FC57A394832391D8BAE9C4CDB5930CEB66B03F52613EF40CEDD810CF2C45D0A62144227496875DC682CFAD4A4E82C42C73C6B830762D068B96B2C81BF1250F9F477B9A0A318E134D22E04AE79B4B46798C37D47E7B63B2D2F58E95841A9B673372AC619051B2BFAC4A654C07E7C714C8820724AC2994ECA3C133915215529351A66B29CD7AA9ABB31986B1677D3DE49007C3C3C3F9A1C4E52AAB1023EAE38396C301F1F57CF653C065BA7439F597D3D6BBE4395982E369DC618052B55B19453352FB603A07A24164B63FC79701A27BCD22C813D58EF86797439B0EE4CC79C9452BF1D2B71E101FA2B0BB392A661CF6B68B4BA0DA3A52C6311E706462845255AEB56C2E324CADBA74AF47CF7A0C5F23735A5185AADBCA26C1638275D045778144C6F71C5FD59B247ACC0A4B22040468DA162EE6B13005594B075C823FFBBEBF1B1EA72A866B8765C9806A374250800A50D6EA4FDF421F87286205B8C346D2348A2A2229B234B7697E18C5BFA6A968E0BA4FC6553752571D880C6C624BA3687480CDE20C018475722C8E09E33AEA03207009CF3AE62AC216A84BC3AFDDA813C7E371368016D862819AC68E5FA8AA394C3E3B94CB9A9AABABACBFA45B2F39F69CAFF354F287A0B6EC15449B82CEE7A1A9041D9D53A87953A1D45217184B2238710291777BE0C713D6F200C67B1658D8481FD88E8E33BDCFEAA88C0BBE5312516C90423DFA92E8AA927330A4A10B884685163CB0A9084990D832C6AFA960223A14D8085D07EB29587CC23B50A5897B969C471703DAC3C2D662FD1C8CA568674D230CC994857AD5C6180B10D3510CBD018966654E314C6CFCC979D0B428EF682DE27081E0663BB1A5B8A11AA9D7495BA2674CCE8698705142B7627CD34ABD81FA96C43829AAE87FDAD3C2518B8189EB8ADD0B24C4302B66F9C8514361947086C0E26263E659EF446AAC4179F4AC4AE08BCD710C63B1B18AFF405E2B793BCB8A6DFB95ADBE52AB0009106B0596AB72BB50B7AFF25A1822C693876CC54292ACE2B25C501836414C08324508861A06AB40778412A65F6699E548916E9CA3A8AB4D68394799653A99785D11DAB151E4A433C1C6D6CB7973168AB4A027DD0639381306BEB52420F7000D81AA1E0172128B5018B0402021B49CC708FD5A00CFA95503DA95F985A4CBE60FBEE8C96440743ED49CF8DBB017815EF17561E56B04D7E03B870726DE1350105270BA1CC905F9164AF44D1F68215A0A333BA4BD03AA6A2CCBA60D0B7E74A4A41E67BDDC74A118246E4845789FD430F5BCA29CDCA9A1E47E0B4231F66A4FE9029D69337415412286BCA0B8B38BF14AADC7197B137C10B0B17E2A40CFF8430D80218F8BFA28382A026BEBAF083816335B8824A47D01647B1ABA5A8D8C2A952CCAA3042AFA9AB5216683DFC83D03419BE4662ADEB44CCBC327F038A3E2AC709372C5BF747321545319832E741223AA7AAD9827A288B5691EEA37DD785ED1222F0743C664CBB4968A3C3DD74AF0D31AD26A2BC9ECB93EEC968BB669EB76B9005B7DE9E561C0E6C75FD6074999CE1AA79A9FD8C128B853DF72740E0094E5E77F84996BCEA450B802654F555F38D11999456AEE817456C41D8ACA024A0C6D31786D738A0A387488E24485B18236243875A9241A325850A668718432B02B91A872250CF1CA7BB3D68618450DB727916961578C50AA5C8A5BE8873E8877C9A241B94B35AA6B57421C5CBD7500B180389EF7F326B27B63E9DBAA5CA8AED215782033595F79CD255BA823CB39D110AEB1307CFDA33D2B193E7D578AF73B8888B601700B1E6E742C2520C03DA05901C29993E4234552981C69CB232BA5F2E229C5231D840B1F8F667590B89A9B0C00307602932302ADB80913A35DA711A4EE5C5FCF682F6B90486FA0B728638B98606C3DDABAFAA169B3565480278F6B4B64B07AA03F0902F409772EE242E191291A06B50987CD58C16AE5983B47EA400C53B295FB8E3206ABF1B2CAA9C46C343A734027C6F221BA68B42C6BF44D806C7A728064E68BBF35F7C01383CB25EA906126623855A31A06891EA4C231300DF5933BC312430AB61F0E536E5E131EB5251C8309047F40B36F34277A31161384C90FF47ED956B0F3B66A78550FD0BAA32EA71BC4F883CD2165EEE44F81E47FB9807BE8973625148EF622B0DBC443403C0410007C99D67316A517DBE202DF804FF1133B32A9833A2116829525FB68BD2E6A7E938CB409E3878D13955B01B93D3A74A7FCAEC6A7AA6752C7B0B0B1F8C70D0A33383A3C3ACB233203628AEA70B6EA6451082B7C6EB68332324AE411B31F120A10781DB456308543771310A2F851ADAA125BE7037DBB186EB4CABDC89BADB4012364DA1FD63BA58CAA9112FA2FF5AC3642319E7A96C9CBC13C00A288DE398D55B2A06CB71187442476964D902B422B24B62674A4FFA9794009866C46978133088696A084D60A9161003B0A3F6174B7CF5836F7667AD96959F3514169183DF200CCF6F541C3AC4066129990ACACF7AC0232279B21752639566ABFA703D853741C2628C62896497B575978CFB7DA37C026B1236B0F1EEA03450736AE73AD20F8853E33B90F40CFC058BDFCFA00379A2080E0B81840993C2505D9CA5A3E59AC1377C4C176BC7EA512FEE7A1D85406A3068ECF91B0F67C79B424958421AB5E411476015C319ACFFF692D67F92753BC431B9CAF00A6B000F526D57351D6A6A63E76AA5B50212A23C64E562E8D66C7AB30843D503FBB8941E064555203ACB3C8864D0A427BF1504856688074281C66C3A7A2B0CF582E2C2293962C2022A0A26F33529E963D7C72486B24977948730CC9A89FEA714A49426669897842F4E23D9DE1575014671BA3801285563213A3FAB2D00F0D26CD453DF0557B4190F81298E44F5A57B35DA4E38A8D970A89E0820A5AE30E7F77CE282425CA39F4A6918F5B97B9580AA6019CDFC5604A13B2EE4D72F5D0896F0C335D20", + "49C77EB019FA3D007EC426C759E07A7740E5C63AE8D0DEB905BEABF4531BCE762A7A455D45F571218C23A434054DCE1D7C65D3557C3D4301688D72D95A14E052EBBE6AF4C2D878837240BB8473D4023B5B0E74DA7AE7B6ABBAE062142B8B06C195623B88757564D6C58C0F929A96E43DA3450B08E0DA716FE52CDD51CA5883548B61235289A2E0F657B250233EF8639DA08E6E10E4A6E75291851F729F89DC37601C520D5A1904CA9D752EB655F9A73190E7350AB410348512BF9CE650943FE41C03BED22DF45CE1B09585E20C67DF556B05D68BF64251508FE8012EB845720E2AAF158F1B069374FF3FE7293A0DEB05CF914EC5C2311ECD4657A4BF55B7DC94530703A60EEC3BFAF70CC0CC1A2CC1C147E35AF6073716F4BE540DB1FE13BEA22B7175BB50D7C15F044AA54B126C69E57C1D4C5C5A9CA947AED4FD279DCB950D6408B62E7940AE12076702E553E604340768A870931FF3CC5C0F4C158F1322BA6FB6E3ED4B5421ED5A2F5949004E885E08E7F87E631C8674EC7310240C16F24B2B5A9175DB724628F1F0CF76088ED5EDDA985635C614BB0DDBD79D3CCBDE0CAD1CEB9A3FB536F71FB5DD0979FB87F0A8D4E33EA11AB19A98F36AEE54BF7870CC22DD4D4A2C375CFE9A68FE64776E612999BCD54334B601934459D0FC18F78259FC4E5A03E6A4996BC66EC0489C1C012B43195DD2EBC6C9A45CFCF2E3AB611E987A9BD527FD89FFBCAF78A2A8E03F1FF07378722C9E624A066F161466D4405E851E70752B7A963195DFB8CC8DD4510FA699CD0B0BC0213EC6662CDC9273A8F2648D4F68CE6EAAD00934CEFBBF8072D0814634444534ADB4CCFB36E5067594E5723893DE05F7312B380DC08486563A0496AFF6F2349BED9E44E09399E1F769440740A7E52097B616E58A859A5D3C7168364CB0C746B524EABE1E51BE8D4CFDAF80A73B8C6779B70B899086D12AE3662D0BC196151F7724194B2E01295E08FCF3C9FAB46CBAE3F96B3BBD6A66D51AEEAD6C4FC2875C5C2227F12E227633264B8C658D867AD67A85EBF8B9732FBBEB08103C733E7ABFE7F6928F414C9F780F2C9F80BFD27E212EB007DA10322034021301497D5F7911C11F64889685B6B6A7C51562CE13C6E8908B6F62246FE6A2A485C0B1BB0038BDF3FAA4CD22FA450E375B0449802D8D96DD33A6A5EBB58EE78A25AA33E8F737C5346FE135324146830259E927BD1E72FD208F2C906792C60DF161448EDF57E6BF77D6B9DAC24A17694C996E92894B9F350799BBDD7E86F30818960BA56FD23B07DB2605392C0A9E152E255CB4FF6FFE3B5BB5153E0AAE288C97FCC0479F3867FC5247E850A9F9406AEFCB87EB282FC46427AC4332D69940153B1B8607E9EA3F5681C9EF1E9E0CD06457187A72C2A10C61C7F39786C7608AFB0D19857A1EBBD333D148FF23BF54AD18CD21019C134BD5960A964ABCFD4364ACEBC64F09243E25A9B5E33A2AE51BB0523D59901AE4FD946DD0977F6FF46CCA2FE7003CC3AE90FB85A3708F0C0DF6A2E5FCA2BD46", + "0E2D4CD0C4C4C9520E5F35D12BB21A087DFBDD502BAF4CD898A31C4F16B6CA67" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "7D092F092F100B95CD9E18B6DC23C39A8B7EED57229EEE522368CE83A23C766FC3302CFFEC6BF67C558BA2F5F20F277879B8D676C75CAB877A060BB4DBCA827F4E35D54BBF0067FB0DCC82702610CFB7DCC90307D733CF59CDA8A84981BD24DD3E146D17C3ECF2DADC2CC973CE3AE1D2881D143A1A55B60D0574291F7E1D77C9D8EA09F71C7F9285DDF072850386B0718D14E788582A92815661EDC2441C57529F63B9F0EF9846C1ED907FA1712B37D9814C70DFB5CB63B385586C1C4B7E91A900BBF532041EFA0EA49358136E916DCA2FCCE4E17BE8A2FF3295BAEBE474C5257069102A50CA9801597E5EFE64DB41A7A82E22B1291F83945FED077F4360F56329CDF2063C3939AA1B284C6BAB65A1DDF20BD97E17B41D03098544B56242FDA328FCD7F69DD372A05B8FDA48F8E5CE27F1B2A917344078000E5CFA5C498FDDB77256827226D63576B51B6BC8ADF81C6FDE9343D469FC866968A37AE506287945AD358FD3E8A3A37FC7FC86DBA5D29CA91F7C80E62D1341B23539A96B38DAE2FC4B615BCE7A3C44448D7ECF7E77B60DC2FAD8BAB64FA3EEDD9F1F5A92F9AF7832305705EAC6BFA9E83D0D2BF162A567E82E59E763775983B5ACB6669AEAF70E756365C14951B963410CAD7944A9AD8D8229D18F0871D8BAEE7C241DC69C0B525B08817593FD136555837AD2F580ACA465F75D1832681652E0ABF66976096AC9A72509A9C34CA839AF15FC33F25B7234EFE562B5EB7597D116499C56CD931EE99611619029A6D5EED99A03C7A45E1FAA6F82BDEC813BB39183AB62721F7FC1BEDAE5BE2F1D1CB22806C9992C1DED298515A63A9C8DEAC6B094F56C363FECA93C2D051E85AC1DB7A153A511A7B3EAF0EC7D29F8B593C2A77BC93E649BEFC306A4AA766099F4FC9FA30882E9790D0F3A77001989CCF41C58EA1562FBAEA842E20502650848F2670D0B9706122678FC910865BEAB5977649D6B04438AA77FA49D434C30F4946E53DF2AD529682C68E20DC0CB0BEE2FA1CC507F73E42645B40971E211C6AE319955168EF22D85FB7EFD9E75408121B0BEA27B537DC088F044C2B7831122B494A356EED1B306C8A114D668EFBDE1F75DCD07AC7AC832449B6F15B0ED9B9CC70482019AC8A3799C1A5EF0CBC1A3CF0B10DBAF16A61795EE27E35C0202AE18CFCDF0BA102D6E40DA93CCDF09C529ACE87C09EBA80D63D8167F3EF89020ED6D1EAC29FBF40912E8D3595B57059653445BCE7B8AF49B575AD4C14D9CF2218865B6FCCE13533C06B15E94B6B8FD1341CD56776E17AB9B2742BBDDA91450527336C596711B236F52DC63357C47602570495BF208D3D9906AEDD466A0C0518910D0954F375173452C2D4DEC28B139D04B7376EE694669CA675771C7F351079ACEB1C71A5FAE69B99C00F4AD93C9CE08A291FC6DA670534624747D8AFBBDA6875EB20A4C03529C67F7B3D0172359E826C38B3C7067DE1B2E7FCBD4A7BEFA3D6BC3B4B44E1833428E81CBEF09BCF2E359DD4DDFC5A353AA779DB26537BF5B5B351E", - "498DA668615D45F52F47EF960E634A7BAF74B0A6EE8D73DECAB67E5C096C4FB0" + "D9E7BA6E19437BCCC947EBC3DE0B9B87E2029E58C4AA2BB7750B780C20C5330CCF83F01760D561976ABACE156F1448C3971679DB529E280AC4E17B67A5F54B7E5072ACD4BD1F4B2C4CC133E6480569AC86FBE368D102CC26338ACD8992DC60B80AF834DDF1B615A23B97453C5E8A5C705B5CF191B79CD32F30711BB07C341CF7C93FC055B4850581167F7A180BD448C0F15858D00353B3903C984169A524AC74640F7169C3C691C0E9FB362CCCB6283C9403613BF545C20DB6C21AD96615422A79FA4810F59691F16ABBB0AC18C035CB2233A80AA7CB050F44283F01279F9DBA4AC2D712A0739DA5B5675776C2BAE37C6D4C17A57230A3356DD691B87278CB85673DCF0C135CD6CA40697215396A67B03345B5AF5371B74E101D8D284221F08E39770A86130CF10B327411BCAC3CB20F234F260AAD1A1220873BBDA9658B98237EDA14065A48C77FC2351E8AB0995CC428C581D400141C1B6F31555C42FB649F893C93570C8BC00585AA21327666AA5C861BA01FB91A60625B8167C663D6B8CCB93851C7236C88D8353A25026C87ACD2A16374F213D37B10A9143C7CCA4C73F881926C89BC31C62AC2B643856877603DD24C032B6A90CF661023FB44419897E22168553A4FB046A2E5BA788951CEE12C3D501556CA8744FD47245446916D88065A522C9158A82BF1B495A91504ABCDE6774F51B405D994332B5735D925875AC7BDE26927FC9092811CAF614372B357B88B3C23BBBC44E880B98D7981EEE36F255A4683E86ED3A03434E1C075B3348429804095A647D53400D480FDA3381DE897EEC08243E8A2CB2C174BF79EB4EA3C76C42DE8DA9ED1E3730BBB655942A452404A0E046DA8B06F29FB51B69058D8B2413C79C3DD8C8EF7538F35E8C007AA5867B8076602715FA98FD7B89CCA9764DB94CDB657413445BD93E095D70B2E0E397788020A0F38B466772739211436727316447FE7469D90D21E2697C5D9614AA6927EE68B368573B1DD2B26AA0B9706598D863B3AA5D74858D5445A59B3829877E26178511115925B65BD367203B8592CE34ACF2A67CF80777FF5A8E88B7E2DD27383F8C6657A012704BD556374313C3D4F257F1D104E2B5B631F41C5D8992344D8C9408B8F63A5C5E479B432DC5C1295C0759406482689F62C47F30B291E3AA5A04AB762663B5DB360C7481FE29002CFB16616F50C1F1CB93BB8828DB22A02E2BD2E166433398436CB92161974A64C73D56857CAE5BF7EA07B5AE9C94DCBCAFDA81AF4BB6BB23A881E181BB6902B9360BBC4B4730A6CAF51B78190916E50503E572951555585156762C547B17D19B4E5D8C43AA63CB331A7E44B2151B0B31F61A1C7628648D0381A7A9C4FDB2B9E2998CB7121ACF280FEC30AD657619594A9A6A8106158A4379B3FC845A2F369267E41C84D8309FBEA7BFE9201B6F25125326FA10A198818ADD1AAB6010A7DC220A19C490CC5CC2478970F183C2FEBD346B35CC6A3A399B29BBC99E7C661D27EA6612068609CFD91B890A9C092AAA638C923B182001D54C87D09A45E5B58FD11BD3965B621F426F9C09A79A39775D4144A64CF0142C8585120552692DD503FA99C206F7203FBD765E5E094F4666891310CAC0CB6D8DA16DE0D7B4079BB462963D3BB50DBD799825A89FC965130C429FC78DEC0BE", + "5CB4C2E47C20D4D968A9E55D1A4A1CA172A154973C60F1BD55FC3A6DC8184A17153AD0059E0824EA12238C3068D6553636F19DCA495EE2064762292BC318B144667CD9438A2C32904DF01AE90A11FB0828F0DCC150A02F7E758BB95C3B64F093ABDC9D576915103954E67B7AB5D271F1603248B16B15C8B913202E85461A4E9CC589C54A0D3041C2B6953E73C24C5C6F0B9B6BAAF63CA11863A2E47420D790AED7CFC83C6BF5C15AB4DAC00F9239B7848231652473322282CA0F34F73C6D9C25040CB2076085D85186349B03A518CC720C0AFFD37E61B56B394CAA20074AC86195E7816AB037AB3D300B9FFB6892199122E703FAA7C6B9C34D8445593BDC00FC786C7CC206898325E44338E74B02AE931D95AC50DFD42FE6C16EA7A344A4304FAD54838AA9B78101B7E803A33ED6822E7C8FDD693A5B3C9F45ABB3893C6680C765149266C16105735A9F94B4B6E0A78A94B537D37A7EEC131AE32545BE14BF6C42384C9B9C7577001492254B7A85A6955551E52011656D95B236B3C10B7CC79119E5223562C3BE2A5DBB527110BA54B852C99F7607AEF66AC730003EA0A170836B22289FCD39A2F5478FEEF38799A28114F3875A7A226FF7A2295858ECA953F7262A6A886087FAB084B7BCEC4663486077B7E7A204EB4A9A7374CE07D09E61C5CD6B168BE584F19C513C35A2951033445251CF6BC85DF872B8DA47F0B00C17391F66706D2BC65B698AC85B36ADBF166FA6A23764562C69FA57A5F2B6EB836883796DD671A95AE4B44A47BE78B22E775C233144A0D95B6C8393AD16F39E217C9FC59C77866B12E0039C480945D98B6A25FB9F0D4ACE6F102039171932F27B7DB10CF0239707D45A2BC84C4A0005821A3B430B125D02934E360193414AD85151E1F4A718A64CEAD112AB5A4206CCAF71B9AD91EB5B2068C1AD04CAAA3238E77355CE71228D962EB4E4AE7B499019C1CA15179027103EF85AB16B0BBC538A955100C328845BFE5199680861F6C865046928264012A7529C6B55B79BE27CF497308408A1A821658D8AB146146F32770B5B173E2B45B97BCAA0B833B68C5981646B3A9C2630D98B4193F6231CE3C68EE1C3F8B5C4EDAC4063D7585A127C22866E96B6984B71132CC90F3844046CC7C23A498B65E4349E9737363946BE782BA811CC67B82380DB87C5F71FED9587D2E4C37EF211ADBB39C973B07266841BF2A0E4F8CF40E62B9FB647232A111DC56028A73B43143E7D671AC1B964EB488EF932510E231B08A64DD83C3A3FE1C2C1A2644AEA554EE85264F4768226382BC5502605519B91566E9C7D52D1922D87BDF1E3640545C70B9C61D402670298119EC26569632A71A362CD151092F21892BCC179252391F0122EEA25CE20590E5605583C28A6F30E26987C23D56FEFD49D8DDBB0C27684713C4BCDF4411F66B541996DAB7025C3AC1E0E424D112A9D27A58CA78B6FAA00616794492808B5E2B48A05240ABC3A6F7EF5339E7A530F703554024D89F0C13514668CF8864947BBF3721325415C7BE738C321482DEA3478D019D2F298AA7B315A468DC13CC39CC0B67FB29C72611051269B42279AA25B942C6152209CA168026288F77515E9BB054CC1B5A3435D5771D9E7BA6E19437BCCC947EBC3DE0B9B87E2029E58C4AA2BB7750B780C20C5330CCF83F01760D561976ABACE156F1448C3971679DB529E280AC4E17B67A5F54B7E5072ACD4BD1F4B2C4CC133E6480569AC86FBE368D102CC26338ACD8992DC60B80AF834DDF1B615A23B97453C5E8A5C705B5CF191B79CD32F30711BB07C341CF7C93FC055B4850581167F7A180BD448C0F15858D00353B3903C984169A524AC74640F7169C3C691C0E9FB362CCCB6283C9403613BF545C20DB6C21AD96615422A79FA4810F59691F16ABBB0AC18C035CB2233A80AA7CB050F44283F01279F9DBA4AC2D712A0739DA5B5675776C2BAE37C6D4C17A57230A3356DD691B87278CB85673DCF0C135CD6CA40697215396A67B03345B5AF5371B74E101D8D284221F08E39770A86130CF10B327411BCAC3CB20F234F260AAD1A1220873BBDA9658B98237EDA14065A48C77FC2351E8AB0995CC428C581D400141C1B6F31555C42FB649F893C93570C8BC00585AA21327666AA5C861BA01FB91A60625B8167C663D6B8CCB93851C7236C88D8353A25026C87ACD2A16374F213D37B10A9143C7CCA4C73F881926C89BC31C62AC2B643856877603DD24C032B6A90CF661023FB44419897E22168553A4FB046A2E5BA788951CEE12C3D501556CA8744FD47245446916D88065A522C9158A82BF1B495A91504ABCDE6774F51B405D994332B5735D925875AC7BDE26927FC9092811CAF614372B357B88B3C23BBBC44E880B98D7981EEE36F255A4683E86ED3A03434E1C075B3348429804095A647D53400D480FDA3381DE897EEC08243E8A2CB2C174BF79EB4EA3C76C42DE8DA9ED1E3730BBB655942A452404A0E046DA8B06F29FB51B69058D8B2413C79C3DD8C8EF7538F35E8C007AA5867B8076602715FA98FD7B89CCA9764DB94CDB657413445BD93E095D70B2E0E397788020A0F38B466772739211436727316447FE7469D90D21E2697C5D9614AA6927EE68B368573B1DD2B26AA0B9706598D863B3AA5D74858D5445A59B3829877E26178511115925B65BD367203B8592CE34ACF2A67CF80777FF5A8E88B7E2DD27383F8C6657A012704BD556374313C3D4F257F1D104E2B5B631F41C5D8992344D8C9408B8F63A5C5E479B432DC5C1295C0759406482689F62C47F30B291E3AA5A04AB762663B5DB360C7481FE29002CFB16616F50C1F1CB93BB8828DB22A02E2BD2E166433398436CB92161974A64C73D56857CAE5BF7EA07B5AE9C94DCBCAFDA81AF4BB6BB23A881E181BB6902B9360BBC4B4730A6CAF51B78190916E50503E572951555585156762C547B17D19B4E5D8C43AA63CB331A7E44B2151B0B31F61A1C7628648D0381A7A9C4FDB2B9E2998CB7121ACF280FEC30AD657619594A9A6A8106158A4379B3FC845A2F369267E41C84D8309FBEA7BFE9201B6F25125326FA10A198818ADD1AAB6010A7DC220A19C490CC5CC2478970F183C2FEBD346B35CC6A3A399B29BBC99E7C661D27EA6612068609CFD91B890A9C092AAA638C923B182001D54C87D09A45E5B58FD11BD3965B621F426F9C09A79A39775D4144A64CF0142C8585120552692DD503FA99C206F7203FBD765E5E094F4666891310CAC0CB6D8DA16DE0D7B4079BB462963D3BB50DBD799825A89FC965130C429FC78DEC0BE8791A5FC5C3256093B6A2771B74BAA0E7A392BE9786539C7D779967E1C808359E68078657C842E8DAB13CBDF6F7F8ADD047FD559D7301C13F6012418DA0E0889", + "F4992501CF2F2EAEE6D1417D8D17317D61A33D8C3BD6E8E85ABA5EA7847077B3675F64C9EB4BE036BEE72C51E124FE95594B9740401FB09025D3D2BD5E277D562516F2AE98F0DD8301C3E069A81E395B8906B5EE054F0929C6C1127B36186CD121B960C582CEF4BCA24FD70D55A33851BECEDB0BE236608B4AEB1A28DED9730B28F3B3DA55337F12B88CCD7073C14E4D8133BB949F656A916A5BD661FFD7320818316DC695DD7D26F8CDA18C7F75224D635ACE8E276F747E73D78D42ECBFBCF8D54D5B5483F8574121C422E94A72E9BAC36D5C2FDDCAF8F5AEE6FFBD4D29C11E2FD2F26E93CBED40573F0D3AF8AC3CA56F8226D4FC5A17818C1087449B74248C2C9AD52CC279CAB0D24CC7EFC60499F927F7A8898C93E42C0859F9E76EDEE539F737BC047E5DBBC9E0A948ECEC3D6C998CD2F870C7858ADFC495C83C65CB069DF557E26E6B0FA3F2182B33E93FE2ABE2CA6F55B3022A518B7E8885BF7357D99C5A8C49D13D9D31E3B845F4641C8C18F4AD79C25E2F854566DB4EA208CB0AF3302793AF0CA778491C666C0664EA0FF3CC79EA6FF2F4DDA3A5228ABF635E8002FEC9EB376B7F709E73A9A162ABA9E14898C3DDD999F5D3EC14B24CE733A30B0529FA6B827482D32031832A907F2889251B9A54B705A19097F7D83F0EF180251BD2A4398DD500820863D051C2F6DFC14D4E712939DCF93D2A79DD985B22025112CDBCBF2F293149E343993546FC8B5DC9CFB7244C9CDFAE8134FE71F1EB60DACFEAA63A61E80EC02B94ACD3BDAA73051ABCC54D09486E6FD3ED327A947926CBC26B185F7F0620EDB773DC5AEA75711B94A076E306CEEE1DA7AEEC03C713D193281F62107877EB6C2238FC4230D263F30CCD17BF3D23138055874B3ED4415203A9AE367F9AE5B235B5A28957EE12D8F256AC6F7B1F7168C6281EE9AABABAEFF5EDF24F9E4F11598ADDDF15E62BC1A706A19CF6E827F049A7B62F185D2D02D92359A76D53C7685230934BCCF1D99F49966BBCBF57539531749E79A3B194BC0AA6A4A139BD5C622F65158B2C1EB18887F998A9366277736CE47F7BA7A255F6B4953E32E8E70A18D1D18914D495CC93887D523BA1D4830A6C71CB2533238819511D4E4AC6BCF736557659908D49AA58A29A5E66E4A10139F1A883CDADDA4F2B874F89DAC2E9B8110347E62DE75C6B5D9D64EE1150554D3AC40EB0EF49BE3D21C3FE2C3C6ABA7BE55503F933864B8D0C68C38AE6E0AC92FBE31EB2A8F5AE3F031B1A201473B3ED05FB291E97386ECF56CCAB597FA4CD43B09E6DAECE3B24840A459BC6045543F140E52B98AEDF21DC5F14074F2EB673800604A588DC0F0D13A48246FF3BD31D3EB9C6F110391927322FC8F4C9602935430D94CC9033BF1881C1EF805377C7D10C55A5AF2520A0A9D459EC13E4C59CB80CCF0A64B092851DDC7D418ADD1C8BF91E45623411B4390CB870F63DBB9A014E98FF19D5C8F54B64EBF931A4124D8133D7A9CB5A7DCFF89313F39A13075C70E68CA8D82F9E9A0E4EAC76ABD148DA", + "DF79AEEB00A7005010721C0E9343ED2EC1B837DE5561D1E68CCDE437995BAF38" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "69FF299E2D6B9D9644BC6A51D99B4C7090B5D1B57D07940FA9FDA30700EFF7DB60D970D56F65667D5F9B40224E00D0499030EB3A3419043D366534BB688F9ABAB691D4B6042B992FE700B8D9CD692BE1D866B6109330190F1BB62BCA02B3C4AF50291142A05C47E94833F10E3E603C7D4E609117944924C4DA9E25E7DE5923B29CEFD0D2D369D7BEF447B63E7E4A332AE9041571DD91B20C459E5A96A58FF51622672DEDE9889564334C841625F5A0053E28EB4C253C1FBAB0C526F5C76918502CBF76CDDCDDB8DBA2CDEAE6653F6B885D678F4E495603591412DF7022F3A80DA638968EA9506F66DAD3D3BD10C06EC8377237F6CA2C35B32E40C989ACE1B51C2ADF4818586C01B92B3FBAC7275A1A2AF8F6A75F030D99349D5229BD87181B6A033B82192D686B3177EB51A07EAEEC2DC4C6471315C9D9939F613F7BE64F48C9050C0EB4FAC15AD553D3249CB9D8AB8EDBB1E4A97E1B8C5EFAB114DA0177FBB12737F1EA0828A0B6C4F1F67E2F5B0017183D07A77ABACB823C59285B730AE0FE574567F4A9FBC638F21CC567EC8F317C0E9729B21D82E3DD8169CC55BC67D2182EEEF38349A3AE589A4C3970B1D9EB9FB6DD540BAC5CA72EA0DC5C88FFAFBFF6B5F1F1F5C33E2471342D42F4483CE4BE0161B27F3692CCDC98AA3843263BD74B93B9198A768659787A19F3369DCA71E8BE2F861A3837F095D84B3AF06A780487660498A9723609BB89F368D2B1111F61B8188D54C67DF9C9DB6C742553A133ECDAA1A4DCA5774A69C1B656834C4ABCA3E1A402DDE6DD2C21ECF9E50D861CE2F98439990848744E7B0441B5A26F43E4C9515FA65F163B85DCE55DE645CE14CAAE06E95C1D7FD427DE8D440806B2E2C0F92C1FB6C4C4D9C6419821D4CF16C305F73B80F3C4765A6C4120106A530C2371921F1D75DA16C460A0197AEC0139B610F5C8DA33DB072A933180C5E3D30541B6DF54C19CBF101BD0DD0AEE88D75C54245DE8BD88741979FAF6A075D6C8DD98FF3F43B7EBAE04AA10966DD915C41397D1C951754DAF4621C59FBA51E13900218B12D1DD819D811909C31FAF7209C5E4ECFE8592C2F53C5CBA07DAE50EA43041F1E1823B0DF4A959F763D9888721550C00929C395D7202C452AC256A86A996C0758AF340BCCA0CE7F474471ED34A49F99584957FA76C431DC8963A22C640BAD8EBABB0E8D73570F985A374CCF137F7D6D24E65837C5A822C4BEB8B065B408A962D618A5C8807A524CFB70A18D74FC5F4CC3C38FE19F613A9083BFED79A806B00825CD07DBFD119BDD7DE7EA766F6B988E631E4D7F5AA614F43B3DA3DCA03DC8F63FA51A9A07D325B9A2E4AE42C3CAFC7BA46479B398E770A9D627761F0C0BDD0F51D42420D2FA9188339DC8BD15ADB83C816DDD5D884496744D5F620A4382F9DF60CB6EA326035CE8B0E38AF6DDD17C5ADB5AF0C091DB487646DA758B6E464B3564C452FF040D84E1A50ABC4B4CECA7F54C27ED31918C6DA8F5746CC02D58BA8E198E62C0066FFCF449DB78ACD9FE94A2AD5", - "572D524CE030EC1E68403DAB418C05D2322A3B824576DBA8BE2829F17005D7F3" + "DCF4C1739C9643E96A613496BEF0A477B097D62A9E4E93B0274B503E5A322F10C4C019AE18EB80C136ADFBC95489EC340E59221C12013A0525BC3C5C7CB56C6283AA12E2B058B9A16EE748C1E613A2C03801E44E39C6989421A6529227BC811A73B2301D981152476FF6632411617EED110C5DC448C8B706ACB48D4E2781C3904053817D07B56E9A2C24A3109710208842792B67E2B5E2B576667985159694CA0590AA4B0C8978BF5FCA96A725CDD10212AE92556BDC000BC77414D20BDA257E5D559AEB4BC75C0652F8C5834167749E589F2915A4F9C406F520869F234BC32B6C72C57E7297B1C5A68497A4C13B53255915B372406AEE46B3A7B418FDD439CCE023222BCAE78C9B405A396D665689177A7AD360730B370E69A76A56C4228A9089695D0D7C43C6D042AA01AA2FEA7025C391253906FAA97ACCB74149F4C44C902C0A6336DD76347578C88058C4AE7A54908A853745971C7A0365DB8CE9433A1686C7C7D16840F6725B254A51D2A8DC659B6A927B5EC074352BAB3F559DB71812E2DA045D9C10B13A1784E46BC7E926D018145D789B78A7C65B61CDD1324859F30A42A168219B1D5500527DF205001D4D5EC66534FB33B8410C5EB0CC0EF15FA344723B2A7B4C0A520B60562D341486C3103A329332989057DA75274579F7A6AA62D51EF98A9E931C5654AB126104879231C4C1B43E2F37B3E7E18AB13A352DB65367C392CA6721A43A2C1D2B8ECFDC5F59150473E2659FC0C57CDB91681C28DEB5292C376608497D87119F85D2A994C48AEBC8166589124D6B5E20E35E4E52275138AF518B19C37AA8B0679B5DE98EA61381BD513535E7847D6C9C3FC58A6A489FDE1C33456AAAEAE92459B5BB4073808F4C512CD8C06F99326AC2701085C711D78D8D41916AD93F63626D2715C1881854530453D69B9A86448A50F1809370B69B645DB90B04AA27A997A9BF1C009374049F55B77497E6AF622565686825DDA321D64005D4D457308864E352C6FF345B17A57FDA64022F05A80CA61A644BAFB7906B38F1255A677300739A85DBB1C0ECC0C3493FFACC023F3B9541D217DD82A4185C6BD1B011E8B9C4ECA71824651B1AA41EB07AC5EB07B9119374984B99A57307C5E608989A201AD118C1A06FBCA614144C8481714B77D5B821CC0B50F80C91443A92420DB8109ECE0686E00AB130DC67C7A867CD3A27A7BC27F3AC19D6159F3D0063F8DC11FB841AD83BBDC8A1581C69C5F9D01805500918C496F3E48F529112F0BB89C495599E14B0D27B1D68C77A7FD24E4402A5C93C9F81040448B67A926C8805F9AC34990F0B131F5E8A4A09E77E9FB380B62A5224030ED0663E05ABACB64332ABBB4D8816456E5780F69930C51355A3F70BAEE896CDFA61A1419570C31341DBA662655D92B507FE336D1A58B0702C4A98C2965E4362FD56147B299E5A0B20DEC6158EC8874C25578EFA4F228BB73979208AC0A4FF1288288AA3B2F57C69D33790F7224EE769ABA0406B035A9A4C8C2812CDF321B74A875BB0B9041EF92E0D27B71A3602D6CCADD882568135AEC5800D65AC16914B597B526E9C83B59CD2AEC3825A24AC8E9ACB9E80220B97881C9650C2D3E496F888265D60747AEBBDF18E7A766E042F456472C765A758B9AFADC7DE35B8F9518DF30B791F178A7F57", + "E895B8DD5C297C811D01281446C44C182738CC585083B068A5DBCD5368C82EAB2141A11B01C28BE800CA932356374813064CC1A60A72E5F4955EB20DF19C9060C9BF2B0B4E0511116F4A49EEA604D6633848D264BEF77A35F643CBAC92F5B25F686011BAA875DF33121E84CD6EF51F0927B3EF4A2AFDC1BB071222BCEC47839875379741EEF209D3F5118CA7AA103A11E738C5F881BC60A67F88B6B47E757A32340EB653C2CF3C6673CB41E843CB4A0875A249851CB7CDE5D87A4917A5F03C558F44451E4382D4E0082F48B4DE501B813270DDA80903C81409EB8470D16B52AABD0EAA8ADA7AAE24B919CA95458334A4AB566B44F865CC78C9CFB8214D48855D0413F2EBC51302014CD99129B6BD8AE11983602D1F05C425138D6DE17AA1F8700489483D206BACFA4E5746A6CED9B6406785BF85C7252641566511DB8C0F72AB752382374C72365E0A9548169718A910B29B6687AA9966505E86137FE845A94F74BC01443DC9F81B43E10E1D7A7265E04BA4F7A733ABAC6F6316BE92292B942E74D04DC3419385EC3AD1C3A10BF97DC2B259DED665DA7258342059C2F12226D46572EAB9ACD9740E779406A73C7893AF3F1C027AC37C5A7451A6A87730B105E0AC9645BB2CD1D2188BE4BE3FFC9BE5B956CA460B50A40D0CFA6BB69107DD1736494C7AF59148C296655FD0630BB14429B83F1F057AA9208B3F11C05B29CB1EB1044FD73AEE659C2040C2F4DC8AB9F0664122793FE89C2536869EF71F80629EA01230EC7648977740D6B11A01FB88F8F99766692ADD588C55591A61634B527909DA61782E995718767D20614175BB1C6FF360371A1334D5B820AB33A03C582AC5163FB606AA489C29385DBE2B206993391FF37F7C3B8B265939480AA01A451AF40C607C18958891CD8CC21984F09426B20570891E3E090DB6422174A03F8D151725126D6C246FE0AB0232279FCEC27415A417CE6424B70B3201AB3E6F14AEDC9A069330AB0949A30FDABC6C051FEAD73705F2645684B7A78654E0CB531205C3F00780F218392C338DEC8566254117CC186A3412AB43A237F4306D68634D8EE624B592835A37757BD645C79C8EDDDC5A33773B6B086003654894577F59F6BCB46731EF66A9A1B96016E94F87F4199384460E02A4EC37A1BA1546106B254EA53AD6B47869F556BB88BF5012CEEDF61C69F3551465222CB758FE61BB28B541EA4CC28F71AF5D115B7FA256126B0329C579E85425B3C9A942B81FF8666C57D20FC1443AA6B5404B477240271ABE3566CD28C0AF5203E6981D182B10333BC0CC62CE7F124CA345A0CF55601EC92A14D7783A5671054C14C24533754BBB12947D2A4B24168932CED48E69E619A806C3C1DCAE30495018F08B02E66749E3B80F686C32A9833F3737154854478839B17ACAA4EBA98AC57B1879BC1E348CDD4631091386DAA38E12EB1DB64AAAB17C441C8A155949C23357552EC1A4E7E568823804A0C0B35AAB0902AA3E5E18C478D48F24A2B4E205331F25AD5069AEADF6C293D68933E85B27E2158FBC4841BB873A758999D1517A87A4DC89C42DCC69C2D18F8C090D1B3452411451307BA7C08C602F9754F1C45B6A376AF35B36CF327FFB9586A8D23EDCF4C1739C9643E96A613496BEF0A477B097D62A9E4E93B0274B503E5A322F10C4C019AE18EB80C136ADFBC95489EC340E59221C12013A0525BC3C5C7CB56C6283AA12E2B058B9A16EE748C1E613A2C03801E44E39C6989421A6529227BC811A73B2301D981152476FF6632411617EED110C5DC448C8B706ACB48D4E2781C3904053817D07B56E9A2C24A3109710208842792B67E2B5E2B576667985159694CA0590AA4B0C8978BF5FCA96A725CDD10212AE92556BDC000BC77414D20BDA257E5D559AEB4BC75C0652F8C5834167749E589F2915A4F9C406F520869F234BC32B6C72C57E7297B1C5A68497A4C13B53255915B372406AEE46B3A7B418FDD439CCE023222BCAE78C9B405A396D665689177A7AD360730B370E69A76A56C4228A9089695D0D7C43C6D042AA01AA2FEA7025C391253906FAA97ACCB74149F4C44C902C0A6336DD76347578C88058C4AE7A54908A853745971C7A0365DB8CE9433A1686C7C7D16840F6725B254A51D2A8DC659B6A927B5EC074352BAB3F559DB71812E2DA045D9C10B13A1784E46BC7E926D018145D789B78A7C65B61CDD1324859F30A42A168219B1D5500527DF205001D4D5EC66534FB33B8410C5EB0CC0EF15FA344723B2A7B4C0A520B60562D341486C3103A329332989057DA75274579F7A6AA62D51EF98A9E931C5654AB126104879231C4C1B43E2F37B3E7E18AB13A352DB65367C392CA6721A43A2C1D2B8ECFDC5F59150473E2659FC0C57CDB91681C28DEB5292C376608497D87119F85D2A994C48AEBC8166589124D6B5E20E35E4E52275138AF518B19C37AA8B0679B5DE98EA61381BD513535E7847D6C9C3FC58A6A489FDE1C33456AAAEAE92459B5BB4073808F4C512CD8C06F99326AC2701085C711D78D8D41916AD93F63626D2715C1881854530453D69B9A86448A50F1809370B69B645DB90B04AA27A997A9BF1C009374049F55B77497E6AF622565686825DDA321D64005D4D457308864E352C6FF345B17A57FDA64022F05A80CA61A644BAFB7906B38F1255A677300739A85DBB1C0ECC0C3493FFACC023F3B9541D217DD82A4185C6BD1B011E8B9C4ECA71824651B1AA41EB07AC5EB07B9119374984B99A57307C5E608989A201AD118C1A06FBCA614144C8481714B77D5B821CC0B50F80C91443A92420DB8109ECE0686E00AB130DC67C7A867CD3A27A7BC27F3AC19D6159F3D0063F8DC11FB841AD83BBDC8A1581C69C5F9D01805500918C496F3E48F529112F0BB89C495599E14B0D27B1D68C77A7FD24E4402A5C93C9F81040448B67A926C8805F9AC34990F0B131F5E8A4A09E77E9FB380B62A5224030ED0663E05ABACB64332ABBB4D8816456E5780F69930C51355A3F70BAEE896CDFA61A1419570C31341DBA662655D92B507FE336D1A58B0702C4A98C2965E4362FD56147B299E5A0B20DEC6158EC8874C25578EFA4F228BB73979208AC0A4FF1288288AA3B2F57C69D33790F7224EE769ABA0406B035A9A4C8C2812CDF321B74A875BB0B9041EF92E0D27B71A3602D6CCADD882568135AEC5800D65AC16914B597B526E9C83B59CD2AEC3825A24AC8E9ACB9E80220B97881C9650C2D3E496F888265D60747AEBBDF18E7A766E042F456472C765A758B9AFADC7DE35B8F9518DF30B791F178A7F5723B32723A44FD9E241EE028260390984E116CD064323427A8B6C5522B88E4B710E8C8283EE8787183176BF4AD28F8F2EF2F01856A2EE84A9715D103158E05F00", + "1598C20DEAF700AABE2592E50832B9DFC33CF78B8BC71B0A73059F3C01F8DE719F65A0623734281CDF12E1AE6284AC5668B8F0F758A1216136528C00F31810A293C05D4432BB63F3CE61239FCDD3FF45DD1A50FFD2DB04215FF566CA9E9AA9E37DA8E78BF279A08301AAC779E3752F05AB33D2DCB7751EF3A18D99B531ECDB7C0986B35C0AEF64897BF24A97E480C05988A136396F9AA29EA73DE77FF41788199C207829FCD2DA68C2DAFA3EA3A0C6783F9A1678F5E6E81E84425D0AD26A8A84FA09DBD27D3C8DF52A54721EB08ADF7DB3BA9D877A6C116C408B5C7BF9C01C0EB61DD9F02D645A4A744ED5AC75FCE2751C4253693912D3A9A71E469A3A7234CA288DE993FBDA9CAEBA8A53658EEC19D8950776FB332DD0D6F64DCCBDE238F2E7BABC82BBDE66FB202A88D22EE1C039AF0921F893689B23AD28D3BA7D8DB87F5AC229733DAF12FD5B10DE452035D7204F996AF51B0F0F7C2A13BF4255E9A37157F26B97BCE1BA50A72B9FC9FA166CC8D499A1BFA96BD4A8EB5FCC8659C8F6EAF381FB968835440ACD41D80450548DCDACAED400E0EE3FB9BC7C180B53FDEDA20F7EDD50B467ED082F408452314C42F6E3A77979379CC0DD83F1FE1A8A9DB4DBE0999365B14B9D75E9AD5533CCD519302904126C18ABF5CE0EBFF5DCB90809500F5B688A9AF48D64FEF6CC2BEE955906776F3BED1745CB8CD73063F5445F696A073C370DECE09FA071B66DE6B90C9D3B62D94E44F40DAE75562F5F722C55C13CCE6059A9156DC917A7AA2D28887C06841B01E48ED5F1E1593FE38BE165716081E5287B747DC8BB58666D65E22AC733CE770DFB835AC63E27B1B96520FA4D7C4669131132FDC92F8FB5B4562F72A93A824E3174B4A0CF04CFB1CF6D425112D7F2DB61E8C8FA6E983D1B110B1BB508A6BD37838756F9CE5063D874E7E189C9CD4222A64BD528F532255DE825CD2B954C9273F7A1EC6A85555CC13DDF16D7236C7839597D7F366CDAEEC19C62269A9D2957550D9B5D97CC3AB315353C5A5EB945DB6F9D8E7810A28669C5E4DB3ECDC657139B67477C289043024CA1B37E2305A206FE739075A562543EFE710663F7B479AC9D5642545301D41A655379B31C3CA4B178F23E12E80855176AFF78325C416EF6EE8665E5010E09DECC991C061A7BA20CB597D4D01614842CC918D0EFB314EF1793C50C11ED3D2A649007000ED87F5D76F76ED4AD3B7D218142433423AA61B548B0CE5FEE8C11F66B7712F6D26BA17292BEF6420DDEE9B11070DA1BD93A08AE092521C745B11136B4F9C6AB5ED7722236C4E776E90ADE469879B573ECB3D4EAB2520D401BDF6352C8EA959C9210E2AC7CFF50A036D77209A82843614D5870F20479FEBBF3B68CB5F4B3B6823DD3863BD92A836358FC1ADC595BA0B6376D7B1290D7EE7D615A2457901367D988BE8B5208F7179FA00C0AB64CF5ED6ABBF5FD136D6CE9E9BEFA9E8CDC1AF1F3AE9C95FF5F46F98CC6619A3A664170533A589354CC7BF24196EE361924D48F5AFE65F70779D4", + "6F46D1B0169203883DDD06BDB7F4563B53C742B2E223C2026809CD404EBA55DA" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "27FA207180726428640D04D6C7581B1A959D504177882AF4956163526A84757E416CB21109A69FEE7794B03580CF4513140F0DF1E9850EBA999103B547DF82F0DA7C5D42EB9A665A45633C72944331ECD86AB636AF3956895B2A10981126BA7C853EA010E7902D07559269E15209FD1F70AD84F9011639753AC9174C98897C2965D47941B26C4EC1716E794756A24949763A6CCB410A779116811D4D544D12F19416F1E2D10E33664905840110F7E05BA356FAC2121E0E74B4B27A77E70AB6BA99770A3FCDD4E97D1B07EDA187C6AD20FEC18CF897D2393288A2FAE08FE800FBA5C2541C62E30E3E390BE141A5468A7C7879D1533F1DBF8A5E37861B889A28369D4495ED3B8969E8DB21498FA8B8F4EBD971D19586004E03EEBBD9AF1660140199986C2531B2AA23C6EBE511F962E35F18F730892B72F4084CA29BBBDE04CA6BF722BFDCBDC329BF32A34DBAED2EB7706153F17CD44205A9A01A7BC010D857ACF4B4E18B9EF9502A8F9739A5199DF95F65F271983E8668747F399CB72ED7541525B2F7B2ACFD1559E217AF2EFD76EE638F11D909DAD84FFD10F5E7395B5451800F0744192240DD2A3A8C8CC720B8EB1C0E8B0F94EE863C02CC72384FBE527BCE76E9BCDAA53D13BEA3A3C983540B86344BD66FF650A19251C7F29724D144612DFF8CBE9C80F56817C48E9A6C189AADD20A5C4E21981560D7FA102FD5138DD5235D75BD28A139F0A8BB6BC0D4B82E3D816A75AB6916DB36C948D78F97705E4C0E7FD0E768C165DDBAF51BB103BFFC0C43324DF12F6F4722D11D7CEB3BE089103AA59419E114C3E830445C5F68D016C861EDCA24232C60E61FCE57D8CBEBC00ED17775701CABF02E3B57BB83FE92249356719F06728A107A8E25AC69E947E42998B285500B10625DE05DE0E18842EE828C4203C4AD8441336FE08B746E6F72206D4B9E9C6A08A5028BF7B7FEC2051B9799DC8E0DAA1EF92CE80B41ABFAF2596325F67AC0833589499E2418C55406D40EECEA4FA122D8509107B5787455B8A58A0E43872AFCB7F3D945CE1DD98F95706765F2108B211EE88B1B60453879DE5183025E0904DE762E219BACFA402400489C0DF991E16BEDC388EC3B1587AF497F212B8136F377F8BE3BE43E5829C6B4068C0F498F26C6A6B056D4BCDE4123B71F96BB8DC44DD435E34FD7E722160942FDA43597DF6850641303AD72C8AE73D578ECFD32A6E68610CD547F4849421C3468C810D174A0C372325BD3312B6673BA791057AF7B2791A36B007F5D21D53B4D9A8ABEC826591869146D2CD819FA1E7B53F194D242B85D157F98F5DF69BB50D44A31CC789407F2BCA0C93CF8AE5BF6370D679638E6D4E042B785394AFDF9015A75A849559131DD1B64987D48C9C6E8C7F84A2D3F356EEBCE942B8C1A68F19B1EEE3AE01AC807B4B2EAE66396564E3C298781943F0562629B992FBC288092B046E9BB865D97CB3B592A18B56A48283900C3CD39EEA21CB11D4EAE3E3CFBDCE4042383B5DA5F479F9F667C2A8C8EC0D461A5FCE0", - "9D83535A535F248E2F90932240AE440E670C859C750AA41E813C209892B9BE91" + "073262FFF5AC037692ABB806C1B416C60926F684AB314A0C90A90B0DF1382F701349A228EAA7911E37C26C69A170782314A928C5E27445322A17C81401D71BAF1B71A63C08DD0A9842DC9A6101BCCD91C73B772CD54A3401B435FDD929C84C3A884597E15BBB47D21D4B933E86E940A554377BD90271E3B5DF0C0D06E3AC1C523CD0A36AC025CF122C619957C3DEB286A7435660D33665466644DC5F4097CFA7B256804909800B298D31993E2B89B024337D58805AA62E8454AD4099448C6C0C91E93DB3673478A35B89540D235C4D022BBEC35176A29936EB571F4660028109CDF825B979F5A6BA51023A8432BCA84A6A90CE544AC57A091055C1099C71BD6604C06C2515130C1A55D6C9D31640D4E9C2F9F1A4C74ABB6701B9EE36238D40B6D682CBB6623AE7665A0242B140F4578122BD5111197B51A7F860357EC6ACE05103A035472DA73548F51B1D887C02042600D84B9FE6BD11635AE8D3AB04B98FDB179EBD148596A3184EDC1210D888DBCBAA1131AC87555F427A86B9FA2CB3EC6F04E3C4A6738EA8E3714A0CB99E09B64697B1717C938CDA2C8E710CD380A12CD988E5CC5F571C47432007A0B3CFAB55C2CB96C948F3829505B5142B25502C7C213027E61793D34844A28A8627AC6BE9263B0EEA0A6A5CB90AA3496137A20A445B93D4605BCB83AA371C2F5730E9C20A738665007D57BB249692AB513BC66FD04486F05C749A63C5C060442B971F67BB1077A0B153986B28BB2900196753CBAE833B277268058AD9680134633BA4B7A4315344166939E9C15629B3A65649E8577289063881B4ABA3655FE8EA0BC58C7017A249EDF43C27676708411949567B53886903B8716AA65D9DB52638F893ACF261BA7868ADB10E3D57145A475C9B8613D73378F0A285D5E29D817592123BCBA8F5CE075BABB112BB0688B311F35ED6831F3F4CB062064B5CA5363267AE9AFA9818E71F6BA1987E479DAAA414C0004BF738445AF250CBFC8746E85900DBB972834F40D210672B3EDC20912961162248B084B99E649A67637A036B974B04C48D750225835C354B92939744699D3159818B54FCD844C64A5C57D3B559417C14B2276C38B122773C99682C6AF988214472399719A86362DA1B1CE6812AE1714F70C1B125BB594BD4CC55F99F3F30145CA6CB2A66235BAA381417C35003C7DE867BACC81BB3543EBD1339024C4DE8CB3B0350C98477B5B4F7AB83AC519C7438DDFA3097B70FD0F1B2E6C220F67C3CD7188678EA1B72267FFA4285D476517590BED240C0A81A97786622CF1B101B012F132CC60015A59DF3A6C4578928F6035A662EEB78CCB89552F165C137A60256464501658C1268AA70B3A3AA665825840EB4E015C558BECD923D32CB8BCC2C28A3370A4614C4335574BDF77446B34D9F5A7E9EB89738148C4AE56D9B1C829A6935209227682BBCE13522D991B4D2625DAAA679B4DC6A118A672D5C247607A9620C1C88CB7600852E0C394005F45C54175BEEBB9BCB3C3873622501F0B80523294F122C6192BF5E53894A64A733E830DCA814EF7BB62BA60B667CC169E0A165528B46ECB2980202E2AAB0EA5961168C6933C6240C85B090801CC0731A0FC70D09D83C9F2C7142F2C5ED6B7C7F553439E8E45B93898C12ACFF89DB7D67EE875DD9834F3D07B0", + "0418440CC60A0D376B474C2435C349E16051F96C6F93E3B7C2EC6BFFA352B31BC6F0D23D9F592EE3CC9330B49E297A8B94DC511825BE4DF459B35173696872CCB13F78F270E35A452AC55DCB0A0E01809012539B990195CA6875660B20DCF00040048EDA934CEEC501BAF21A6E54B096C8AA93E142E98A7C6A496663DB9317585CF731644AF55DD3C34CE8988E48C27BB9B28F5270252F6A84AEBC54B0441A7099717AA68DD955B9991C533B67C6977851EDF611A844055A47B5FEA256745C34CB1C511CC934EDFC7448D5B8E0D681AD6877168815FCD4740F1228236C43A23A7C208CAC0D8BC8F4855049310B5C06A49A8706EA134B4C179823632B40489C270814D102310C35B76FA5272BE18497A7B6B5897D9FE7246D3B940E25AFB7C44C41DA25E4128948E78CA8D11F241243EDE3A691D25DBB4323A884747A8C514CA0AE4A89557AD34F92BB414840BBE7AA5E3535894BA72A9C1056A20639D7265D5199922F3C17EB7A42C879C25466BFB5D45195CC898CA8BE53A01D1864C87D548FD4E3B203E51CE8CB140F061654085CACB3CDFF778DC11212F4A50107A2C7003D67A92B859312582C3459A5B5AFC02935F8B462331A416117899C32321670710668A8D15A8B5F73CD828231446A19FAECBBA8849DD0724879D008CA87B0FB8B0152541CBA86BFC7C4251F2329569396E6C1A5AD750001117A5B3486E8F67502BCC31ED9BB28EC224CD1C7E73B6F664566ACEA3CBD7AC063B0AB8A4953A9B95D920A080AB64FEAD7C7A9B304756AB15F44C48D350C6A6A8162B95CAA698B3DF824E293B7EDA91055686F3BE25BFA4006A6AA2200D27D98E41A08382FFAEA541D34A3E63984A9287C2A540BE4401E0EDCCF29A4285313684A972032A047309729D6BA4163204F33E8A592DA824EC281CE82244D24BB883428FF9CB750816C307B6084CAB23EF6327D2233241A2B80069E520C2E6B706EAD3456312961B9167DCE049F7014460F769F22CC3CE8C05FF6D14C2209BB0C1AA0DEF85DD07303D651C5ED3277E284236BE570C3E956FC845BFEF650DD9A6015B2ABE33704C93B8DFC4C814A47AC8F79AFE4E2C51B5A4CF3C8A1C0C828E0529A6B707599B544C9336AB4005FC076182AE778E20013AB64A6F28736E47802AB63C33AD51ED994724AA472887189D579BA6BF802A670CC86210661F3A46F1C93E1EB3CC1E944F9C479E4A48F45E08F8E2753562477E9C350AE8B3E9DF32589527413D154448C1BCE4B55933B8D657885B662672C3743C0F17294276C2AB5703D0324D36AC50635424C3439DCFA7C2B3009E4B934FD866DC7454130445F1898B5DAC33DEE7A4B69BB0ECC3949108AAF59888D92358822522D8603061BA14FBBCB681FCB742DD910EAB7A4685C1968BC1C55072800625FB476B91963AFFE589168D16AF7857025B277A702634BF7A2625943A219455F0139C36102521C0F795363B2C9902BDC51517562FF541E04C12CC00C90B224C32E7BCB0DF15BDFA82F56683ABEA2C2659A35331C4625C2A5C0D1B9B036AB7C2A879E6531F8A08249795E5BF2C920639F50B74DF2F2946D1399AB18049C9107B6288DDA53371D18A18A72A66E167C14BB3D9E9CBBDA76B9073262FFF5AC037692ABB806C1B416C60926F684AB314A0C90A90B0DF1382F701349A228EAA7911E37C26C69A170782314A928C5E27445322A17C81401D71BAF1B71A63C08DD0A9842DC9A6101BCCD91C73B772CD54A3401B435FDD929C84C3A884597E15BBB47D21D4B933E86E940A554377BD90271E3B5DF0C0D06E3AC1C523CD0A36AC025CF122C619957C3DEB286A7435660D33665466644DC5F4097CFA7B256804909800B298D31993E2B89B024337D58805AA62E8454AD4099448C6C0C91E93DB3673478A35B89540D235C4D022BBEC35176A29936EB571F4660028109CDF825B979F5A6BA51023A8432BCA84A6A90CE544AC57A091055C1099C71BD6604C06C2515130C1A55D6C9D31640D4E9C2F9F1A4C74ABB6701B9EE36238D40B6D682CBB6623AE7665A0242B140F4578122BD5111197B51A7F860357EC6ACE05103A035472DA73548F51B1D887C02042600D84B9FE6BD11635AE8D3AB04B98FDB179EBD148596A3184EDC1210D888DBCBAA1131AC87555F427A86B9FA2CB3EC6F04E3C4A6738EA8E3714A0CB99E09B64697B1717C938CDA2C8E710CD380A12CD988E5CC5F571C47432007A0B3CFAB55C2CB96C948F3829505B5142B25502C7C213027E61793D34844A28A8627AC6BE9263B0EEA0A6A5CB90AA3496137A20A445B93D4605BCB83AA371C2F5730E9C20A738665007D57BB249692AB513BC66FD04486F05C749A63C5C060442B971F67BB1077A0B153986B28BB2900196753CBAE833B277268058AD9680134633BA4B7A4315344166939E9C15629B3A65649E8577289063881B4ABA3655FE8EA0BC58C7017A249EDF43C27676708411949567B53886903B8716AA65D9DB52638F893ACF261BA7868ADB10E3D57145A475C9B8613D73378F0A285D5E29D817592123BCBA8F5CE075BABB112BB0688B311F35ED6831F3F4CB062064B5CA5363267AE9AFA9818E71F6BA1987E479DAAA414C0004BF738445AF250CBFC8746E85900DBB972834F40D210672B3EDC20912961162248B084B99E649A67637A036B974B04C48D750225835C354B92939744699D3159818B54FCD844C64A5C57D3B559417C14B2276C38B122773C99682C6AF988214472399719A86362DA1B1CE6812AE1714F70C1B125BB594BD4CC55F99F3F30145CA6CB2A66235BAA381417C35003C7DE867BACC81BB3543EBD1339024C4DE8CB3B0350C98477B5B4F7AB83AC519C7438DDFA3097B70FD0F1B2E6C220F67C3CD7188678EA1B72267FFA4285D476517590BED240C0A81A97786622CF1B101B012F132CC60015A59DF3A6C4578928F6035A662EEB78CCB89552F165C137A60256464501658C1268AA70B3A3AA665825840EB4E015C558BECD923D32CB8BCC2C28A3370A4614C4335574BDF77446B34D9F5A7E9EB89738148C4AE56D9B1C829A6935209227682BBCE13522D991B4D2625DAAA679B4DC6A118A672D5C247607A9620C1C88CB7600852E0C394005F45C54175BEEBB9BCB3C3873622501F0B80523294F122C6192BF5E53894A64A733E830DCA814EF7BB62BA60B667CC169E0A165528B46ECB2980202E2AAB0EA5961168C6933C6240C85B090801CC0731A0FC70D09D83C9F2C7142F2C5ED6B7C7F553439E8E45B93898C12ACFF89DB7D67EE875DD9834F3D07B0B806AF8E3E2451BD2609D06E781E8D7782B5F5A7A3827390F89AF1144345DB681ABD75E434B9C7C69E0B9F600073E2D6761E7B33B81DD6C636EBE07641A9CC8A", + "BD8C66F480EF2CCC9D3AA349F020DA9C5F36999A62EACE288AAB387A2A1A41229BCE8DC1005F3F7A703398922F86E2FC5E4A0F9799C4C11FF3DA46A165268DE2DA7E1F79CE8FF15119313942AC6DD7DC0E1B8DDAA294B6AE215C2924ABB4440DD22691490D2E02C434E30938848EAFEA25DDB13A6B6AC9675D7A55982CCD726913FC82C00952FEE976A714BA341291D7F3261A20945F1F53104D56B3919926F851FB986C1894A8106F0EE94E0374ED9FBE193AECA2B8E6EC615DD39404AB16A9E30FA66BDA5E08A395BC76157B3C3931CDFD2AB5FCC7E2C37D2288EDD7C8EEC9D2D1CACEC466CCAD615D22218C410CDBB0DE79871E5C7947203ABE704C24616749E0CC0A892FBA42EC116D956CC5A33668261D43F40D24850DB9BEBDB3FD648950C13BE2F73DB6FDD31C8DEF189BD4FDA96A5ADB19109E8BA67E8D68BD0FB9FFD94A7470D8093444D5A0682099E9A6E7149400845540A85FD82B338AE79CF695E27A055C6702755FCF928CF1B78E78D7F73446BF446641AC69B7889C9F466BC29A3C32D99BC9D1F8546EA484D11EB26222FACF825A2F96A16C12031C3B2FCE0305B0473270016CE95EBD7FA02CFA5CDFC6F8FDAD31F801AB71AEA2C6E32524F5BE77AE1DE5F33FC4E61A2685A3D4E5CAC57B6803969B8F0CD4D42042E04B38F4F1C9C1AB8A994BFE2C5EABB66E05EF343AFFA4C3500E396609C035B23D6DB7A413A59229928CDD998414E0E8DB3FF7576EB36BD7AD03EFBA30466BA6384E6744A6F568AF579C097E71AEEE0F051A138E6855FF3DE3B83556D0C7F2A859C30B5EBA57D58B3E0D996180C06619F26F557261D0F92471600A8A473F735550E9E050C96522C3A2E98EB8ED08643695188A0F3171D6246D815F33536B2711D882B0358ACD95E630BB71FABB29C9B89CFB8FD16BC5231FBCE680D607CF82F1F1C30482EC014F43DE03688022F05C71DB110163A13BF95E095DDB277CDB697E4E48C8E1DD4D1762E9D06B186C5ECC41C2687254A02FA97CA9BAFCF113B6F5D4B99BFD89032EF09D584AEFA3F5A5080A23019493973DA877FBB07F3628DE93ADFE57FB09A0B95BF19CD6D8A563ADF719BA47E2CEE325B00B5756CE39B0FC9F6DFD4B805F5B33F61180620239AEFFBCA9C211048A8AA6055356AC9C2992022F6B601A7101E1E16DFE63923F19842C4463FE0F06ECA2158D04449F10C5524727821FBC4DA70DA0F2BEA5EB0767F512EE9FFE3496EB2EDECDE2795E1EA2DBB5FEF6F8D54E54A0CF235A4E30CD64EF015FD98231148E09DD79EE949A7CD1CA7B70E704147D1976ACEBC3E4D15596D206099FC915256162ABE59542BC149DCDE807C33B89150BDC630C9C23E24F2D7EE7D49BF85FB4C2B47E2F26658FBC0B93EB56A89AFD497D7895FB76718BBCC3431A5FB5EEDFB66885BE1374B174940C55124A30233190CBE636E0418C248D4EB63251E2CD2F5B244F37A76BC9B167E50221DD826E9B1EBA00536E992574C6F84DB4D526F40D29F62476D9C41E9C9763D88EB3718B91AC53", + "9D2EAC936B7D0EF407ED5FB1448B5C511C01607A90D61FC6BE72893DBF60D120" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "FA0A403259997B18A17F48A725FB8672C4BD35699DAA1412DE7C09C0165836583CCCC03A59005CE7C890540C4B9CF05D330AA645A4BB5038672F3619DCCB427A370F437C16491A15A0C60950F19AF7599A1E299E6C40C828A2492D4474C9CC50A67C558351A8D57B4EE27A990982ABD3F935D6F31797E5A3ADD69C4C76893B569F22945B42E1413365C141A81A62ABCEAD2542837C0F1018C266605A06590C7A96296E875139FC7939CA1DF6C07A6F8271539AB8EAE8C25FEA4C313A590BC04E25E954C648732330726BCC3FEDC39F46320D82C9B20F229D211137053BA72B05CB2FC897212B184839AF8324A189B9A855C0B232447668D899EC675075D35FF5DB53E9322C3F3281622A05A7996CCB52159255AE012886B982A1E9A03CB1C3A0199A32001D75304068560162295C8AA8574ACC363D806356A9D388283CBD0D700C36DAB8B55874CDA60608FB90EF4609410459A5319A4F33AD7179329F178A6870BCD6084CD8B213A06C88934952FF75916987A738A3574C60451D70AF60C855D8F78C7E680157320938658F6A421F1B590C7BE87429B95F0B5A5178B25E3F2B61E9268D41486C05402423D12D529B2C8AD109ECC10D48E6841AAC7C2F0B22700985E21A4DEF6771F70AB01919562203925B16802824877142B93517733FE5922BE28638B728F6CBBF21D079A2A61BF1AC7995272031E076EAB6B68B12BEC782CC3C967FBC956C0F4C9345967D59C17E55C8926F342BC6067FAB55781ECA4D47016258C0B6A3A39C5EA98FB9F46745D52AB103ACF7D45D6488B91F872BBB313DF76247D297AEB8F87EE1C63A2BAB82EAC59F4F80CD9E1B845853AB0148A4F12A09FC9822180436BF7033C637CD17962B19472FAA98957B226C3A337A0489CBE3B61E2BB92DD0A390D54C5D56893529C75F956A415D3441F696B8423187C6B1C6A31C2C42F85003900540A21C00546B4AD75F1C001BC56443AE87A87B1993F5D18B4E1211100206A3665ED3868A510BBC70C6353DF89BF8B933D9762D499BA61257BF15D653EEF42CD737BAE25C03986644F9C97968CBA2BA7A8725172C78F15AFB659221115169EC08D0557C7AA996551061271747144C281C94181BA2177803BA6B671A13E406ACF5B474A0CA96D18A96997CEEE6082C218DB27C94FF4C55B31C2CD0BC4438AB719D1B1C6EF46E69298798986EDED0C83292A70CA0B061AA86B625C3803B6389021238457A9FE327957C63D7E11727D7954203C720244AA5D80F6C303DE49B73D71348DACB700B7A4BE795C5065110E59264AFCB5665442F07E14B39D591F3D56838C98C78F8A04CC1A2D1011B2D32323489CF31581E03457BD1876F6B2295F44A103F0C4ED3F939FE16C52DE113E7AC8F4C955FD88B180D8CCDFC605C13CB6657FB9E4AF7CC702B65A13B9C121536094292BDE5A7A752CEC8A2761B2CBC20E882F8B651DF73B23C4B23C3C8309A50A0AB8A7F2B43548A143C40A597D63946EFE4C9A24CAD0DC0B98C6A9129D6B2C2C18D4FA4837CE72084C514DAF3789FEC2A5098BFD2F1A9E056C0A20A03E62685E3FC6AAAB3AD3DC20FF4AC686ADAAF9D1B2FBA94B43D55984A5364B3F7B5ADE02241214AA5A663F11903E7550FD4688EE775DD2ABE3F3E5557C554567AF0405EBC8FFDD9164359FC38F5", + "2D13797FF507986C80E5F2B7CA112C219A73BF71C099943770668F7780A052319466C2296BF67FB71C65EE31C24027A00D3527F3B03D407CA04E43AE2E030A6009BA7B851332B4C5345B3964A8A6390395AB800B2C87AB4C852C099B950BC5324DF13230D698BBB37CD53738EB3447EBBA759C7A0FBDA746D348B0DC985BD9D7BD44482F9AE32D0F60060BE6A630BB51E32C575FC72ED3B2A1DDE00E2321961FEC50F4583B68D246AD1B91128A765F6C7BF93CA43CDB2421416C0C711334E23F32D119DDD7374718400ED8CB283B36115AAB9CD83288A817A6697C3143397C5990E4C8880806230B9361884C539A4466AE241002F7854914BD48B2A9B468238D1242EF4758708400DDD4A8FDB341DD87C7D4225E205AC88D47BED993796B239467C6A6BE986967A913AC3933CA1998371CB244711B90DA638E797E78A95CC0D230C39A1CD6282A9BAC68FE2514AE7833B412B034666538682765C424D9AB1F69578DDDF030D3734A620A4D22F24AD10692D5A08665688905639276D3C9263BBF74587816A188249010560540831AA1F438CFB156B701713EAB1C48F01148D5147A13318317A21AABA515893BA84A453F215A6C2B2C7AF219091DF5A376F8AD57825EF09896F414AA577524A0087086915E206AABB25C0DD5669444E6A1D1FBAE5CD5A490B0283D6B77DB658D54649BFB499D78B209DFEB815BEAC20B543D3F386675F253EC296634CC321983338B109BBA7B0326F766E9C90DD1C0A1916BB2D73664EDB1C6A04195A31BAC0302CB8AC9A2DBD725C579CBFB6A9344C4673380599035513586087307692EE79689D3C14A4903197B041AE98FE4643F86CC3B02D32C03231CBBA2317C16626C090FF0219FD7A1B32B5A0C6CF06CCB3341751A29E4994C9154303FA48789D8B12B773425EACAF84004BCB19B468127B492136FDB39791465090B5FBB36CFB42409CF785A5642047DBA012CE89848784A3011B68854299E2171FDD3A53B8B7C2BF3936057BED0F2067E316AD7F925FE3958C026CABF45AD10263DB78387E7C6C6CE7477FC0C95034ABA4531BE217091265CB2CDDAB742F29D21409F429C65B941AC60A7BBDDD91CAC04BE307C75F323AF8D6C155975C7C12839CBA17D22697F672C7357318E53285B19489D79ECCCE667692B116FB222A7DF8843DBA8BCA7611597E6784A8CC73456A9D297AC6D54B942BA902EE20EE8D755256717435BAB9BA336945B0E71B5986D517F02034A9E90C90307B7FEB500472A212949B0F3C5CD22C7324966CE7A10C6EA05598F22BFDBAB8E427630D2002A815B0B9626053D46BFAA65A896169FDF8CB9B763857F6999C6A7343B8BAE4208C71C600F950208068CB57A747F69A3A2215CA23F327FB648B20FD9C53E116CE58C2F4BAAA67758308708A0E14B74A548A8883599BC07173735402229196C7A269F72CF42845B0883095A57212631127010AC9E2291122B4CF416250FD01563A46031028CFF5745B475365F776841868B0FBA99C763503F337D41668131288C0CF84BA5530622F8957A56533EA53ECAB66C19C2094CE340D05A88C010A325017D91AC216A038EEBCA1892802F009561C6168777DB13FB7BCC69248761AB64FA0A403259997B18A17F48A725FB8672C4BD35699DAA1412DE7C09C0165836583CCCC03A59005CE7C890540C4B9CF05D330AA645A4BB5038672F3619DCCB427A370F437C16491A15A0C60950F19AF7599A1E299E6C40C828A2492D4474C9CC50A67C558351A8D57B4EE27A990982ABD3F935D6F31797E5A3ADD69C4C76893B569F22945B42E1413365C141A81A62ABCEAD2542837C0F1018C266605A06590C7A96296E875139FC7939CA1DF6C07A6F8271539AB8EAE8C25FEA4C313A590BC04E25E954C648732330726BCC3FEDC39F46320D82C9B20F229D211137053BA72B05CB2FC897212B184839AF8324A189B9A855C0B232447668D899EC675075D35FF5DB53E9322C3F3281622A05A7996CCB52159255AE012886B982A1E9A03CB1C3A0199A32001D75304068560162295C8AA8574ACC363D806356A9D388283CBD0D700C36DAB8B55874CDA60608FB90EF4609410459A5319A4F33AD7179329F178A6870BCD6084CD8B213A06C88934952FF75916987A738A3574C60451D70AF60C855D8F78C7E680157320938658F6A421F1B590C7BE87429B95F0B5A5178B25E3F2B61E9268D41486C05402423D12D529B2C8AD109ECC10D48E6841AAC7C2F0B22700985E21A4DEF6771F70AB01919562203925B16802824877142B93517733FE5922BE28638B728F6CBBF21D079A2A61BF1AC7995272031E076EAB6B68B12BEC782CC3C967FBC956C0F4C9345967D59C17E55C8926F342BC6067FAB55781ECA4D47016258C0B6A3A39C5EA98FB9F46745D52AB103ACF7D45D6488B91F872BBB313DF76247D297AEB8F87EE1C63A2BAB82EAC59F4F80CD9E1B845853AB0148A4F12A09FC9822180436BF7033C637CD17962B19472FAA98957B226C3A337A0489CBE3B61E2BB92DD0A390D54C5D56893529C75F956A415D3441F696B8423187C6B1C6A31C2C42F85003900540A21C00546B4AD75F1C001BC56443AE87A87B1993F5D18B4E1211100206A3665ED3868A510BBC70C6353DF89BF8B933D9762D499BA61257BF15D653EEF42CD737BAE25C03986644F9C97968CBA2BA7A8725172C78F15AFB659221115169EC08D0557C7AA996551061271747144C281C94181BA2177803BA6B671A13E406ACF5B474A0CA96D18A96997CEEE6082C218DB27C94FF4C55B31C2CD0BC4438AB719D1B1C6EF46E69298798986EDED0C83292A70CA0B061AA86B625C3803B6389021238457A9FE327957C63D7E11727D7954203C720244AA5D80F6C303DE49B73D71348DACB700B7A4BE795C5065110E59264AFCB5665442F07E14B39D591F3D56838C98C78F8A04CC1A2D1011B2D32323489CF31581E03457BD1876F6B2295F44A103F0C4ED3F939FE16C52DE113E7AC8F4C955FD88B180D8CCDFC605C13CB6657FB9E4AF7CC702B65A13B9C121536094292BDE5A7A752CEC8A2761B2CBC20E882F8B651DF73B23C4B23C3C8309A50A0AB8A7F2B43548A143C40A597D63946EFE4C9A24CAD0DC0B98C6A9129D6B2C2C18D4FA4837CE72084C514DAF3789FEC2A5098BFD2F1A9E056C0A20A03E62685E3FC6AAAB3AD3DC20FF4AC686ADAAF9D1B2FBA94B43D55984A5364B3F7B5ADE02241214AA5A663F11903E7550FD4688EE775DD2ABE3F3E5557C554567AF0405EBC8FFDD9164359FC38F5A5F2297286F62DF6AFAD2C416C876B55C9D1129505273AF92BEECEE3D1FB23F58FDF6905B494AC4D33DE50E94C0F09707654643DFBE1A36E7AAE5B9E4131CD91", + "74AA5FF2D034322EBF625A73E2A0C35F38AB9C3390FDDD656309E2AE19C316AAF13F104D294B8543F24D970F122A5099FCBE0BAAC8B421779FF1CA23CC59DBE8363AAD8B73EF10EA8DDFFEA58FDD12A4D474F33447AAAC13736D34B06E4E99BB8F1C17A0F5F50D4C64007431E781A8055861AFD2CB9A390B51FC051B45B5F23389E52F7AD85756A75F0BF8421B51DE2FDD7468DDD249B0A90EE52F058FBCE99C033398C9BCB36FAC742DA0F74DE679765FF92B8F40FCA320689C3BA451252C95902EF3BA37926B2F4D12D300A5A6E49273DADB281B8CFF493B809591A60C9AB16EE406D23E5F296A7028223531EFDA923BB6CF1585D8B17EB2B73DCFAC84E282B8E00B0CEAD38679A0D7AD977427C3C7DACEEBE5B792DB0FB8295151805D2B805A53101B0CD61DA00D80E49A48792628FA1D52432CEFEF7ECB4C1AEF36BFF4220E3CCA58EC02894EF35736BBB76A73171147459DC24DCBC7F49617004737BFDD845F59EDDCE74568ED0B60BA3CFC2BF7A4FDA2C850CC6D5ACF820A9639103F33022F37AC065DA563321A5B6536B4F215C00ABEC431B5B8DE23B17709D4DFA4CB57B7790E0807D81E613921249D30477402ED3D60D35692D12EFFCD9BA96718831810AB53DD189F4C5520FE9038C7C0B5A3FC3C324AC888A189228C468C2238B722581C07B427E8799D604FE997993B6A85044B1F2BB7EA6D3B75066D07E642D108004F2E17171E4D3EAA09BAD812093B76FC8823BF1C70D0612A302D5CE25ADCFDA914DB31A10172F47FC9BCCB4F71C85DC6E15C253991A1DE91BC7286881D87BF5035DD92953B6E1E91BE2E8DD5DD495FFA6094F40BA948865457AA9E2BA36F066F8B55CB5CEDF0B6AC0D24E84DA2557D9E16D791E199F534FAAC1BACAC74E86896569EFB00CEDC3579B32C31DE1561DF54398989D7CE9956861EC70E931E5A2882B90118DD0A30A1B22A1AC08430A07277840307E7D2FA9FA9E5A617A9A13A225A0878121D1AC53C85364CC21F65EF8DB5D2E3D3280763454A91AD53C79A276BE18D86C220E15CAABF56CF05C059DF4B9120807A82934AADBFC74252585BC0A60E7D5F3A2A73EA22357ACF1B87B0208A7D989E76AA4B646CA68626768EC47C04F21AAE8B01BD5D389B8957DD870363D45C542AE316E46A02650DF060672D32A2AEF67A7455090F47ACB37F2D495D9252E1196D8905DA59A75100383F8C54F177B52F0AED711486F58D4F6F4D3D9F108467A68A7344DDF55EDB8F36C19B1CBCBA01BE3BFF34ED738F431B2C053396D82C56F5062524C089F2FEF5F6F0DF9BF3323D471201676A1FAF7A600C10DE3A8CA921F563B1B41C705EA441B677DF384EDFA1BBE9BB0A6B877624349511F2A107AB8EBD7A17D15D78B8543ECF48CCF386A341C9D3B13244D34EE93371227CCC9BB8F206C98269840660288BA4F6803D150EA0BD364747BD939E2B0F96784C12D48EF667F48F21B6AF33FF7320694E618A6D240048B43E266475617AB4EFC037B27FECB24D160C1D66FE0F9276A9780BF3", + "A0C2CB4A476C1F55562C7BBB80B88CC98D48E9159A110926660F7CB053FCFE08" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "9D44513CA81A19B9619485AF92642AC01785C277AD4DB73FE96921BF98AE77A43CBB8B576439CF73317795C7130E76851B0670C12B2BA2555CF8F0C541010C438507913609579368BD922E506869627316D3655F20A62B4C8A7BA33A21DF71A964A9225BB81FA84ABFF9B81FB26A64BD65C4EEA5C955B33D2077A3EC9BC99B6A6F9339BB0926856111910701CCC6EB7502193397AA5C3E773FC453991B444001F474CB18AC7957696A643911555DFACBB03CF9050FE86F7E30181065AA486021D4C36B4C12CF34241852FC6CD322531107B038E46760C59E112149BE905C1915B22B396F814C83A3A1A17BA9B337B0C4D3213C79400037FA80BB3143914B56A8E45DE6348325004D5BDAA461DBA04FAC2E57890F1F256D9BE984E13B3200035552ACC6FB319E756948D7363510D9813561CEF17599BBE584CBA99E3D6564D53C30482A148346BBCD1BA4F56017AADC1A6DABC127F23CB595405B930D41185E56F51418A895294C21470097DB0B1E826619D65C0DFC2123428C88EEA040F4346A83F46173D45279F239D55600F1EB105A86A1FFB61738D6283A03B889E7238A31530FF869DE598235ACCB3E50B80FE59BDB2641F2855C38C643571A629C0B2B87CBABE6C6B0BDD7B2BF415A0B90266564B183E362CD8474EDF93C2D780F69973765554B6D50C7AAF23F4B79BFD8F8973B827C9A92625779BE873A92A9D9361EE20C31559DEC154E8BB5592B85C8A1F64CC13B7058486947C1929E3C6C7AA375E6720C41E03FA43045B549A05B97027178BF7CA62EAB0B123CB232A3E4CBA2F4BB66980977A78A7202A25527325C4B5682F79B3614680D9B9370C888301B133FC7BC74441A8FA44979C311C26182E01674CAA2372C681D53A019F7E1213115257E4C9FBC90478EC760786B6770693F5EE149AE60CC7835C0844177D8C04E54096A40491F8F6352A231C8E3348F4A02558503C18E2336C982226937AF63A15693025D85422D695737D649A04BAA617B6524FF8853FD664966302E29FAC6162848503908FC0BCEAB9710A806B81536CC78A332EEA70F04F27C6DF9645EB516B7D97B8F84C8E8C2C5ED87C0678795884A893866B853A9AC0B301C0320AE07C54C9D06709E66A90D69724F4192C6859DEA8054BA294FADCA6DB075233CF8AA159144A48C0D8CF4CD51A78A9D23A805E632BFAA587D66A7DE052829FB9FC23C6F66D6572020C60166A220C5432C24886F8553BB7214676AB135535D0CF711845C0F654774F591144D498CB93013E5676146361071E047452CB31AC8CB1F19B35A009CD12C0B0A7A84B6D983C388890E64408FE68F950584A917695B3304B580B3EBE45DF29B2685B02695356CDCA01869F4BE00A9930D384C5A7C8EA17B7033382DC0DCC806DBAEE26222B94C0A775C0220BA3835659F002C09CA37A8B5870B7D2521271B643496394157C621D44276EA0CBDEB0A01C6094B0C6183C92A9638BF1694CEECF66A23CC7C6D0664D4D09B58F39E6CD1CE4D125B08C66FDF0514A3534F026CC4C2517F9C137288232B08BBAADC635EA6024A8C4667E8DBC0B56556DC565D5C08C6963A33959B67F5A32A851B621A8B31B8704C97D0499FFCB6DA2A54DAB35E2CA31C722856061B3DEEBC7D6E5BBB64A40FA5CA1AEBB928BC3437DFA449486225941948A7228D56D7A60AE535A30A7A04925733F29A3E242F99876E7981502FC00258E67A1367778539C1E8529FFB707E13C1446099C6E681380F9A2D2F90BCA121009B822C1854B185A51B0BF61BA0B56C6FA002A5B675DC0A0752451F5C92CCDE666569FBCC683379FE6A850440346A3112888548D47B0468D7481A840946E53C0293C7696BBE88A914506A49CAEB3E233BBF00CC94AC74B70BA2A57D4A032BE3C1724382FFAA002DD7C9F025189CC385C1A24C10AC716376C98B5356AE9AAF75FC931E342F5986A146E3855F6873CC8BA3CB86BAD732241C313AD17883E86C5E2F5486C092BCB4F718B83213C95272D134A2A745A4D6309C266431980C8A0F86CB0CF03247FCC25E2072D5574009D4B61DE9608B29B44488942CB27FF3749A9480408E62AA47A0425D74CDD276B26495B0956BC398AABCD1FA51D5C342C5C13677D46BBFA994FE633F2BEC53C0B6BC50090ECA590CE5F6B30A9436A741AD68C7A9966BC9E7E3D0A64ADBADDC6AB2F71F57AE0AB344F614619AA6DAAAC767", + "F1B84483E2A3740C62F7B50CE3588848FCC3DD4851D8866250DB6EB10352C7AB582F537F25C0205CE97AF7D5A0BEA7B2230C37D496A47BE92C3657C924497C3DF90BC3B547C3A129C16532F3584620D71F99253EB0275682B75007B5A1387268615708C210B9C8F370CE8304377A535B8CCC0E550DF7521F18536A0AB4AADA863DFC81BC1044B37135B42584A8F7121DDA4036EC869566D551E3EBCA35902372580CE55A3B58934D8E445980453FCD1B9A1C85B73748A98FA837CF677C23268AB2EA42BB642198CC4631753104E9121E3832D34C7CEAB049F7D22F425C093FB6AA070ABB49781EBE1BBD55F663957341E432818169CFA8515C9F044766C397C191C129355B244730339B8E6404CC63B71A1E93349DDB5C2F995F61EB2508B96D51522A3532C14DCB095AA92F2E16404F1B2328006AE9EC5FB9627975B2C764432382A22076F701BD9A5E281909E3F8393DC3671CF26574B412A19B04D8372C5D1550961B38C6DA7B4B0538C978A4D3D8B61007193B1CC8D773777042A46BF496A1895584091B77A498D164BA4BD1C9B6D49A262AACA8CC03136389D480CA458348F9B2B67840180F014892477D1589C89D42B0097A72BFD9C215808B7317922AC360A8D5B1E3689535C45246948501DA8418D0464708CF8FE7A18566920E086EF879BFC154277E9BCE9B7906EFF0B3B7C33CCC09424C41A487B624A692805C5003B7E98058FB2C30D762981CC164D337C8B830552724AAE7B850625EF5556707520FEB633868270E0B40245FD07239B70C8FF00E9236409832551D252AFBB860739BB6F2427B42F0A08FC264EAD743F1E16E592BBB32B99308FC969980B8C4C685FCFC96E5B1BAB05A343075B327D658753B2065693FAC5258D6C149260183B7AA2F100B0564A6553836373A082D1E2843F140984B37ABC75A36A65B0162F958275ABA3A4119641709DEA1028FA620C322BEB210A68634CF93968C5B80C6AAB3A137A14440FB7E65C570CD366404853D9EDA9FD513A20332010298AC6AF9C85049B3AE4368450B02C598105EFA6B7A65820C659FE220B7B831A62DE7002719A7FCD18309AA154B2C3B28932B85822062B16189862F9E89CBF48C6FF612165F529424E34A72728DB92564F3A4135D3B35A4EB5D113890BAD49CFD4678600927C81586558818FD72CD048BB5A6682241081BE2B8B6E9077DF172363D32AA81CCCF5F4BCF2DF0324A2AAB062ABC2B2ACF591C59B56BBD10238D49202803D31A8C33B39DF9A2BD35CD6F8AB6CFAB65717B327148AAE2F598A6851FEE9A642115B7CA392DB1B273BA6A0D6EF2CFA010259B95957195BE2F93A3FAA68C703C7192AA6E7466BD766C620323662943038E349028208D1ACC70BC396D75D4526DC53CC50C4B546CA24969163E06B6246A542C1C776414058B458494F804510817F7DB8F55F9B32E85352FF6A8864359DD39621426711733A929391248D31A7110C80819795601CA211B87AE4323593A5987C89B24C55039DCA23B28A477416974699D27D6219F943937B9C44C472041BB9729624C0A2358CF908505F8C270F6CA12DCCB15A63E8BF88F4C431B5137BA0F6C90BF209832633B0CBA8BABC7617427479701287C35AFC06163B0429B155B91D414CA16D23FFCBB17FD1C3DCDA8262FC3798B1B1B0843CDAAB6C2609422419C54AD94783EEC42D06BB60F844B58F30427908156A660CC5AC63A5B0B2D8BC496BCC1AFB0CE4555C15956B134565F6C5B3386C57013074400E268CEC74A79C08112F734E316C969471389E94EBFDC14416C106CCCC8927B97DA76086B2C5FD76891A62C5521137DA3C30614361984058214B3507EE932682301F45CA20ED97BB607150AF70AD5DCAB4B5B0C3528969AC029C40CB484788A4568A654C32D4224A22E6A5D6F539F0B94AFDDA10BAC1563807686C48C07FDC622C9F153FAEBB85528C53C0ABA383BA51DB5925670BCCDB3C5B5D2C7750A2E9A83B51D1886C70534C8465E9086AB7851541AA4A6B0E96304CAB8B452C355F52034E2481F426F85B03899DA6B0546BA427AC751C84461952A9DC0A93A706B174733D7081CE724AE7CF04F08CA5B92A6CF0495A10DF2B682FB16806B9CDB6157D6FCA8C8A5A8E8970AA96434B27BBB77D41B1C4821EA6A8F870CBB7422499D44513CA81A19B9619485AF92642AC01785C277AD4DB73FE96921BF98AE77A43CBB8B576439CF73317795C7130E76851B0670C12B2BA2555CF8F0C541010C438507913609579368BD922E506869627316D3655F20A62B4C8A7BA33A21DF71A964A9225BB81FA84ABFF9B81FB26A64BD65C4EEA5C955B33D2077A3EC9BC99B6A6F9339BB0926856111910701CCC6EB7502193397AA5C3E773FC453991B444001F474CB18AC7957696A643911555DFACBB03CF9050FE86F7E30181065AA486021D4C36B4C12CF34241852FC6CD322531107B038E46760C59E112149BE905C1915B22B396F814C83A3A1A17BA9B337B0C4D3213C79400037FA80BB3143914B56A8E45DE6348325004D5BDAA461DBA04FAC2E57890F1F256D9BE984E13B3200035552ACC6FB319E756948D7363510D9813561CEF17599BBE584CBA99E3D6564D53C30482A148346BBCD1BA4F56017AADC1A6DABC127F23CB595405B930D41185E56F51418A895294C21470097DB0B1E826619D65C0DFC2123428C88EEA040F4346A83F46173D45279F239D55600F1EB105A86A1FFB61738D6283A03B889E7238A31530FF869DE598235ACCB3E50B80FE59BDB2641F2855C38C643571A629C0B2B87CBABE6C6B0BDD7B2BF415A0B90266564B183E362CD8474EDF93C2D780F69973765554B6D50C7AAF23F4B79BFD8F8973B827C9A92625779BE873A92A9D9361EE20C31559DEC154E8BB5592B85C8A1F64CC13B7058486947C1929E3C6C7AA375E6720C41E03FA43045B549A05B97027178BF7CA62EAB0B123CB232A3E4CBA2F4BB66980977A78A7202A25527325C4B5682F79B3614680D9B9370C888301B133FC7BC74441A8FA44979C311C26182E01674CAA2372C681D53A019F7E1213115257E4C9FBC90478EC760786B6770693F5EE149AE60CC7835C0844177D8C04E54096A40491F8F6352A231C8E3348F4A02558503C18E2336C982226937AF63A15693025D85422D695737D649A04BAA617B6524FF8853FD664966302E29FAC6162848503908FC0BCEAB9710A806B81536CC78A332EEA70F04F27C6DF9645EB516B7D97B8F84C8E8C2C5ED87C0678795884A893866B853A9AC0B301C0320AE07C54C9D06709E66A90D69724F4192C6859DEA8054BA294FADCA6DB075233CF8AA159144A48C0D8CF4CD51A78A9D23A805E632BFAA587D66A7DE052829FB9FC23C6F66D6572020C60166A220C5432C24886F8553BB7214676AB135535D0CF711845C0F654774F591144D498CB93013E5676146361071E047452CB31AC8CB1F19B35A009CD12C0B0A7A84B6D983C388890E64408FE68F950584A917695B3304B580B3EBE45DF29B2685B02695356CDCA01869F4BE00A9930D384C5A7C8EA17B7033382DC0DCC806DBAEE26222B94C0A775C0220BA3835659F002C09CA37A8B5870B7D2521271B643496394157C621D44276EA0CBDEB0A01C6094B0C6183C92A9638BF1694CEECF66A23CC7C6D0664D4D09B58F39E6CD1CE4D125B08C66FDF0514A3534F026CC4C2517F9C137288232B08BBAADC635EA6024A8C4667E8DBC0B56556DC565D5C08C6963A33959B67F5A32A851B621A8B31B8704C97D0499FFCB6DA2A54DAB35E2CA31C722856061B3DEEBC7D6E5BBB64A40FA5CA1AEBB928BC3437DFA449486225941948A7228D56D7A60AE535A30A7A04925733F29A3E242F99876E7981502FC00258E67A1367778539C1E8529FFB707E13C1446099C6E681380F9A2D2F90BCA121009B822C1854B185A51B0BF61BA0B56C6FA002A5B675DC0A0752451F5C92CCDE666569FBCC683379FE6A850440346A3112888548D47B0468D7481A840946E53C0293C7696BBE88A914506A49CAEB3E233BBF00CC94AC74B70BA2A57D4A032BE3C1724382FFAA002DD7C9F025189CC385C1A24C10AC716376C98B5356AE9AAF75FC931E342F5986A146E3855F6873CC8BA3CB86BAD732241C313AD17883E86C5E2F5486C092BCB4F718B83213C95272D134A2A745A4D6309C266431980C8A0F86CB0CF03247FCC25E2072D5574009D4B61DE9608B29B44488942CB27FF3749A9480408E62AA47A0425D74CDD276B26495B0956BC398AABCD1FA51D5C342C5C13677D46BBFA994FE633F2BEC53C0B6BC50090ECA590CE5F6B30A9436A741AD68C7A9966BC9E7E3D0A64ADBADDC6AB2F71F57AE0AB344F614619AA6DAAAC76772B1D32CDE082B6E240351358470809889513B4C05C4611B6C02F4E0B4AF9C2890699250EAEF4F0DD68C72720BEB1D19804203EBAE8B8903D98F25903A764877", + "BF5EF354B5EE7D74188232802D1B421F0C17012ECF2364E4CB996067AB6270BF034E5FB475BD2EB17C1708E4AD606FF23D38D27C1F4E524CC9767087F7F042F09B1C080B055F27CF879779D129823E4A491DE0F9AF496F04158DE90637547262D3086778AB268665CDEBFCEB85F3C5E02ED837AB43DDD97B456921AE2E03C88CCDAE7757A4773B1A207CC0B11B170F19FD70F25350849CB6C39AD12DC69352B4C4A6A9619CFD41EBCEC4E26B3B0685EDEC45D87879940C4C6E5C43FAD20C65FFF64F676847C4A63E7AE6144404332220CCF51B84C26E726DE976A2CC3AE143BC99B657B5F16290B37E43F8680B6BAED4F033FDF189376882DFF74864E55542CAEECB0B55B3FE2BE91EE73A20F74D5AB984F868CFBBA63EA7F6086B19D624278553378C58E3394FBD1FDB7EB86D919FD99D1B79B59BBB4E5AD0EDF7474DB392F2DAEDC3910D02E636775E313E7D14014027CFA561B66D0B249B6574A35CA45F2CF9AA63C2C71B970BAA3DBC0E0AF1C429FBD8D6E91D67CCA4EF9755522CD0FD49216F8D2BEFC9E37E7066315027BE0DC35460B4DBDC64C07EAA19C5A135FE9A0CEE287CCE67A66BC8E541936477A71157180EA185165E41230DDD35408448D9EE281287D6C03A9FFF128E7B3EF71512CDFF126109392FC44977BCEEDBB12C213E4A40F37AA7559A85945E4A14F6715CAE676F07B5237EE46968AD41A6B0AB4B2A0E558688326B558E6EA8FC925080DB42629CFA1F2BC13BE050476D9F0B2614E9EB0485CBE16C678ABAEC1ECBBC82B506A183EE8B66AE938A57A36EC1023D3981A38AB7E86FB267F722479751B0D01092C3D4F267419865225B1E0FCD50DB4E92172D5BA2DFA8D27F7E7F3971C116581FFDE1EB7C97AF66448ED55101A774393159BD058BE12640AC403AC8F62289938F332206AD1C82D8E0C969D7EBD0DDDE9B6A45E3B5B1CF2A6EBA80F91EF87E347B8EF4758EE8654566BA7DB32CAA8D79C914D291EBFAF7E9C6ABA393972F09A5C8821D435EECCEE94EFB9341561E367A15F5ECF2E4758A0D3558D122907FBF1BD0CC21419C9E6D1157F2A41E3CEB5C9C5089666A81D45D28CC30053CB05EF23235C78B121C5CCBE5E72056A792721FE1427A0CAE8891FC8AD94F80A4BCD1AA1287225532C6EAD21C8332AF19F1333095901F83EAEC30BEFB9CD35F2F056452F682211F4AA7E4FD886AB72A52DA710B4B19ADD0722B8CA090C349CC20C04020AD8284D24E67038AEA537E2F42009B24474EC61223D312AC332C189A696E8047EDD788EF78C3A999BD2724F56FA0BFF16A5F4899DC401C6C55573B954DE01F6C9928E2B1504DB33822623B2CCA44D2178AED441F1F420952FE61F1161EEE907F318E1C693BED9496DCAEE654151CA576EDBA2FBDC12714FC37AA2A3EE7BB167DE1ADE78F205C9E92B4E58A2D8A3D7C8788A167AB1B0EEE549C292BFB25B847B0BB7506A69C32DE245EF8D95E625E89A5C20A3D9823C0C021F1B703F2ABD31B0ABB5912802BE89E530A021A83F65EE94A17B091841661A3B63DD2812AA85A52E7A87B497FA61AE16BE69DD68EF016FB19904E8728B8647B4CA88ED38B90870A1BA32A2014C1887BF9390196B504F950C983546C4A692BF5022BF54664328B4C82D0085C8A399C96D13780F4FF9FC11EAC78F2C689CCFAF4483195ACEE717BDEA3EC75021E1691F53878EA9CCDF1D68134C4D8AEADB1D3DFD241424B2EF0636A35173DE770D0556FDBD7852B74A2D9F0D1D8DB59B4A634B1970E3A4037794A2151970B045AAA667F50549AAF71411792D613B1424AEB3748CCB1C844109D0FE6BC9E10E50FDBEA5FEA833BDAFE4E9D9910E366BA08792ACD7B2FB525C5987E16F1A7651B591C1503C7CE66D6D1A230B90C82CD7B503C55BA9D6951FB3C9C626521EBCDAA0584A05589889D018644E6ECCCEF120BED7079C2E1C66C0975B0BA01C29C0F7FDA9E3141449A1B6548A6B7A6FAD868C0A45E7766FC2D637A2A8A3AE68EC7FF3917C512B51EE5F9D54372B42440892F3DA9E4CD713AEA0311EEF7A5CFD8E441DAC5781827D9FC2C86E09D5C680C43B997CFB2D38D2A2019DBFBC144D2C442BDDC12DEE0C6DF9DC101E6BF0EADBAF2A89CCC0FCE10ECE108ABFC2BA288E64D130B2D72642F0456EA24C8B2BA88AD24E5D71778DDF85F8C125BF4710C0D333E4F7D547CFD4C6282BBF9A81BA8707804EA", + "74E9A374CFD12E92610591E05E80F256FA9BC85146F678C0FD538ACBBB765A6B" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "5CF432212464C32C44A8CA8FA6F6620899B08E968B2F047B42B00527901974337D3613C1BC278EE8D5C254B4898E1088D4A8C09EE175969407C01B11C5F8239C4A0455DA5DD6876C18160944054F69545A5340C5E2EC8A378B1824D313D4001F20FBA7B878AC5F490E0EB65C12D0ACFF68C9F9E54170F4137A4C206834BFEF81651C61BF3A6736B981A222994D3571B1B802B5D759847E915A9BB0B1CA894E055B1DB0FC5D7EE39C5695C10A3112D4E2A0364036C1824C7F32627E81176E659AA1B6CA4EA3CD6591CB7E86CDCB57A6440B6D92B08A628C378408ABF7B93CEC59AA19EB648B39170CA87AF41389ECACBA26919DBD3C4870360A72A398DC7CBDA62C26AE6A0419E5229DA7C77C725FFE9AAFA9EB0E5BEC8B1CCA02FE97379DB20143E21E1AA8BBB55B724BB668C10932BA9C58A24536CA9CAC675350C7F72157B0AF497BA4B16425F52069EEE144FA96A40DE99A1FE10D95F71102FAADF1A8A0FE8038B5A49C04C952C97C65685965E18A0BA8B805AE2839F61278B76265082329F6CA4040242A760B6CFD683D52D6BD4E1156BCD181D4C16FDF9C75426A8000B6952E2A023D3A59844B72F3D9BEEA35BE4F70988871C6079A2F49474599C9A0BBA36B8CC41865363B42554D9722B9CF7A5BCC1812889BCEDB1B4DED8B48BB42695D83BE31A543367819EC75851E1B920BA69AABF57007CAB1426C56EDB6B6F6832C95C0834581BF6240674D336D2437B820E84040BAA93D2056C1C3B2F9A0A6536C19F43A1D0904C188421805451BB91C908F159B1D308071D3886287C2CA56263C60A43F67916A3A79B2FA0B1BF897E941514E78968276508F3135D8A9B8E0D781FD41C05EDA9F2C4A9B4FD33B1C80BB690C59BCCC8CED95C1DCE72136125128507F30A465AE10AFE44CB764697B8DC1AD2CBA07C73BB888C9A559407A3D0636A4134A3E162853493C25770D10847A72956FE3CC01778049B46142AF4B4AD1D900B44A149323190500899D2801AA5C031A0C378F5CA3A778C8B7B688EEA26CD720CD8858A07DA46C176C08278B7C5D47AA6AA92753C75BDFF72E88708E6627BEC0335331D38604E84EC712B0D3EC8714E56FFA8807F40B8CE6C3723369883EDB462AD9BC972206A16C78DAF8C1428344E9C76B161A818BF8835A0043621B3841F80CA3F02970F7882B715EFF117B80E125ABFB406BD75027F9AD34EC7E7B629C2D834C90225020017CA511C8E83CAB0F98C739EB030E172A67586D90A5827E063B9C7B0705BB61F5A6067D102776F18950C3C2540198D916B7D64C803EEC3701799DA2C176AFF38C26004F3BC18144A3501D80B580C1442AFCAB6A458C1BB49E5A5728EB2818B6EC539F5C931F9743EB34B889401D19D220CF7822DB6906006B59A5CC90992691A2071631A96B6D8617F7E863C44A610E72A34CAB05D68281D07088D23580F0A87C870684D74C66D1827BA2702024098377AB359F10CF21B7C5EA9A77ECC121B9D81E52B4CFB315CE0076757EBA100F87A3CA1B28785C46B2B2856160213B09B3B0844055515085F721EE47356E31599D0071214C8B1EA44374890838D1C6636383CD9376D131CE1139277911B221A5CFA182ABE535AFF8995F573B55CA3C08CAFBBEEBB92EC280BC351735A5891997972104993F53321E70E571E86250CCF96010FB59FED89755317A0BAA5F5AD1A6CACAC5CA4612F2B27E94D6B61DCB138A661B28B03091C173BF96CFBBE00CC94223328B55F0B848E27497BAECC6A588C24EB34BFA771C94B4C3B6F87A54458941691C6945470AA68552B77DE5245CDEDC8A457805CEA024034C5731C296E0A468BCBA19D0DC7EC3A38615B10E1D7CB9B61315786A2AD737B384E511AB0CB300976324287063A76B589B88A686A276CA770AC9B79A0B0420692AF8D28AFE392135A62ED20C953DBA3EA0B1B740715DB8084B16661CF9F497BC8BC509E9A9BF5713769CC309090ABD3BCD49E69A09B6BD01536883B5ABF87622A93566B51B1E0C8A0A191A0F90EA5995852BF0EB8B3F15BBAAF55B82D900A74507D167CED79B5D51B5A7791055AE835D79C1B0FCCC0B213664BBF35D9B604356A23E89F9510AE2B8EF6BA3FA52387AC92019A773C4F26DB9F44801F00A2BDA3C14B2953486A7E5605E1B523F894510FA8BB85A080E589A4538F3E0C08FF714113962C5A6FC29172509B3C1AEC2FA41707439", + "630859B0E9292AF46619B7312DE45D6D4B01D4A4BF075372B8A345E1CCC66F3257FD3A5B47EA046A168211C807672C13BA4A48AE742DEFB760CC7446F086C0A8B439641A24EAC5CAF3A730CD3215BDE8B419CA04FAABC3FF0CCB8BDCC8AF1495886B6D33B01D25B032F7C3282AA9259E5178D5841106797A5D559882CAAA17EB695C397BBDD297A5E24A9E00532D355286C09197FC0D186666C5D5360E42B1DB865B1BA950B7D1C2CE46B64AC43D89404CCEB3CEE397175237B618D4112917535F250F2AF42E1A05282CB7CE65C73117F934E1B661CEE4763C375820F09F87916615865E30E146298B525B730B1D89AF469509A0F06FCBA5CED2405DC210AA39FC55251A80A8A0037389CA7DCA5D9A10B777B6919B6C1E805588E3F20849E7B2033C5B781B0545A84E842961041891F91A5E5D4C211B86B8ECF91DE0AB42919B1A5B2245EDD54689AA169E61152DC94FD9C1B80E1602F3E69F9BC38455C93FA2757E14A6369E942E8EC9173C9BC9168B83233902EDB01FAAA66CABB796793C53DCE32C1F81C329215EE9002D8D09494C8301218A379E1B3EA221BF2C36A927E4BDE0F27CC72735FC4B3E7C181F07270A8903460C88B5BE499B5763B79BCA1FC964B75ACA1F2649AB34771D90855C03AB8262F99B7859651FC49AC5119AA48A8931E19035C011A2FA7EC4464DC35B8D7D3392EE0B710A98B3E565CEA3925FFC9202DEC07042A12C677126ADEB25EC34BB0343A1DC311D55F464263C0E32287EBD5A6735682ACA478DCC34B5BF119D153A2C26BC4A47E743B5721A0A1B3DEC00196A006DAD826849C1146D01B891F690D7F116187A966A689E4475B6724445ED17CF1FF4026C8B587B600FCCF148D47852C546A70BE6767855603C77258CB4BCFA1CA310D533171287C5166230C759430B5B1027B8F7C1BFD8051DCF29B090423C93E3301E39ABE8F3C145735D5B9A83E5DACA1E013BDFC51ED05A66DFC8CD32798C928627C98393A1DA003C797BCAC402D3F1C6AD5B8F56626D7954A7C587AD7C7223D622A58169B826456088AB50D4A48EF959124271479E6AC7D979675E222ACCB2BFB8748AA9416B0C67288BA75963196819BA8B20B116F79955AED72735C08BE4297F28ACC8DF25215765C17F9A775310699993610A490F2368A87E9019CB60370E1749721B409B398363FA49F0246C08948674E3670F32525A43C337EB9677760264A05626021C2DE7C180935D3532285905AB71F3B94A259DCAF6CBD62BA5F7129AED0270EE86483673693EF90B84AB39A3CC10FD322D7A989E527920526A94DC8CA7AFE677376625B41AAC4BC4027A316323C877C5F5811888925B81A76EBA5D496923012B37FE6C2827872B81E65339AC8BFC57AE68A3C900C026DDA6AEDB09A3CB98CC2A809A7218B190A5749C42AE4F353124809D78733DC52A89850159AB73415988320C7A093C01D03F4492293856A531A4F013950E30C7A548BFE0466987C339DBF08E9A0B4EDECA083C399F2E6971CF3AC647FB5EEF401759E6C292F038DD732847545A63E43E17579C818C3DE888895F3AC712DC6C767158BE311F24E44FCF91ADB2663BBB0B1ACE801495CC5ABCC208F0DA634046503C694646E9368E43CD98A02DA67B1138EA5FB5BAB0DDC87F85E0A2F7B7308AC26B72427BF7F07DE8B5C304A60B23AA50C2E05E68A9206C3859CA017034814242F49C91A734353C0C17D075E31412245C131CE863E654927337AC046B1BA83214336C32CA8BB179F671E010922080BF1C2891967017459788E4B69131651BCE03911AF8AEDD6570ABEB17727BA25C719E69CB226076780BE183FE705E1539480C147773E3C313C359C3B13EEED49139B27AA78736F41283005CB40375C2DBF28D2DB5A767F0814D661B7E483048E465EE012E877760CAD3A25BA95356C087E596540A603DB8BBB45CF05D0D6431E4B5646D045972FA81524B9476F07F03BBAB400150E4A840853B768B0C02B1D75EB4748E3248BCB7CC037EA70F882299EDD18470443D9FB7A479D83A239809C166B6E7BB61ABD1BDBBA7AEC9B2BC55320F17FB72BD842D52DC8315A8738875ADBC254E5AF369FE32CF8AB5CC45459D2F7433D3777312F17171E3B073F01E0D175935E7B870676D73C1015DA7A64D6333E6601A94902B5CF432212464C32C44A8CA8FA6F6620899B08E968B2F047B42B00527901974337D3613C1BC278EE8D5C254B4898E1088D4A8C09EE175969407C01B11C5F8239C4A0455DA5DD6876C18160944054F69545A5340C5E2EC8A378B1824D313D4001F20FBA7B878AC5F490E0EB65C12D0ACFF68C9F9E54170F4137A4C206834BFEF81651C61BF3A6736B981A222994D3571B1B802B5D759847E915A9BB0B1CA894E055B1DB0FC5D7EE39C5695C10A3112D4E2A0364036C1824C7F32627E81176E659AA1B6CA4EA3CD6591CB7E86CDCB57A6440B6D92B08A628C378408ABF7B93CEC59AA19EB648B39170CA87AF41389ECACBA26919DBD3C4870360A72A398DC7CBDA62C26AE6A0419E5229DA7C77C725FFE9AAFA9EB0E5BEC8B1CCA02FE97379DB20143E21E1AA8BBB55B724BB668C10932BA9C58A24536CA9CAC675350C7F72157B0AF497BA4B16425F52069EEE144FA96A40DE99A1FE10D95F71102FAADF1A8A0FE8038B5A49C04C952C97C65685965E18A0BA8B805AE2839F61278B76265082329F6CA4040242A760B6CFD683D52D6BD4E1156BCD181D4C16FDF9C75426A8000B6952E2A023D3A59844B72F3D9BEEA35BE4F70988871C6079A2F49474599C9A0BBA36B8CC41865363B42554D9722B9CF7A5BCC1812889BCEDB1B4DED8B48BB42695D83BE31A543367819EC75851E1B920BA69AABF57007CAB1426C56EDB6B6F6832C95C0834581BF6240674D336D2437B820E84040BAA93D2056C1C3B2F9A0A6536C19F43A1D0904C188421805451BB91C908F159B1D308071D3886287C2CA56263C60A43F67916A3A79B2FA0B1BF897E941514E78968276508F3135D8A9B8E0D781FD41C05EDA9F2C4A9B4FD33B1C80BB690C59BCCC8CED95C1DCE72136125128507F30A465AE10AFE44CB764697B8DC1AD2CBA07C73BB888C9A559407A3D0636A4134A3E162853493C25770D10847A72956FE3CC01778049B46142AF4B4AD1D900B44A149323190500899D2801AA5C031A0C378F5CA3A778C8B7B688EEA26CD720CD8858A07DA46C176C08278B7C5D47AA6AA92753C75BDFF72E88708E6627BEC0335331D38604E84EC712B0D3EC8714E56FFA8807F40B8CE6C3723369883EDB462AD9BC972206A16C78DAF8C1428344E9C76B161A818BF8835A0043621B3841F80CA3F02970F7882B715EFF117B80E125ABFB406BD75027F9AD34EC7E7B629C2D834C90225020017CA511C8E83CAB0F98C739EB030E172A67586D90A5827E063B9C7B0705BB61F5A6067D102776F18950C3C2540198D916B7D64C803EEC3701799DA2C176AFF38C26004F3BC18144A3501D80B580C1442AFCAB6A458C1BB49E5A5728EB2818B6EC539F5C931F9743EB34B889401D19D220CF7822DB6906006B59A5CC90992691A2071631A96B6D8617F7E863C44A610E72A34CAB05D68281D07088D23580F0A87C870684D74C66D1827BA2702024098377AB359F10CF21B7C5EA9A77ECC121B9D81E52B4CFB315CE0076757EBA100F87A3CA1B28785C46B2B2856160213B09B3B0844055515085F721EE47356E31599D0071214C8B1EA44374890838D1C6636383CD9376D131CE1139277911B221A5CFA182ABE535AFF8995F573B55CA3C08CAFBBEEBB92EC280BC351735A5891997972104993F53321E70E571E86250CCF96010FB59FED89755317A0BAA5F5AD1A6CACAC5CA4612F2B27E94D6B61DCB138A661B28B03091C173BF96CFBBE00CC94223328B55F0B848E27497BAECC6A588C24EB34BFA771C94B4C3B6F87A54458941691C6945470AA68552B77DE5245CDEDC8A457805CEA024034C5731C296E0A468BCBA19D0DC7EC3A38615B10E1D7CB9B61315786A2AD737B384E511AB0CB300976324287063A76B589B88A686A276CA770AC9B79A0B0420692AF8D28AFE392135A62ED20C953DBA3EA0B1B740715DB8084B16661CF9F497BC8BC509E9A9BF5713769CC309090ABD3BCD49E69A09B6BD01536883B5ABF87622A93566B51B1E0C8A0A191A0F90EA5995852BF0EB8B3F15BBAAF55B82D900A74507D167CED79B5D51B5A7791055AE835D79C1B0FCCC0B213664BBF35D9B604356A23E89F9510AE2B8EF6BA3FA52387AC92019A773C4F26DB9F44801F00A2BDA3C14B2953486A7E5605E1B523F894510FA8BB85A080E589A4538F3E0C08FF714113962C5A6FC29172509B3C1AEC2FA41707439B37161E8A5BD109953D75BD81E062D36D81EC8718B0FF11F835FD02EBB0E37D1AF05419B0CB3DE1B514404D1C0DB9017182CE71D7A0E69CB141A94174CC758C0", + "13E45134547251CF55515976985578ABA6CA97FC3FF6DEED8E15AD947117FE7D2F2DACD7E681BB899F5F39AADCA87326085F01FBDE655E7C8A3711C9EA5F6604A547D3D019416E46EBBF851BE3C2703A3241188104EC340BB548E5E37B65F2272C104802AB743C88908D299EE6B9F1DE6F8E0038CC9C4AA567341A4984A8F101E2C2B2795D29557D84D61FE9A8CA937C2123F02BC595BEDA11431C1A2A7D45EC5730638BACCF5FE8397F8F3893C729208138912B846803DEA9D70425F52F07CA7B0BC60B09EA741BC737E60B7C27833BB1C7F2A8D650A7E5ABC1A963350CA34C852134A650254389F04EBED26D33F0BFD24877DAB9FA7173B12FDD6B52CCFD5AC840FE04E2381781A626C814B58EE149FEC67A5D978222AECF323E60AD10077FFDAA62960326191D9513F5E44B22D318D51DECDC1598CFEC5CCE77EF12114ED335837A9D999CA572A392B735A1E10808801687F66B8ED5E10D5E0E7561A1CB07E411CB1D2EAA5A55A9DDD146B661564CAE0BDC4FB175E508C43F6A41E2FB31A38F6A6750AB9B92C69B19CE9741733B77B49DCA86CA6A899D39087F285003358D5C8ADD8A8A5987B8B0AACA4661DAC7301383D80B1EBD29098BEB447E0159F06D72A414F0E28410696D71C7D717967196A22160D9B36615240D75998B0F1177332EA3EB3EB6F9B533B939494716A935DFDCC862EC0A25DA2908831A8DAF5030CFDD0262D0CB5DECDB4B468A3A75401D7878B9714F4C4D0C07538FE7DA6CA3FE9AC5FC829787CAFE2833740A6204B85E951E6AF2D5DF448F125004D85A212900DABE0361336F6284A8E3196B06AC45BFF78A10759D33307C4F6861641A8A515B2A56892B4640B0FD5622637ADD9AF0BB1C3F742A7803D2634236C69431C0A41D99E64A8B454652F3FA507CE74233CA4F49DEFFE91A16A08AAECEC3EA8DAEFE6F0981D2B4158AC43E6E10A8EDA0B112CDBF42EE0E5D552B7E523F006B04FABB3CC97D2FE955CA1A6445A017B6C434268D8E556DF27A6001B59B0ED67557B0673A3CB00959FC70ED07E9EB413BB62F05E7EE6D289215D267ED39ABD9D8D93B0AF375C308C3D08C1DA812502F79B36ACB07F0B97A6A0A127277B72C63394BF35054B9603CDEBA40D9809B8A51637D12B4CC826961B95394635843B4BC3E721670AC7E70FD6FDF9B7533E41A1674E2A189DF133441E7D09762E58B6492873CBCB3661C62C0ED26D1C4155C7DB5D24B08B85476CD9BD4139CFAE689DBF0B6DB7E1E0EA8FF81A8E506704DCF068EBF64F50A8C97D3C127CCA57EBEADAB37E2137E74C61927ECFD24897BCD207B475422AD6B68F9A6146FF320C7AA0B2BBB9C8129DB1DC03E094CEFE88E780DFBF4775E6464F77B5D2BEEE49DC074755110FEC2F43F728F866B0B51407B6AEED48DDEA08490CA786CFC1395105A13CF2A8D654AA7583786064C5AB4C3F432D1FB0E4F4F03F9E7580F839F42F1B72EFFA5DC5D0C90B2C21BD8B93AC7D1EF1603357DBF40DCA8AB551063E2F9C0600BF731BB54D21BBDF15A210EB7E5F2B8AB02468348ECAAD15992535B5EAB1E7C486B6E97968EAE3ECAD37CE9748573673381ED892627CE2F2BEC6D709390D6DA01394DF9B42AC9508C76BA57369FFF42DFFE028596651010D507AD065239E9E00E8C797ECB6ABA2B6DFE80B724B5F9826F0642E4BCA077A8A661CE86593CCF8C685FE690224E4A3F41D15115672FA485C362D641498D655A7CB1D696711DA7F77BA414D528B1BC861199BD0562832BB8032DB885786DE6C60170F33DAC20C2618945F4744F6C6FE1B10A2E24E0443BD60B1F40D39735625725FE20C18EA6C0192E9AF47ED1EE9D23DE3B83098FE40D36D2D17986FEC683FB5411CFEB8B1A5A61E990FCF6B3BC8E32E3B1F1A4BD2C3A86C089C38B3B1266A1CCEF53B663E0F1D28A2B63F11E1E2F86BF43E7542D1EBA891DD978C8F573289933A9B182FE4CD8CA072A59C4BA15D0ADAD86F7735307F24EE01D1789666A7123C25F46B38CDB72B43F86CD5A82B97EC8916ABDCB0CC03D1751106807FBEB21D1503C3D23EDAEB255F30F252A8AE83B5C02BD34DB15A34FDBAAC51D0E60B2A415E1BF0E07CD2453C9021BECFD13C73734F7F6BFBB4145B27F53847873A948977401EB8680ABAC4FDB1A5E8D1A94E6D1A8A50E4BF2CFDCF198D804B43B053276758C51E3B0A20FFFAE94B30705A66E5F586396", + "0178BDCD5B5412B1C06884AD4CA3EB43607566114B599A22323C508578F1CCCA" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "06725AC358433FC95A1269AA9247169504CFF462C01771B40583CFFC91162AF4062FF70B95E2C66EE373191051215B9A29222119385EDE2C514E018A52D847E0E616752A5717F9AF8FD6C5A4001FF21497EE765EC0D040A1D16CE9EC559DB5386C5C6B77B62A341B532FD13A7AD960D80B01FC2751B0398BE7147D688B7732107871E8C71EA1B8E0ACC8B93623B9E3848BF811FD25B1AB902048191BB516CCE4564CB1715C1D1BA7E3A6CA8153951C663B8772CA3058535958758461AF57805604E49114B2751EA13760E95985003AD06C86710B4E7A231D6713CACD75309077C4B92B288C109780F27663B8389594AA84C014D54AA1692C70BEA5C36685B6C66A7D11FB0B94DBABB71C1C80C95BC9277AD0871354123C0A231D255AAFE43B2E10B92FBB99390D00AE3FA68BD938954D78BEC3C08A31A1A47C03BE2C0747F4658FDE4299A58877271A0532C46DF2DBC18C655F23041BA820AA2BF37EEE304A72A587D15A1B26FABCE164B7700C09910902A87516A41054E24AA30623206FBBCDD57612B799B3DAD37D7DBB4A8C43CAD3B0C3842980C255C0C0582D685067BA837B9C2B0997A98B57B9AF212139DC4047A572484FC8106669036DB9951E460A42A581FCBB099F015705203C8E636965EA24BCE902706C3108D7B86A410A8D808544DB34E66A6417017CA41607CC938F4DF27E621C8716F834753B959FAC7D83C76CD80C167AACA2C00B794C416D4A008DECC84163522DDCC22FE5F519485AC5B2389149A694C86B08ABCB071BF50C9C93BBE7FC565D35919714336B413F08004BCCAA4E390C50559142FE35B65D56738B003E38E59712A193165C10F0B99C80C7BCDAB7102DF68085B546581852D42683D9D070AC72672CEA16CDE5C1239136D44CC1BDC92A91098CAC6C4B66B87546B71CA0B882A102CB50E0A0530C4732228508875DA38688585357ACFA74566C48641948200048B6FB59064B620A0754BC2901B4E89BD45C47E24BC9CDC7B81375324EA28429A3C2F273611A2BC2A60B773BC21AD2353F7DF804FFF062FC426E604A894532A051B13D97120DCBAA9F97588F2F96075614BFB6C78D43610A28044CB49969CE2A923D2B6845748EEB8B7E087CCC9AEB16A4F723A4C5924787AC7212C50B488CA99B99D5F90C2603073737A6A68B111D548C66EC62F79134D17C3D3F8BACB1AA22FB3C9515E423A350CC32ACA6C29CC621486CA1992D32735962C9819BF204594AC5AC92476C418E3121A187771020219551FA1BF8A9BF5373286999A7F701835C19CB4119A8B6AA7CC2323967E90721653AA9D8620378C1BC1AA205B13BD298AF5C406ECFA8061A9493FDEB69A3714196DB126277AA9BE11077E96CE196AB2C51202CC66C20F5C354A1C95B46726A6B2FE31702633200499C9AB779090B8A6E8D9B6B1A9452E94A698FB396D87978083C867D0B79B9016ACA4906EC109C1A291AAFCA8FA77C24E3A254083AA4CEA3A370A9B01D3A10D43B487E8496075840E9901E8A0845E9B550AAD7C2F7A35D56D19FB923B130574EA25B256370341D18872D158858148BC0EC3900DD3DFC1770D2D4A790307B2AD4C60B45919BAC9DCC913C66A277ADEC19197A5EB0FCA94076515A1993961322A8D82E86B286F4013F541B15AFE8BA9538B3F6F257990BB2C37901F4A961F53191B0BC4DA684C585338D2EB0B05A373BD2BB97F7B4061295C639DA13E830BAF22266C9326DEFB4BA732A392589593A31B5106C431CF5A985DC927E5567049082B62430541829C37C9A1ED968E42232EF50441B3480C3737CB0B57F2A7A5A48687F73D148FB89C7CDC95424CBB42A186FEFAA51C20C840493360EF05070454346784EEF826C34F15FCAF9B50FB47ED0467666A4BEFF465283454A24245ABF870BCAA89D70D51334A2942F774908DBC61693070D58A6997B6A1F6B2AD1D2931C27C74304321457BA3666153B169207B89786E40C2E050B560A37503141F67420A5B05C88B54F4BD2081920C314761FBB60C85D1443E93089DCA26007D3402FA918D522C85873C80F1A041AA63C0BC65C6F86178C61C5C732225980370BE51C7F065FB4C45E3C73BE30F4A3F31BA63039577E775CC0E2B62E8A1331818BB5943A637697ADB5751E16892DF3272A638051E009CFC0831632CC388D5C54CBA8FEB8607BEE47D52B8810EA13B378160BE4DB04A59B794CA91846", + "4659824AA22A4F3454BAD00ADB48C8CAB062A10470D83A74BD6A09441B5CB1D3AD148765ED18AA202CC5841901B929871E085F3F0B4FBCA649384176E962C9CF4022DA73A66D25ABC24CB5BB196099541F238518432955D2803E29279C7108CD2CB87832386368EC9A8F07CEFDF2B291A49B164055D78840EF6256E1E6A8E4ABB87D7137FA5A2A6082B5773C2C33241B00DBCC6C60561B3C66D3D5CA3FC66044A5AD63033011FA720425A874B805B0E9A8EFC6B0F701790975A7ADD8A3E78C7FFD872274E1CAAD0A087CDB742BD440931C5E43DC9B834A6EAC3C00E96415F0407C7E75CC9A074FE04517BA85AC694771D1457C87755DC6541E05E328F3E328EA87BDEA798506103A4F68C038827E1A357097B9330AF68D39C15FA6532943F6A8BA3ABB33738C31E0A96BE3BB353BC9C955A2E2B89692F4C4C1B520849CB762F8021A408FB6BBB9D1683D7657AFBAFB8D0E185B6BC03431C6C52BC69432FB347BECC48975A015A078CC691DED516BD5900226F2B7CDE6728608808FDC0D86F02011796E4A973A0B57A3CFF25A8EAC1CADBA93CA6397E00AA5C9E979DC90C3B7F729EF9C894A4739FF69BE65EB313DB1C1834C097F75B085C16C3AEC8FF946963312B82D6292CFD658D599410F871EDF522FCF952B6343A7EAB52C59C0B1E7822E6AF63994D3896774614E6091B6132D7F8A4F05619A4213037F6BBD5CD4466593A9BC7729929031B80A8906F031CB4C3498B93294F4B769C661D2B7330511CA43E8A87A817781729E45AC219D41306FE9B63E288D724B82B2A07ADB351108C15FF3FC67A9819403DA49F29659765B6D33D18D3F0A65CD5A4B2CB58736914DD7B74ABB85A852D1BF67A1B03DFC2B5A73710249526B5835EA7CC9F17059B761886D82B891B65844678148678876D8B9D765252E0A5E8CB18A4F9120F01954FE5208905AABC7D1163300B6B2F0BCBAD81C692808FD3793A2047C033066FB55AB924245193C68F01064EF610D7DA2CE64F474988B037FD79EAEE8554EEAA077209EC51849006886264574EAB71BCD93A2A735B44E4632C0D43F39142810D10CF58812436964D5BB4487157DE703A56186C3BDE12A5F074C6D947FEB740403C27D8BE7A2AF097F553947628851E909957E428AB6E43B5DE535F8817B234244C0930E700530BFB2827C4C1DD9570D8DD86A8CC2352F97A0E1AAC353E761CD7226D6F62EBFE95EAF280EA77A237E9063CA9718C5227A9A092587CCA109062679F84F890164BE7B1DF041969648272B21C76F78A02A7617F22CB389F9640FA75E0C957431696081E0AFF3E1B71A100FB68C0E4217A706BA06A1F52C1503AA8D06A28E67BEE5CA9F5DE5B1F4C2ABBB18BCF03694C5A70812F80982B28B7336B093C56E3C042E9551AE34980EF8C7489A541DD6F6BFBB0BA25485468AEA70AC373E3F80BA883A3346614E6BB00A64B7CF0D9BB7C1B8BD18B838757673CAC9663A88BCD3E4AEDD04945DA02AAC359E4129B42665A3C284AC94C75F97D932E442629995666D93B8C43ABA34AC420F8035D529C3FF5B04A3551EA9BB75184057F1D657A4A181655427543B7DC63546C8B0CF1FF9057336B86103239BA991102968EF841632306EFD994ADDF103D80A5FC34881AA54C217460B7A6BAA753820EE8B39C6553E88575152A103B26376C49A815FC17813EC0BC82A86668B965D641C92E02292E4065E2477D2927917A197063B9F27B0B996D90AE75314DBEAC9DBABA71A1713D616BDA831895D8A4BA187C0390A979C1A7ACAB23061B7A02192C2DB372062A42BD9BB10898571F183119D0C4E72227D2284B45390A516A23502374576C906D13509DC20AEBEE88EDE13603BB0404C52549667C0CA9BCA084837850BA4A2F93B183017E0192B76B14842644FC891279349224FC9C60F3C0595A93FD00276724493684A650FC00A9E029C2CB8900DCC363F495AF6D5A5E058CB522823D9113A68433919C5ABEE896DD0110957D7CB64858AA2C76E4CD47861C21EE65AAA38AC7B7BA262EAAB2A4311935AFA35DC31696D948964B596AE12356023835C4643F158127BD321E18B084558A607CAABA52A952EDB817C176BF1A4473E2558E23A5B7DB8781DE064D6E3BF65088BA8B20BDB0B629DCA6658309C4923398A8C82D73A9FDA7C6306725AC358433FC95A1269AA9247169504CFF462C01771B40583CFFC91162AF4062FF70B95E2C66EE373191051215B9A29222119385EDE2C514E018A52D847E0E616752A5717F9AF8FD6C5A4001FF21497EE765EC0D040A1D16CE9EC559DB5386C5C6B77B62A341B532FD13A7AD960D80B01FC2751B0398BE7147D688B7732107871E8C71EA1B8E0ACC8B93623B9E3848BF811FD25B1AB902048191BB516CCE4564CB1715C1D1BA7E3A6CA8153951C663B8772CA3058535958758461AF57805604E49114B2751EA13760E95985003AD06C86710B4E7A231D6713CACD75309077C4B92B288C109780F27663B8389594AA84C014D54AA1692C70BEA5C36685B6C66A7D11FB0B94DBABB71C1C80C95BC9277AD0871354123C0A231D255AAFE43B2E10B92FBB99390D00AE3FA68BD938954D78BEC3C08A31A1A47C03BE2C0747F4658FDE4299A58877271A0532C46DF2DBC18C655F23041BA820AA2BF37EEE304A72A587D15A1B26FABCE164B7700C09910902A87516A41054E24AA30623206FBBCDD57612B799B3DAD37D7DBB4A8C43CAD3B0C3842980C255C0C0582D685067BA837B9C2B0997A98B57B9AF212139DC4047A572484FC8106669036DB9951E460A42A581FCBB099F015705203C8E636965EA24BCE902706C3108D7B86A410A8D808544DB34E66A6417017CA41607CC938F4DF27E621C8716F834753B959FAC7D83C76CD80C167AACA2C00B794C416D4A008DECC84163522DDCC22FE5F519485AC5B2389149A694C86B08ABCB071BF50C9C93BBE7FC565D35919714336B413F08004BCCAA4E390C50559142FE35B65D56738B003E38E59712A193165C10F0B99C80C7BCDAB7102DF68085B546581852D42683D9D070AC72672CEA16CDE5C1239136D44CC1BDC92A91098CAC6C4B66B87546B71CA0B882A102CB50E0A0530C4732228508875DA38688585357ACFA74566C48641948200048B6FB59064B620A0754BC2901B4E89BD45C47E24BC9CDC7B81375324EA28429A3C2F273611A2BC2A60B773BC21AD2353F7DF804FFF062FC426E604A894532A051B13D97120DCBAA9F97588F2F96075614BFB6C78D43610A28044CB49969CE2A923D2B6845748EEB8B7E087CCC9AEB16A4F723A4C5924787AC7212C50B488CA99B99D5F90C2603073737A6A68B111D548C66EC62F79134D17C3D3F8BACB1AA22FB3C9515E423A350CC32ACA6C29CC621486CA1992D32735962C9819BF204594AC5AC92476C418E3121A187771020219551FA1BF8A9BF5373286999A7F701835C19CB4119A8B6AA7CC2323967E90721653AA9D8620378C1BC1AA205B13BD298AF5C406ECFA8061A9493FDEB69A3714196DB126277AA9BE11077E96CE196AB2C51202CC66C20F5C354A1C95B46726A6B2FE31702633200499C9AB779090B8A6E8D9B6B1A9452E94A698FB396D87978083C867D0B79B9016ACA4906EC109C1A291AAFCA8FA77C24E3A254083AA4CEA3A370A9B01D3A10D43B487E8496075840E9901E8A0845E9B550AAD7C2F7A35D56D19FB923B130574EA25B256370341D18872D158858148BC0EC3900DD3DFC1770D2D4A790307B2AD4C60B45919BAC9DCC913C66A277ADEC19197A5EB0FCA94076515A1993961322A8D82E86B286F4013F541B15AFE8BA9538B3F6F257990BB2C37901F4A961F53191B0BC4DA684C585338D2EB0B05A373BD2BB97F7B4061295C639DA13E830BAF22266C9326DEFB4BA732A392589593A31B5106C431CF5A985DC927E5567049082B62430541829C37C9A1ED968E42232EF50441B3480C3737CB0B57F2A7A5A48687F73D148FB89C7CDC95424CBB42A186FEFAA51C20C840493360EF05070454346784EEF826C34F15FCAF9B50FB47ED0467666A4BEFF465283454A24245ABF870BCAA89D70D51334A2942F774908DBC61693070D58A6997B6A1F6B2AD1D2931C27C74304321457BA3666153B169207B89786E40C2E050B560A37503141F67420A5B05C88B54F4BD2081920C314761FBB60C85D1443E93089DCA26007D3402FA918D522C85873C80F1A041AA63C0BC65C6F86178C61C5C732225980370BE51C7F065FB4C45E3C73BE30F4A3F31BA63039577E775CC0E2B62E8A1331818BB5943A637697ADB5751E16892DF3272A638051E009CFC0831632CC388D5C54CBA8FEB8607BEE47D52B8810EA13B378160BE4DB04A59B794CA918460F828896B3ABB156C26BC2E37F4C2DA1608C54971206892640A8B7FE278D8A82B65351EB0FD5E4BA7378EF3C5D2A5DD4084824D6C383D2377D36484624298A81", + "5CCE7410F68738ECED68AC00E2FF78963EE06325D7E030590584A30F9B740A2F7A5CEF919F384D1801827E677C2C155089EDDDFE74471E319B7A96C74A751368354A3C5C62D517CE7C20415E6E2A9121277E039432B99244D95283B9222AAE6F675B1FEA9E9AF71D60C82B8AB74628C2C0A626E8FB7FEEB3A60B97D85EA7BBE77B3FCC85FFDCA8C4501BF7B9AF179716EC483066FA92530B63BC0FA3C296997967FA1B3D98667A350447D59B8FAD4EBDC24F80C25A525022E1CF75F497BFD0889711ACAE5B5FBA78FF0A1CBBD47A352A8709085AE4ED8D06D05A9388FDB106DB6DCD93BF21407771A66B26C1FEA1ED2D15AE345F4D8131E7F2523AD95DA91D6A143AAA08ED15577DEF0F274AE853B41AB63650E7E733D9D7E9B3643FE4CDBE607E5A7DFE75AE57BE8C91932FD5D726691FBEE44D8F83DC94A78CA87369AB35371523462D3254724CE245FA33068606AEC2B7144706A18F34793AD298229E073511EFF4062182DAA6BCEE01CD388629ABA8EEEB105BF0DAA0120BA9FF27FF95EFE6FD4842342DE27AFEBF8972CF100FC3977B2F40E851B7DD14C02E9EE9EF0A7000882718EC2055C25BED85DDDDA8FA7379A904FEB36CA89E749A54F633042FD87DD70BB261058E64F82B5DCF19CA59233EEB364BBEAEA9B71B5E475C33D811D60E7608251F2B4DFD3AF9337FF03B9956BA7F53312E1955E9A1719C3CFAA7CCEDF8AE7CD90FF4F6129967295CAABEC97644108B3C5CFFE65E55ECB93394BA5F56E94FC2720A66023A4CEF20FBE9A3B7CC6684E7ADFAC2644E7E6A735A26D5BFACB56D03BB37474DBE73E11390DA4243162EBC5F93C9CE7CD5AAAB419239C89CA62B7AB233C7688803A32751234D7313DA0A888F41C9FA98C4486AB1D474EC933993BA7C882BF6A5B459B2F8CC606C9F6445FC8DC6CEB24BC376FA9BADF1F2449346E671A584BE000278A631B42DC80A6F723F64D273BC264527247F9B6220371C05FD3F729527FFD87A7C1528A0CC6BB2E5F5E75B009B9D8F92C29CAE035CFE1C16D7B66D32CE3BFC8447BB247F62E46B96A187CCE43256C5E1A0DE4B339854D281BD0AE36D248AC25DE1419BD2E3831BD9E1F5856CED3AB7B1BC9A48B33E24DB0814AB30DB03A25BA58B4A6CC39EA45556D02C6CDF9990938C002ED43EE740E8CE2F9C9C198D287E1225A495B5A054534705D6C47E00CC997539B63433A248D6331F70888CA4FBB01084DF34A8ED1934600FF0052C2C3E25103C6B588277E0073A6DDF31772DE96C54417A75D7E1DC92821B464C5418342D96E10551C81103978D7AE960933B054B7EDEEAD4601B670B86E080B6EE898E5D225897D683AB9006F1BD97A5B99CF95A9E8EE4C7CA4078D6D31F8A3C3EE51DCAE9E87CFEFB2FBAACC39DA57579699981F637B7755393093AE7C3292B748BC26DE7B6AA6E1E06A8BA4BE5AE0D7D8EE929F533EE1306A0C59EEC0EC5A54407118E2DB2DCC2927A176B425AFC0F6AF16DC9503DFB8F66D55990FB9116E7E5EDDE67BA3F9A42746A3103BCD0E3E688639AEA6E63965524997131F9F3BEB988B1AF9D79C5948FFF35EDBB579229659F009C8E29E9ACF753907F4126FD87C8FB1395CC1F0B796E7FE67959C034030333FE6A588FBBFA4536BCA76C69C1654F1BC08914A67BFBC229D8DC1E8FCFAD86F30312F544458818335E5D912E127524905C1590E198F3474529B28F2DEF383CA2A156D808A0766CF4BC99F1730BC846DEFB1C80523639C6CCC65C252491BC37242C0DE5F1F3B0CDAFAC8438195DD2F4AD66CF7EEB47C5D37043B40B5D102BE8CEF12710EE0A3FCD3A01E30A0FBC7837E97CAE4D6AB4A57F9F126C4DE3F8FD05DF3387F3AFBC4D33AA708AE4EF76266C76B6C9C3FD7FF9205146E56CFE1BA1275D57035CCB742B4B16E52F8983AC52A7EC8736ADE8CC998B82AEA49718A9399D2F7B388D16300956ED7A42854B712BE4857FD0FB85609930106BFFD6B91989AF5CBC8A3578DBCDB43A109E0D149F54E03F5B1FE3660ADDE9B58EC6133EC3724371D1B3D356FE0B7ED1FE1E7FDAB3D1DBA4CED7527D07296E59656A678091FE69E2F569AC15DB85B47A0D8CA9F81295C96F894128C52EB1F2BA3124D4D174D58D04680EE911EAA4029CC513F80523DCA639F6AB2649B5E93ABAB36DC1B8FABE40762F842606813836C3A5C011B37FB8B77EDBC1FFB118B3AB641C0616", + "AC32764AABF8926EC41754181B2CFF101B907C0D60FB92638214AB9164E24F2F" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "1023C20E2CC659E9B02355287DE1643CE2155E736FDB64213825B8C5A849E261C309B69558932170C5675A53CD4F62898593A8792535A0A06187EB688C1AC90B957719BB7B3933002A95324686741AF6998074AB9CA116ABD10D3CD482BCDA03710233FEE6296C718F3EB846E3B32FCEE59E2697ACA6C4905E86260038A0635504ABEAC8B656420DD22954A62AD05CA47BF685010CAF64A020B6782C77BC8DE7FC5BE33C119452AA518C4AE5183E6AE3AE195C07D3E4372E7B77B31A737EA6017EBAA1E9E1218970B1C26926A3F758D2301E2449B917D1192987613651B404D98E8A652ADA735E92D34192B6261A52C3A56672642757669A5716A277F7DCACC7D503007D805E950DF9765643349125310742042D4AEC4CB375C8F0C043C82A72CDC73FAE372DDB301F0C684A02C94D9C415E7830255C60CAC599392FC2A63294A2FB22B72009495E3717862AA7D37C5E8A0C0A89E990F16759C54AC9D7D6911EC0BBEF342C13CB988A12452355A8EB57734D1C5B42E485E5E70C98B792C0F0A4FB0B8DF0743CA6A94A936A80A40231FEB69F688B82692356135C45E2D6B3B346B05721BB570A9329428F86074B50930AA737BEDF2C0F3D4320BBCC4CFE2AA06E8820D38B09DC477C78385AF19595F34A807E3BC558228A06E629F479603CA8B8BE49CE24A48D68DCB2D183C83116BEAE4ACCA444A60A844749C6A76BBA67B8B60E04AA4852C56A462550A74B7A4A00CB5662B735BAB6F27157D8C1801A3963F8A1CCA0269D61D273E2B6B1527A1A0B683845E68D1E50C573C3841631300FA39336F3C9AF58A2ABBAAC45274DB4CB139FA7952D7323B658496C7584B291B58A17437EA217FD1A3720CAB173515548D045F7212A93A5033F525C6AB13FEC801ABC4B22177CC409EA1A37B10B48F29A9D631962552F35D291431C6E947B664B164317F010206BBB5023542B6A9CA1E1B877F0269A77C93B7C6E7C65755847328CE2809B74A0FFC76990055D02552919144758673D6F5090DD69ADF3A283B2E0CFDDE3460C8796E7EC4F4ACCB3A9E8872EC744D705C47D3511DDA09A7E8B3867C4385FCCCBD04855DE3619D1E20E3875861A88A40F672D12179BADF5C81FDC7A18E7A5F158866A932401D057CFA363087506C6E64DE22B1DFBE3C4E0634A3CD868389A262F1261FEF19E7B818F53D703AE9B537973849D26B97A8AB1E3B2252C0143E5B3388C577B718561F9A8C19D090D17E943A8D1503B26CB67E8A7FF6C7046F5AAA1CC33EAF011C4550ACEB88C5DD2CEBE12CC0D535E14330D2445A951FB528B108CCB7922562734C59CCB4D3552C354192E8A033DB7AA0FB89AE216689054AE0DA4A8C57A0311064E7C66C15DF19836F80B4FA23825235B6043C6B8B7937D295203B9002F697BBE8859481BCFF00C5E169030D9853EB4B2B924E657A1B424F34C36D0E29A62797A4A43282D69C30C512E6B53C4E39C55C5FB3C19106F14B06E96271CB4A6CE070964368432C721BBFBEC8375434539696322670709A832DA9CA666488C06746987B78D9F348C4B4576FC90986453BA25C7931D61BAE6A31ED5D2845E86366B0C1051233CB259720F615C22E0B62DE3C06264418E1A7DCEB10803224B0D963B3062B86453457BA804BE059499AB849DEC619C101BDEFB5CACACA5B85AB045CB21CA3528090C945D432A581CB6644B7F36D88E1E0290DFD83474B6614DB5377829A21640588FAA7F0E703D0B5651178A215753141913A62E59A61AC8522CB38A705824F2918BE534529098BBBA0760DD7689AB981AC342AB0278B109838FD798C12F71C6E5B419C261CB1AC99B173AA53C5613ACC6BC41A3CBE46CCF4EF3B7F4F49940648AD6AC21F16910FD91084B2B6590B21267002492CAB7E129C64430BD4CA911A5633364E30473B3BD86945134A93A8362C206D19AB62CC96EEB4012A8C218900576A5AC77B288124A9EFD8AB362844F7D873E21B84629B01797676D25533D0C21B4400242CF06CA4A9339E8C373E28CB2CE75B12D54CF70789F5C561A5231052149607E2C17E5D0A019B95B8AA161F39A6C93E7CAA803AA437A5F34E9962D520F49B72EF34C9D7C8015A154410C29381F417ADB2698F23734CB29570853B7A962225735A85D66C0171378E1F0A52E75251B512ED061082E959E04623B0F06A5705032C33129C953A6EC2A75CC21E114F6985BFF79837B", + "E3E45344B293B119586B15BBDCD8C1DE07392B64A444B7C6ADF10FF2089257471550166042016834CB592B8689B3F55E638798CA89CAE92AAB3989A24476142CD27CA4A747D134B7F8308A928890C52767D839535ED880B90C8C004C35FB5B261EB3A6B689786E044E3C470CD6A318D8AA9BC686814B655F430AAB78276BC1893ECFF095C95BA22E9B720418CDCB65A89B6C7170971C3A78CAC6B895D0BBBABC6925F0089656D6539DA9763A107C666AC7C4F01BFEE69B6B76CEF8009F8283852EDA1DFC6CBA2B053785D79E70680DAB36096B4A851EF48949297A419125C91290A105C28D8B4C33829B7075CD4FFA323E537268372E43345930D657EDBCA5760A7E67E442D284A20B1AC7003838241C26286C41EF628DEC929746A3496AF199612C42BDF17B74BCBEEF631E2E973E8A2CA3460C20220BBD7B726ACA0C89B8ABA792621FCE1C45A5C59C0D04988DE71D027209AA4C96245974E4182042E353897817C5C6309343C2E2208F6A2BC88583049E1A9596456FB81B7F67B83C8564CA78A3B0E0FA3F46517B8C63ACD3DB2F326CB8224C8740F2347CF828E1079B8041461BC209F90A7C6256CB00FA3803375EC56CA53CE81DEFD4322FC39A5740C894C31408B88DEEE21F32F42ECFC70E8C9CBB7473428FDA0AEE13A7B549861768CD1777AD08D22992FAA0CB5B9C1A16B60032028EC5055F296FD2A83D7A5583D0D5C2A8FB5BC6560F04673457214F49D715AE466F8D3C6094C676A8B38DF4F663637A472799AFFC236D3499726B6737DADAAD964351A1295193056626E182267A0FDDB85B2DA667CD4A159E592C6A83404273AFA25C398CE3BA70EC0A36249D1385052CE41625DACE34AA42B9538544B24242AA28F8D92FA0116E52F859BA4343FAB36CCCAA6FDEA1CC2928CE3C09CD121008E4B4A965C84C6073544F06D014642BB8D106D36726241197D7ABCC1D0B165FD566ED1C73AC57B10B79CCA6FB3A04691EF04465980B58BDF51E99F4BB836061A38715640C658AE55D9D08B071A566320A8E5D120BC433A873EC21DFF814D6A65D81B19BED6BBD5D52896FA4B4C532A6CE74793384A7344BCBB87720B385C87AE12E771C1152E495BFD9312872384472BF0EC39AE1E82BDA834802524630EC03810493D55C832217CF444B29FC9A5618646635EC767AF696F0F43A388CCE21B22BF13C9431406EB0C72CF7574188872A4CF553102B5353003D4CD256FFC8ABD3C59B743ABCAB18C0B31C41A277658F3478947AAB9027163F9B211C69C13E703E9F9A1CC6229501934B90B8745C8777CDD355E808CEDE632A1B009BE178454CB985597324149670FF2836A4085357776E418061488AB066868B6144CE41FCAC8F8B8C6C975078C19A9C0517047C0EB35772AE06A72A42BDF6435809823938A2C62ED00CFC78BA27F35C74F0A353D255508456D64008F62137A31B1F869C46BE6768FB47C37D542F77E28ECFC69265320679142FEDF0C870C1A8CCA981FCD3B61FA7289E9C16D8A416A86C951662AEDD096BC3475AD0C1AD82213082503D29D8AD8B71397955A3E2294B5205BB7D438F614A574C5086636049537C6CE0A24A242B54C723AD72F167C45923161193196BB0C55111F42A758A83253A396537946DB792C0D0C3647D418041A84F029107BA5171062349E0B45F9F34359E6C6E37750329B7B5069B375A147ADDACB1734C8CA0E0A6F7CB1675073209C9BCDDC8B4C8576E82E5A55B0115C18860A1939E76D8174D7960702AA381925ED9317BE85879CBA90832DA65E1D90AFEEAC77BAA46391225C910960D7262D842A4DC7A860B8C7F79E494D393C22A323A7B64604CF05C7D8907AF3B2159B70B20E83DC1D654A08641CE7566A0BA5BD9767A8583A0564808950526A9B4401667188A89604DD618EDF521DCF89063771EC3992C784C293232280CF8B68B5248066A476CA2482942BE48DC44BAF79A6DA37FE0E32744EB92B2E74B534B26D84A0E2B5073C09A0AA8810EC1204D9A02A6E4F35EB8809B67B6427D772143B91E1AEC72DB582CAC5715D0481698598E2740491451BE81EABD97F4CF838B4DC1268ACA4B8AB4CC67C8F09B8E0A0847922AD0280EF69226AEE95459010C512B6745E1C0F77A8BF315108530595503BC7A080D32A1596D7A51CE524C1023C20E2CC659E9B02355287DE1643CE2155E736FDB64213825B8C5A849E261C309B69558932170C5675A53CD4F62898593A8792535A0A06187EB688C1AC90B957719BB7B3933002A95324686741AF6998074AB9CA116ABD10D3CD482BCDA03710233FEE6296C718F3EB846E3B32FCEE59E2697ACA6C4905E86260038A0635504ABEAC8B656420DD22954A62AD05CA47BF685010CAF64A020B6782C77BC8DE7FC5BE33C119452AA518C4AE5183E6AE3AE195C07D3E4372E7B77B31A737EA6017EBAA1E9E1218970B1C26926A3F758D2301E2449B917D1192987613651B404D98E8A652ADA735E92D34192B6261A52C3A56672642757669A5716A277F7DCACC7D503007D805E950DF9765643349125310742042D4AEC4CB375C8F0C043C82A72CDC73FAE372DDB301F0C684A02C94D9C415E7830255C60CAC599392FC2A63294A2FB22B72009495E3717862AA7D37C5E8A0C0A89E990F16759C54AC9D7D6911EC0BBEF342C13CB988A12452355A8EB57734D1C5B42E485E5E70C98B792C0F0A4FB0B8DF0743CA6A94A936A80A40231FEB69F688B82692356135C45E2D6B3B346B05721BB570A9329428F86074B50930AA737BEDF2C0F3D4320BBCC4CFE2AA06E8820D38B09DC477C78385AF19595F34A807E3BC558228A06E629F479603CA8B8BE49CE24A48D68DCB2D183C83116BEAE4ACCA444A60A844749C6A76BBA67B8B60E04AA4852C56A462550A74B7A4A00CB5662B735BAB6F27157D8C1801A3963F8A1CCA0269D61D273E2B6B1527A1A0B683845E68D1E50C573C3841631300FA39336F3C9AF58A2ABBAAC45274DB4CB139FA7952D7323B658496C7584B291B58A17437EA217FD1A3720CAB173515548D045F7212A93A5033F525C6AB13FEC801ABC4B22177CC409EA1A37B10B48F29A9D631962552F35D291431C6E947B664B164317F010206BBB5023542B6A9CA1E1B877F0269A77C93B7C6E7C65755847328CE2809B74A0FFC76990055D02552919144758673D6F5090DD69ADF3A283B2E0CFDDE3460C8796E7EC4F4ACCB3A9E8872EC744D705C47D3511DDA09A7E8B3867C4385FCCCBD04855DE3619D1E20E3875861A88A40F672D12179BADF5C81FDC7A18E7A5F158866A932401D057CFA363087506C6E64DE22B1DFBE3C4E0634A3CD868389A262F1261FEF19E7B818F53D703AE9B537973849D26B97A8AB1E3B2252C0143E5B3388C577B718561F9A8C19D090D17E943A8D1503B26CB67E8A7FF6C7046F5AAA1CC33EAF011C4550ACEB88C5DD2CEBE12CC0D535E14330D2445A951FB528B108CCB7922562734C59CCB4D3552C354192E8A033DB7AA0FB89AE216689054AE0DA4A8C57A0311064E7C66C15DF19836F80B4FA23825235B6043C6B8B7937D295203B9002F697BBE8859481BCFF00C5E169030D9853EB4B2B924E657A1B424F34C36D0E29A62797A4A43282D69C30C512E6B53C4E39C55C5FB3C19106F14B06E96271CB4A6CE070964368432C721BBFBEC8375434539696322670709A832DA9CA666488C06746987B78D9F348C4B4576FC90986453BA25C7931D61BAE6A31ED5D2845E86366B0C1051233CB259720F615C22E0B62DE3C06264418E1A7DCEB10803224B0D963B3062B86453457BA804BE059499AB849DEC619C101BDEFB5CACACA5B85AB045CB21CA3528090C945D432A581CB6644B7F36D88E1E0290DFD83474B6614DB5377829A21640588FAA7F0E703D0B5651178A215753141913A62E59A61AC8522CB38A705824F2918BE534529098BBBA0760DD7689AB981AC342AB0278B109838FD798C12F71C6E5B419C261CB1AC99B173AA53C5613ACC6BC41A3CBE46CCF4EF3B7F4F49940648AD6AC21F16910FD91084B2B6590B21267002492CAB7E129C64430BD4CA911A5633364E30473B3BD86945134A93A8362C206D19AB62CC96EEB4012A8C218900576A5AC77B288124A9EFD8AB362844F7D873E21B84629B01797676D25533D0C21B4400242CF06CA4A9339E8C373E28CB2CE75B12D54CF70789F5C561A5231052149607E2C17E5D0A019B95B8AA161F39A6C93E7CAA803AA437A5F34E9962D520F49B72EF34C9D7C8015A154410C29381F417ADB2698F23734CB29570853B7A962225735A85D66C0171378E1F0A52E75251B512ED061082E959E04623B0F06A5705032C33129C953A6EC2A75CC21E114F6985BFF79837BB476B6EBC850461C28D4AE315666DDCDF4FE185EB612397E63569AFA884E6819429BB325104E4D5A8A83A27713B50E8BDC063091B606A298AD8F4DEE24EF2483", + "B352D5A6E2EADC640865E102615DB648C648EA3B1646DDCEA1611FE6F08C7EE36E6A84E3B389BBC59CD67559E3D304AF8DC139CFE8C262134BEF89A8B2DA20F1FAC6F1059D7F49C7D53AAFEB1EC9D507A1CD171D129FCC74E757995B38023245AE175AD9E0DCE6407567AE0734676567C62E019E94A033BF75593BF8A58B907750C561218C15FE345FE27D0439331988BD61C2755D5147D8ADBA19E11B25B3598F512D7525694150444B714D900F85965C870DA505E087ABB2FB6FBB1439A0E74664F8087D341C7ADAA5EA54AFF98D725B235640D89119A0CDE2D2DB1E08C9DACD6365DE79B754D88EE9F75BC4E3357507AA652C84D5EEE042BCE3B250AB16C1E9995D2FC65F097FDF3F019378AE0DCED07EAA0DEFFDBEF2CF7F66C3522ECB7BF4CCDA07C354931A6DCF7F759A41C5DDC17A5927C8DD452325DB023B632D1D5478623E641C9845725E4031D777BDB3E886EFD091D2A654959EA841A394B2620166B0E39D5D53BF98F37F6EC45FDC10236B8704771E518FD0C9581D81C0A7801DF129BF7D8EAD32F9BF8290F90D3CFE1CBC0CD9CD0AEED6F37DF04ADB354DD18CCBBEF4100FDDE5102BFD9965B3A373E9CE47CD4208A1C6CDE562D20DBFABC45B553DC0411E6EBE45219B16DD0BFDE0F5BA8239923FAB5CC5F796BD563B75BC10D45217C1BFD05BDE23CEDE44304F3B4644CE3BD6719C258387D2F684758C6E2D89BDFFC498EA518CE47A7E188E87F64CBBED10D27732E651557855827BF8F5014E5AF3E4FF06510DEC0F7F48BEC66C9731AD5CA8D11D5C1B6B3E6C4D1024B41EA4899919927F3FBD8A3F8E89CE54BA83C8DA840611CB16A439E004D486E08B8FEEC8B0BA65EAED6A1A08FBFC4C2D63BB6A7EA0EED678197736877599AA96E8F27BFDBB9A217E97B694DB2B604F4F2CBDCE7DBDF349960B8E9A036317F7339DED78ECE6CBEA9148636AEA5A2BA7F2B84CDE87BCB656A0E4B8B5351407F9094686909B2E7DF85E425352B7F95F7ABEE4243863F9C134E1836AA281D70755F66E6A4A3B6E8A2F7765D436129F719599A0C01E9C9798CC778FC771ACD5067E9E9E1EFBA1F04C367EFCA76E9C32E1145E49A6AD2D9E2B025FDC0EC71F510B2D61C83CB7D215CD306D9EBF2D6083F19EF8ABB7B3E46A728C5A25A5333E48EB2192CCB026BAF143D62478E23953C131DB0FCEDFFF17637D685ADFCF3B994ACC831607516DCA2695283DAD5E10D3B20F9F7366F0076F227EC2448D840F32CCA52D364A1912D569BE14E74A6DC4B4543FB3411BC0C1A3BABDA8FC6F0C4D20BB36C8B5A7FC8F4104A10779AC8375CB174E1366DB213917DC4340570192C57431067C0740A86BB342DFFA8E36BEC9BF554B36839B7D1F572C12928A197403B6B7814D8BD83EC23FF35E4475C8198D7C8EB6B9AFDD4A9DA583F5F92C5C4F048594ECDADD26057BA4C989E08C8E800A9E8A7DBFF4494A33FBA336BD60789D6CAA3277823462421CAF63C2937E16CDDCC5CC0668E49F75BFB96E0293482ABE5FD188DA961EB1116B3B2D2155725A8E52D25EFE3C2D6965A2EB62A20BC640B4E172ACF6DCB2E85EA99A3E0AD711F0FB45084F3DC3C433179C4C6BE311A1909DC097C911C666F78678FFF71D342D1661F07A14AFA2DD8A6D66AEE7A4C5C4CA2B8B77DE19B53E31DC61415937B676A13BD1EADF11A7F7302022EB41E147DE8FD1C2D71DB80778B1DB2D378B211EA04F35087FCE5A98F3D2F40DB13132C4E1B3B50241A70A44E5829DBB562E350FD01283CEB743FA0C5B72A8A5835B9FDE77AA23FF6F016EABF57A256C572AD3727455A10311FD7D1DA6483C70810AA47860436CC4216A90460B0BFA8B98D49FDB3433D0EEE65356D00A05F027C4A0C9409AF72D0E1C3E89E12A383E2AD5956C5A7DB0164613467EE7404BE8025D99CDCB59D9D701B119B16F3E462978850E8DBA8AB08B88E2BDA07DA68ABD89711A086B825298C8AAC9166D6936D3E4F1E09452853EFE6700D126D17BCF6F0D82434CD9F153FAD3573E20D35BCDBAF35D664309A2B9FA21996CAA29C9B11FAA3A22467DC1E5C9A986E225D199732B5B248A38587B2D0E441989170509E693C1966DA3DEAEE35C927DB6EFBBD4486C6EC570437E3879596A1F7A3EC3F4879782F2F21CDFBA0945F99BACBADD25BF1F25B6C5B6BF853901DAB0793419C543CF52525D759C1B0E899EBBD0E994C39EC7", + "90DEDD24590FEDFF42A27AB44173E0711839EC9D15728D7A0C191CE6CE5CBC68" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "288A856E276D2A364E5DE2ADEA9ACFF34858698C176722CC937CBD23C9500E339CD0B03E7B071790739E68566A5C045119E9C14B41693349B2A2B728E8A3410BC3B608A47C6525A680343E2A3C056B873C8B92A6993506F1E51966677218060631E11953158511721741E74EAF91B9D5279B8FE76B698800E4763D56685B5101C219D718C7B01401C85586577394C619886375781A1AB8977A3AB97A18D8C05186486C18C53490B964C21E6B5C4940251200FB79D89295FF39C903D10A710B26317B370BDAA78C0A396C5A7B312341A57B34DF7CCBEC4CCAC412C800D25317125BA00255DB3B99AE4244DEA8B395E29C55102429F1CC8BE854BB7272A1B26AEDCBC863666193DB3397C87397B744C3D9B43E58262716AEA81422D779C4FC60C0B82576D149C630AAB7429B3ECAD23F42219C7BC348F10052824C63CBB5B5F39B7919084E6C344F23B18DA3E1630C2427A7A526A0D26B57319E1870754C7854A4E2254D64AEBE8566A4FA13F890A01C046D356AC0AFCB6514E0038D47CA01D96432922379E16637798006476183F0BA5D516B6A4AA143C9484318A6D0970150D530B347BD53A0AFA587320BF1162D2B21CB4C9826942002628BD9A5699682AB56B83C4F5AB112815A8089805B305720E55E104C68CC1B7EF8C3916CA3581EE16730C786FBE35D7FF017251549EC88A5DF5A93AAE44F60962B2A2549442A2DCCA7107D96C4C0028FD32ABA32A146FFB2832CF246F66C6B3E500B2FD0886EF52ADF58B86C6C6CEF046A67F107DFB24595BC996631C81DE0684AD5A248C6A869807D460A44DBFA8A060B6A69E13EC37A0DF7A7572F573D1CCB3118A2B1D6D337EF33AFD8EC90AA08CC24B39C1B92018B7002B7A970A07A7DA1B8AB8DE1ADB01745BA159BD111421569792960394CB7AD711C941540716F6A4836AB5AC785A1297426D235CC001B35D040506A46264E92A6E47AABF23261D2A45E11516D73C5331B2A4F60E3007DC12A100C2068FC29EF5B82E4EA7239F316173B259D03B2C64254ABD52F3F498268691D0D61CAEB16CCA57929EBF88DDDC00FB632831194499CEB8231E77BE2DA5132136FFCACB633B6332AF25B224857D5B72D07922C8A5C26E6C76F31888BBF3B5F8C29AD06D57AA9841E9B22249BB1639A5243BCCA5293F2990C4C5149545D0C7C0D5F0299EB361DDB285CC577C8426565177C89BE0AA674EAB947E7257D745CC02BBFA815A34AA3155D9AB773094FC61B15E98595BA685A207A3D92902E943C585E7521B0D39450C1C812E2710048C978FA54D53A267568444F139F2D5A97BD23B12860A835E74D773B20AA668BD9E02E601CBEE8A3AA4DB119492028CAA4ABA50C1FBA3426C99BB6958A8B34A0A7B32C6668D32176B16CFBCA137F2964D56A643F888F955CC25D22103A9396CC133F01A99F29145785AC5F3BF42C7FFCADF5C30F9457012C36BBAA9C56AB917660762A7ABA25C3F1AED2EA2CB75214F1D798672A89EBD74285D8B3F51801F77693CD0C20DF48ADB38B6696A1AB4EE804D7A02A41B5928A1C2A0786B7C867493CF28AF62C927644154B1942C1880C593A4770DC303594461F583C590A9D268B4E0B671F12593227B609B07A3924FB5D439A64921821E2079D9323A977CB9C10590008FCCEB745151D4A0C9AECC62E7C6754B2887C566CBC20C004D546A01BA09F92273592AF9971B28FE5CD84974196E79D684962449A8D54560B8B57BDC386ABA1674CB3B30AB76BB0CAF135D023B20776487DFB20707636A9C21022C104DDC51D0CAA9069948AF89CBB80C90BA027BA60E319F1B7B563695197F4120A26CF81C51C208B4A7A054B03C3AE624096CA2C5CE9B20693EA0067688193EC626F39C474C9B070A3BB8414C7BD6897C9BB1489F3BFAED6461AEB3098F7CEBEDA12EF007F7F915D7374312CA581DE8524422BA2A5310E5A96003EA86826C815FDB6AB4FFA7000783A9D3A379F79B235A204B94A21499AA0C959CE3E25B7DEB9720CE97B604B2B4F31CECC75C3BCF469F61AAE553352479C8E0237A7DEFB42F349013BE6AB6CE7AF7C144E481B245FE2303FB230AE3462D4B3ABEF3AA227F4AE652AB82944444FA1389B720BED57647F93947E5886F70598B002A6E087A736576964331CFB256FF3E13AB181980F26867C0C7F094141522A3F82A9CCA8DACFFEC23BD7973211C4F6244D2D2AD2BEE8EA", + "63066A49C505A3D548D5B348D4FA84E06B3CC95B8B0CB08289B28AF7AC49C7E6382779351B27616DA67D79432BAEE32595FA789E7371E6F339B22B68415B844C0074ED2279D3A22C6A62C91940760047CDCE9C71E4680472A0C12BB951E5EBA58A542F259367DB13263CC1862964B2383960D8568C692463E996665AB98C7B65C8B958BE3F26CAC855A2780B6DCB4AA49950264DCB70F35705FC28CED4DA10FD1716E0C85DCA17BA85F60BB54A514C89458ABCBFB95A131C912A4F89A3BD54CC434663F3888D8C86740B62870B07B6FAEA30C3623C8D4A677976BB7574BE32336BAE6B4210C48BE50411EEAC7D40EBA8F69A246C5489AA998B2F56C0CB8CA4DA16B1A649A41B94CC00BD6420B4CE356137B441559CCBB6B729A1912107183231D802A575D590BF6A7388E2AACD521930191237628F6F1147550B21CD574D3EBB04E5A12D5D8C2C9E223EDF66B9FDE9986503263435A070860B9E4AC5F22A0C5287A7520797D969555A70C5F54CB5AA06BC8AC253729B5BC205CD22713645455E674651CD3327680893DCD53C726B67A3806349C102C68070C5E56D8B601959FBAFDB8943E0A63C42002E3D29AE59271725F92A85A07F2F347D824C1AF68BB6E242B2466065C791903371A702C4AB99D44A79002FB8540149F6616398A3F2883D63DBB964106C828A56A4481DF1A03DB6765AE474A031787141E96ABAA02C2533826BF43861F5798D2B57D5614641993F9190910F731FE3130304E12D6F388088401BF6DB3314B2630BC322678165F1886DCA34CA81616F7FEA844C01514BA9AB42A2C23901930CC365978A9E4545776C779100784D5DA3986EE677329A4F45991A24B57C18CB7AB1187AE620761EA08F14976E320B4BBB8B1A11FCCFFD6A440FA358C395BB1BA7346B3B426821C8144A48D93A9124422154D430B4167EB09B2236B8C46557BFB545B488F80875733B013811F049642DE483303ABC8F43BB0D884CEB8C5F539C9073E488B95A19A4F107559BC056533B409B9C32EC14E35C8F05730A59272399A5626F13C2A20198F54460F8A689BFB101C3C5631F61CA8EF61774BB51EF3AC20E16BC11FC097F055B45C13911ACC37646AA5E4C3B6B98A6BD82447E83B331289797216AF4824725C7C809768C2EE56AAB991F84C1056A069255F0B8F14852F8F5C6A6F47849D7BC667A44F488B66918294A084B7A47C18433198AA24AE0B516D8CAC18BA5AB03E82F607701C53C450812947807CDCA4A088EF37AEAC3B7C3B885515BA0E34593A42C221A74720864B673E792D030BD161C86C8564D3F3C3DCB04C930EC68D42A4BFEB90270FB182A9371E6588C2457B345C1B4E139BE87008A1B572598BB5244222363B86C46095C23F4084B4B24FED715A72452D2B349EB8BA0C68B491CB371F363682BB1A237F2BB424C140A0A59D3700755520DBF6330D8025A59D69EFB698CCF99C318C44AFF16B8DBD1183EE04FD12822F3259089F1CEE382AD118972AD7C6FB6D845E781C75EC87A68905EC2257A1BAA89569A2BFBF55936781B0B3A398658085EE840D03878A447B7D9C64378EA07E5C61AF6D319BAD88503790FBB980F5BF75C114600AD267A6FA1673EB7899035A0D5AB3B34119CA919574A36AA4651192A593D62D8BE1ECA2B0AC67906F3464545C522C73E052673339901A6969933739E567C622C694176979297644E87C9701AC98473C99E17A04A93EC1EC26A6A424AB1400BBF04A7183837824963372030462E47205324CB8CEAA60A248479C633CE596A61A8CB1AA9C8C2E344BE548F4CD97DBD3A516975574BFC62E9E1383667B5FE393481A434068B0E4D800BC8207CDC7B06CBF9297A6758D7F2063ABAC2FE7652C2FA86EF995B83AC16CABCAE7DE250506A5367E9452DD548AC6A55C9F886CC8B1B9536AA14C9CBC98B7CDAF9A6AC725D258B610E10B369411BA550598C3AB928665E0F13CBEDF63F1656C2793B0C1EB9989D98ACD8D45FB29A0BA532A0B1E62292A77AC8D4BC254B1A0A87C7E961C9F7612927E514DB2AC9158A1823339415C50E6D355596B48873FC159B3C3846D211EA481E87FC2196663B5C1184717508F7A5C13F7323EF62AEF58456AC960E4E9C4BDD5670FDE441C5A6A867A216C4977CC6656BFC7C195ECB3D9D77706C0253288A856E276D2A364E5DE2ADEA9ACFF34858698C176722CC937CBD23C9500E339CD0B03E7B071790739E68566A5C045119E9C14B41693349B2A2B728E8A3410BC3B608A47C6525A680343E2A3C056B873C8B92A6993506F1E51966677218060631E11953158511721741E74EAF91B9D5279B8FE76B698800E4763D56685B5101C219D718C7B01401C85586577394C619886375781A1AB8977A3AB97A18D8C05186486C18C53490B964C21E6B5C4940251200FB79D89295FF39C903D10A710B26317B370BDAA78C0A396C5A7B312341A57B34DF7CCBEC4CCAC412C800D25317125BA00255DB3B99AE4244DEA8B395E29C55102429F1CC8BE854BB7272A1B26AEDCBC863666193DB3397C87397B744C3D9B43E58262716AEA81422D779C4FC60C0B82576D149C630AAB7429B3ECAD23F42219C7BC348F10052824C63CBB5B5F39B7919084E6C344F23B18DA3E1630C2427A7A526A0D26B57319E1870754C7854A4E2254D64AEBE8566A4FA13F890A01C046D356AC0AFCB6514E0038D47CA01D96432922379E16637798006476183F0BA5D516B6A4AA143C9484318A6D0970150D530B347BD53A0AFA587320BF1162D2B21CB4C9826942002628BD9A5699682AB56B83C4F5AB112815A8089805B305720E55E104C68CC1B7EF8C3916CA3581EE16730C786FBE35D7FF017251549EC88A5DF5A93AAE44F60962B2A2549442A2DCCA7107D96C4C0028FD32ABA32A146FFB2832CF246F66C6B3E500B2FD0886EF52ADF58B86C6C6CEF046A67F107DFB24595BC996631C81DE0684AD5A248C6A869807D460A44DBFA8A060B6A69E13EC37A0DF7A7572F573D1CCB3118A2B1D6D337EF33AFD8EC90AA08CC24B39C1B92018B7002B7A970A07A7DA1B8AB8DE1ADB01745BA159BD111421569792960394CB7AD711C941540716F6A4836AB5AC785A1297426D235CC001B35D040506A46264E92A6E47AABF23261D2A45E11516D73C5331B2A4F60E3007DC12A100C2068FC29EF5B82E4EA7239F316173B259D03B2C64254ABD52F3F498268691D0D61CAEB16CCA57929EBF88DDDC00FB632831194499CEB8231E77BE2DA5132136FFCACB633B6332AF25B224857D5B72D07922C8A5C26E6C76F31888BBF3B5F8C29AD06D57AA9841E9B22249BB1639A5243BCCA5293F2990C4C5149545D0C7C0D5F0299EB361DDB285CC577C8426565177C89BE0AA674EAB947E7257D745CC02BBFA815A34AA3155D9AB773094FC61B15E98595BA685A207A3D92902E943C585E7521B0D39450C1C812E2710048C978FA54D53A267568444F139F2D5A97BD23B12860A835E74D773B20AA668BD9E02E601CBEE8A3AA4DB119492028CAA4ABA50C1FBA3426C99BB6958A8B34A0A7B32C6668D32176B16CFBCA137F2964D56A643F888F955CC25D22103A9396CC133F01A99F29145785AC5F3BF42C7FFCADF5C30F9457012C36BBAA9C56AB917660762A7ABA25C3F1AED2EA2CB75214F1D798672A89EBD74285D8B3F51801F77693CD0C20DF48ADB38B6696A1AB4EE804D7A02A41B5928A1C2A0786B7C867493CF28AF62C927644154B1942C1880C593A4770DC303594461F583C590A9D268B4E0B671F12593227B609B07A3924FB5D439A64921821E2079D9323A977CB9C10590008FCCEB745151D4A0C9AECC62E7C6754B2887C566CBC20C004D546A01BA09F92273592AF9971B28FE5CD84974196E79D684962449A8D54560B8B57BDC386ABA1674CB3B30AB76BB0CAF135D023B20776487DFB20707636A9C21022C104DDC51D0CAA9069948AF89CBB80C90BA027BA60E319F1B7B563695197F4120A26CF81C51C208B4A7A054B03C3AE624096CA2C5CE9B20693EA0067688193EC626F39C474C9B070A3BB8414C7BD6897C9BB1489F3BFAED6461AEB3098F7CEBEDA12EF007F7F915D7374312CA581DE8524422BA2A5310E5A96003EA86826C815FDB6AB4FFA7000783A9D3A379F79B235A204B94A21499AA0C959CE3E25B7DEB9720CE97B604B2B4F31CECC75C3BCF469F61AAE553352479C8E0237A7DEFB42F349013BE6AB6CE7AF7C144E481B245FE2303FB230AE3462D4B3ABEF3AA227F4AE652AB82944444FA1389B720BED57647F93947E5886F70598B002A6E087A736576964331CFB256FF3E13AB181980F26867C0C7F094141522A3F82A9CCA8DACFFEC23BD7973211C4F6244D2D2AD2BEE8EA1D776B957BB96078F974576554C53D94D059A55CBC2D02DA6A1BF230E9B31489ED499373F94B10D8C54D1F41676E47A6C251D23C69ADABA915F4E182D6AB33E3", + "848A038059ACB8EA4514933732F43E117B6320F3EB4953E27CCB3DF2A789A09264CC77577489110F2EBC6B5CBC57D2BD73891D73A3763A37E88A8D58A37D187016507C619466726974303AA72A5461B720B862F86F84124302844377588D942F74951739E9C4A8BB282520A166CB1188747FAB13F87BEDB230EB7A8820D85C995546D7C7659A5FE19894F3C59D45D4595E31F655E55190F5F31B7FD325E44A62B9388055666AFC6C918C70F5FD7F9EF50A8365EA996286CCD994E3FD8AC963E4871BE0FDE74C9F76AE07D7886E03C8A821129C6AB2AA06B2D8034846DDF12948487E5C209744F62FBF4D71BD492DBB1F8AD108AF5B117181C5BEE77C2C8D23D0BF806B367FDF051D6A569F02D07BB3580C10E582A8243EDC3C8ED4E320DD8083F88ACBEE4B4A5EFF2038568477DF25C2E38D26161A6A7FE94DD8FE6F9B7862FE5FEC4B3AFAA93F4007A7F75A2D2CF06CF700F7768F5B14A35415676B36230752546FD734FF1F512DC1852029A5F56F961BDD0E8444A800AD645A0428650416AC09399A7105B5B4D8CBD77501560048D1AD5D5EEDCF1D3FE0D756D25D82BE7F97F744764FFFE89E900D0BDFAF21A2085D560DF3B8D6FD5E19C9A5D298E1D806627E60804F5D6E61E2C241C59DA317DFC67D18AC3C62F613973526D7DFEFF7F99849BF54449941924FF8CD6CDBFDAF972F8A2B9B439BB25B7BBA1A6381515135A6728B2B2389BAFA02490E3DA005BDBC508787AE2D67D23F226A55A9504C77D0D61FF8492DE5F3B7C9E8E4340DDC8D2A9E99101A1FC85E3CA3A6AD0BAF443C7F55F1A857075367563998B0CD14FC003E970D036277F6EC62278AFC43B1D6B66C539BD8B1D6C1DE18B46CF75D124A67E4BFEF32F3D5FB70BF94CAA1FFE13D0A2023C0EA84631011B50294ACA5364AE3C95EFBD266459CF225F7494272F5487EC90D42683B45A6D4EF2327899843EC9D8C8D2D0CC1550CD0B200AC62976FD322C8830A16028680EC77D97D09AF15EE24F23D977E16E4962F42BB7C2396F6B057742435235D38C3BE0E51FA5454045245F39B7CEDBB864CDBA6A7B23EA65FD406F80A7132467A1937C4C5468C7AA52B556A9649234265A22C1867EB898A230A193E10376984CA92221783395E49A5241A5FFFE049920EAA8EE1692C9645F114992B25F912D8AC695E7AF2D737065BDEC09D0F5B5C2611017658E1E9A7B66995B672E04C8522026C94C8355D15112786213D7D56BC16243D1C642536C00DA2851A7EFD334D7494350BBDE57F2F5F6967ABB6004000747256306FCCBBB06D34289E98F066D67129F6A07C4EB45BAF3CAACBFC423A9217C8932C701CF8402BBCACDB8AAA0C67EF39688CF85B08B62F09587249891585EAFE3A7E723C21C4C23135A8961BAE67ED41615C6A32740F02BA8A419379F5C8554B8E6E4760274A2703995CB24896CC00DD2E2C8531EF56544F7A1B25E2D1BB76AC282BD116BE64562CE433B74077B376CE437E5263793EF65DE101277FAEA6CFE1CB18A5B3CC18FD03CCEBC40A74D9F46EC8B9BE0E45A417E296AB6AC1F867013AD534EFCD8805D34B99248A8B446429DEB4B45AE27822756A55166954D05765AB5D9B962E49A0EFA1EDA4FB006745B9602E1DF2F3AF22A165BCA4134CAF0D2199FD3515BEE853ED258B80B934BC94CECFA762347CE6974803BCDB360117484D04F8772D975ACB2AB025D45CD4261AA4A5608E63F1764DE6A38B107BF5DD28C2B578FE0BC9FB36DE9AD31FFE91DC21FB505A1C8511CC2B64C0F3853A3A07AB57CE2053763421153908B94DFDD3CF3E3FEE6EB382CA6B99F977A01A4B1EE53D9BE240EEB76872618C0A90DBB0A8346A63DC04AEEEEA8D6B6AAED016E0DA7D06180AE171A60541ECE6488E39DA4215DCC405A84C4B2A70572013C1A33EBC7016ADA7BECB09DA91014425CBF0DF5AA3B0F2E76CCC4CF8BB239601D4BB6AE7C60568822D963C3635B093A5263C035E446340D81D6BF3CE82672CB9F2643C0C9B12D4AD3D05F9E8567CD821A882AD6B034648AD6975A896F12BB00210D5B6591E484ED3C15DB97C869EAB167C860F03B3EDFD7AECC9FFCE49D78F68B048245B88819A9434BDDA676B0B6614C13DD5C8621F21AD1AB84AEB2F658A24BA0AC9C291BAB982EE2DEF7AFA79AD57901D36115803F04EDA0029E15BB3A16123FD74A0603EE718AB5A51E3B688E023554A1398", + "F255E47BC336EEFDEC3B8871881B26A60BA848E004976F97381F5BEDB5F467DD" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "766DD902E7CEF070AF64F46A73AB46A62DFB60F93592EEE73FC5542B0A057F7AA182C01CB65197D87546ABB8AE3B2412CFC89C762F3D1DB07D2B8BB4B0A714383D8913BF2C2217AD0E18166D86FD645290C705906CF31AFF16A63CF7E6CC0C7CBC75B5ED4358611658ADAED95C84347CA582A8B2E50D8A2C33966BC47BDAD9D473BF455B4B5E9E238B9352FCFF07D21A3E8BBB4BE27825111E8B10CAB55B44C6F7A0F28044A0AB2BD460262D31A31F43140FF54A7B8994979D6784FEDF6AFA278C0B0ACFF94460123E8CF08D3417481782196899FEB79B614C3C5A24328CAD9AE5937C0771BD49BA8E682EDE7E24296BD1069CB15217C962045FC246295F479FF6D2FE30AF64341E1BB786F903FAF2476F1C6D8D0051E66AE35A63C71206D4D4D9E3879EDCB10905AE914267330D781A7A4BA25B51C7E47DAE067BD25FFBF585DC99D8B60DCF106B22AEF1346A76EF7A887B62B54BE14CD7A1E84362BDB615B03AF33ABB6B06D4628D43AF197DC99F749EF0D3BDA839EC5EBB48736A56A62032C4486670026A7C9D3DCFE04982F02D1DB462FAF5A6DAD1AAC0C6B38DB644F607EAF69CA5790EAA1361D5E1FA1A8C8116A874236D25A55E9218FFAFC8AA8F752334ABD574F01CC324DBA192EAEE5B13668E253880445E58542C50CA8B048FA89637BAD44CD5CBF4C12CBF13B9D00E5297B25137D045D8BD33DBADBB3B9AE5C433F962081177CD8CC523FDBAD322D8562259B06E5CD925B8521930B90BE6357C75CDFBD3DC32762C73260FBFD534789EBE97BF30F0E3F1A968D92AC2D12A0AB3D05164F2CBDFCAF7FC7BE60CD758233303524ED3716E4DAC9ABAB3A01C86A4EF8818CA787E5AEBCEFE18D8223BBC1E70CF276729E50B7D1498964A572AF6F5800B513B8ED49C6CAEF578D6230689D061D70301565E296D9D27055296C93A9308C7F94B3941948F509EF817309CC742D7C0E079F731FB6C6AD4535203D8423722152F2A9AD0E00BE0AF94CF5FD58BFD0E3E720CF1BA7A7566DD350FFF8C1DE97570FD6894A0D3B5E23343D902A81FE23AB3A19C5D1AD08800CBEB667E05054DC749B663052E57D9A97194BF2CBB153BE50B9BFB3ECDC88ACD756DC9FBB717A3B544AAA6D0F289D436F7F2F96E4D20A7D2748687E1C55F1D416DC9A0B51C6318925A621CDBE80A5400326168DEB50DD39BF0EF2073C6573B753C55E5B352B5F69942FABE9D34DC59D70BB349FF01430A69C54A7D7F33333B112DB2E559DC5971273BB9BCFC7E7779506BCB1C51003B11AE1FA6F33537F44CAE9CC50F74DCF0B61FC01A89090CFA56460F9224A575D6C073DE405CB69E559901284943CAFFD04F4F252051B70A0A18AFA18526403FE4417BBFEAF27AA98B92066709669EB6901E33817EAF46B83AB8FE89035F34E38E135ADD10D86194C51CFCB3350AD051FE506C92DFAB055E7594AA49C151605F5FC45698AC0B780F2005B19132C6B56E40C341D4C918E73DB18BFC9468C998BBFB1B6F872C2DD0806DC57CCFB9AE5CB7DADA91C29AABAD1C03A0DB4452EF62734994CD3CE74C58445A491623C2F6194AB5B7BA8387CE1C0A0905E24FB2738182DBE0FB24822A022DD51E63DDC4016A08364E5E2E77D2C05DC1636972599AEF1357325612218DA843302196E7DF43D9D81568051548096284C51FC676C9806C2F2FE40033641E1945260F3E9E2E52A5CC307F48F72F6B673E5BAD14023E4076EA2494EFA47278D734AC5751EA4A86C155C39E6491EC614E3C4FD6AD53D74BE932361B3F4F8290D0603FA7076D452A1CFC77B178F69F5609A7B37BB5701B9A46B4D321385EFE772EBDBB8A0CA01293C77AA0C7571B3F594827E4FE7A1CEA31642BA197BB8187CC31D539574803A7603796AE02728370B2A1A35334B1D9DB5F6363EEED00D70311542C88F9D041DEAD6BD1399F46E0C0381F030C68C84E0F4251349E8039BCED39DB028B95A96BCCECEE7097FBFF9B6B9A679DA6C191B82385EA00A8C07E8A395470238D5A1198DDE7F0A9C5A91A1E4D7C35ACFCCDBC5FBB029ED17B0415ED954ACF25A3184A5309B74421E059EF2C9A864051E35FBACE79A7F85023E2442E3647BB6A795DB6D1A667497A3925ED5BBDAB3D801311C5825DB4E10B667572C5DAA81FD1A5A8C013B9D02B78D8CF2CAC9CD0E7B8735A6732754D6D7AF1254EBE066264586D93EBACDFA434B8CF29D400", - "02BFD61BE5523C69628AC9154794B2DBCB45FF5A8671C8D5A95EAF9414865943" + "6A90974F34A78A186903DA0EAE76C0D1A903D83903BA107521096B9BBC2B82268A3D897428968216362017F967866598D8A1559D067FCDA8018A7245ECDB70BF96738EE7873E146D2E9715A6ABBA07413FF9F902A3D966D3C794FAC83D7937034DB0CE645B0CE8040AF9A5A8713503F07154945C0BA8059780557A0A1B8475681FF1B73FEE227091D377782993299C02F5E9A58291A7403C8620A401459BB01643C623590B685BC2FFF28B2806613E2926C8A802B51CB8ED1005ACB255DF5006CE373C83C54E3CE15977BC8C8E7515498A3F1B58594A2248B4F450F6879FEE66C214BA4C65D586E1EC0E44D8445DBC8A60755459D1C29D3A25D753C54D721D248102D9B171823232767C5F4CD73EDC3553F2F1BA940096EF154EBB6700F4218CA9405F918996681C59897C868BD56E5483376A89649393B7B6E3BB53C9701BA02278877A53546E6B38008555A81CA91F47E05B40348E2A16CAE03507F66BACEE8741ED1B38704267CD7C29ECF13F9BB072C81A716E89651D575D6FAB5FDEBBC0C9860FFFCAA19399C690B2184EBB8EF4F2A8FFC149B5985C7B3AA0ECF64B13EA38013B5701B49004052DCEC7BF1044C800F86B5CE1317F285673985DEB34588FEC259683C7B08382A877AAFFCCCB06B21CE7839607CC2E7A13B7B5268FD314424740864FC10B5552641FAA410FC633F9030DB1602A8487A664F252F1E1936C647912D8205DA16CFC9A6F89622F3BA4BBEF22343F408C6FB25F90037944E057925C05E7CCBCD02041E1CB9C029B9B125582E4F7B62D3243A5ACB50C50364B27341B9C2E101742CE8927BE7B8933F6027B2145DAAA311FC3C6DE80441DD47092336BD834BD77A2A5974156227ACB24252C0FB35616015D2CC6CC33E9328A49868AB630F1CC14D8530BF0A68DA1D244AD960FDE1A63BB880F5BF67A4D8889D7102851E85D80130B344181A69C23FB34620A9ACA78C124718982940AB57C570CCD7368E3B8BFE47A6ED0F838929BC68E558296FC1E0ED46B9C401F7068B1ECD28626F37779B3C950B914D7447D041C79AA1C72550B08FDB13829D05692406D57DA181E772C2C79329BE81DB20B8807CA460DBC1B68A49E4181CBCBFC1924DA167F9202A777B71E7B794B0B8FF54375FCB4231B648B3AC229CA9C1215168553A6CD1EB9AFCD299C0A96266AE09C06DA5641FB72B15B9F26D79FACE24C26E67A33B28B1A80538AC9BA943A7EE239AB6E3349D65674E9212ECF7762DBD0A23119AF810897FF331970E0667BF07999A531B596B0D4116B24476BDB9757D4B67BFC99A4D3282BF415A544753934552A1C0519A132C84804803CFC2721A62D848A07DED647B0246947D003B5D014C44BBDB4D3BFC068C099364495937224216B6DFB79DC870686E5A5CBBC366268B8CD24A3CF6101C2D6537C57252155AAE570BBCD958D25D51BE95B545A24AD29D6355C34A81E758DE7E671B932A9ABA80987E63781DB367CC0CED8987C688428416625A97C77DD3251726716D375B0FFD8836D6A606DFC7A92A727CFD0BD5179A55E6206BF83983E756BC150B9BEF52D127226A106C8076B91EBA32B4384224F970FF0393936E89AA04B864ED73572194A628A053D526F5FEB580C4270F1226D1EE907B047791210B3E388B0753970957706F1864FB7EC2A314B812494AD9A3B6F82C567ACAC2DDAD6A05D720D8EE80819CB47819A21B64C0633644CF230BAD92920B451711C286A04BBAE34E1B55E737F487B37D33274B591272F562E271A884854AC3D2C35E2949937E0550D10854B4613FED929972A240DE08A2BBC76FDFCBD13F91C3F074EA6FB814289739FFB464D7CB9CAD280DB16B35C23548D7C0C44C76541B701F99AAC04BB1743B467788A836DB96E3D530CC3929FC424705A8632F1B437DC45B86B3328B15B1CD862455D991E14699537EB94E766B509D1CEBFE411E3D14B92099A803250F5466397B2439BFA159BE250E7D14A72E4CFCCD24AA4998EC775A8E031B9691980F50A0407CA221DCBC3880C3A25A54164D6913D016B63D27B66434BEA65C80F3A753C57318EF98D36A80272A0AA7148C8761170AC97979094AFC5485FFF10493D1B1E09A7149D353B253C1B6ACC04A2D7C9C0D39F693A7573E853B55846167214C6886928CC844397503418AC414924A2FA37BAF19DD33232F9C9F9DD1AFC78318CF6A37230D9E5CC178179CF", + "9DD7A8EFB207A4271BC08473293BA333543980F66EC095284CC9A36C705637CA39A42AC2D51005D58743BF00BBBEA4620AA897663B41713507BE6637A8A353A1D60E14417A9DA8B35D9471D864BC71A26061612C1A6A4DC08BC9460A1741906D19643D185A504AA3247988156ACC0FF8671E07B3C8D0BA7371046A18B7414CF8AD01E936C10610D6868C7C8B6E2BF5110DB106C81B7B3EE6BF43991050C01BE0CB3EDF349BB92887A1AA6F40D23F36DB1663706926783ABD5A8C5ED84C6138289A45BF85F782BDA86B4F81AEE5D6628591AF594738E6B539630A93FAC133CA406E4766A1A6B4C867EA580D06003579C0F875C88362278E452D349C2CDB070C877446BC18B400957CC04AB7B084B3CE28A3FA6299CB644315C1AD0D691F55B65427CA1828E8A340C5838F49090FA8B47D531081824EDF126315B90278266239B559662C9717A8A92C64293E7CCBBB98A2B3E80E5C845524AA34C7D42F1A1446BB818022142AC6113B3E7289D200698FE05CE67887C6532CD6FA5C1A295F3395572178B2E3C515701A15D40AAF77783697916594235C97FC979652242640011758AA40424821AC46F33CA43C1C5DD31614090C9BE96C7584672EFE810368A71D76403E32424F9E3197D44535EB717E2109653D3CA522A088403156F1975CB6447CA656B27461C8F5D8B77118CD7BB0130A56A3E2689687031DD18A2C99B51CCDF5621B2C684583CED0F25859118C84C9BE253603A8C627C8582FDB4BB81BB693CEA821EFD712B33730D68A0232921D202120BE959401155670F119A3990158D2C5A6EC40157287BF5B70D7699B212665248CB42BD2CC6B02BA15759BC5333A53794E51D033BAB16F59F0A284B92171017FFB00256B6C9F8311188F24B2B26671A4F1C2AAA000826926469B9336D315FD29A4C38A8491F79B1F9C3E9F653E41B0CC52A6756F80CBA4C27D82A370459426C4F5432A5696463B407DF93816711BBB54BE092793976C159856BE92183C3AE1C14A5C9C8A39AC74836752ABB09065831E22948E3929EB00BF561CC57A597530370B04E10458F34E2B7400537C73FA902B02BB13AD98908A793208842ECD27BBA4C22FA7204C8187092B1012F3001D495162FB97A4DF0B5C2B0740230B7FEF2C5D679B2541387377A99E9B3A9650E64C44300897E8961F5B65B0559952603E80105A979BA1B2F26F6103647A1123A7F830FED26139497D77D220345A620812785061334CF002E50439B0B93A803198FBD80B238C9F969C3BCE8781B1F2314AB48933628C2E6301B8FB5105299739D31EDABB5FA8CBBF8C57C764E1B04ED35379A593FB869B7AE37C0EF093A44AC1A75CBB2979776E34C00720B095328F6236664005AE6A2846A1BA7E086B19C52C91358443C395BE7603110EF6A564660009246ED4B800E77250B96C665B9CBD4B74B4154A8B98561CA4395F92D405956223294692662B46D69043353A7923D72B93BC3F1923AF70B9C1772B8AD5078686694C56C746C0378D35732161D50A6E9AC012796A4A24203D0038AA9B573193264A02BC8E41922A556770D6A2C76AC5150C1F27CC3360A384397A118ED58746B4221C84414A386711C093998C705096457FB9098786985450C645184E4A4861C4750BE91C16F9E25E42C9BC2C865FA1181477125C42C727000640ED09AA7FBC75808B0C5E3AB6004A7364D51C66B48E10A42F6B625B5FC07F0C108A15C4547DAC3E10C59F613273D437050845470AB02A95FAAADCA3B336AA96334A1C871885B7E3AC73635BDC33BE6564522B9C7D789C459E422A6DA3C333B9A4E29A792C68A6B685088176922E06C42D0C030A30C229B69945E32D7500A1754A605BF3C5F0E50C9188C7A3786926151451187CB2931F8EBB06F3D8985D8C871B02987D47CAD7C84F423CC252D2340BF90C6A58241B57220E78A20CE82D28703C0C0619095057278B128289396E08BC876B3E171A2CD231BF5BEA9042418D9B42C75E2A90416A2259EC43D105119E47695001C70E766AFB798421A931A05B455B3AA79E034014350CA7D47141F43BF90017D61139DB380D33793954A10332F37784D25AA59A3878E0B99E4CC291B657F8368D1C025217A292FA200A9CBAB8CE832EA9BC974EAA4CEE3B875D12C0BC9B9C57B56A425816D9B14C6A90974F34A78A186903DA0EAE76C0D1A903D83903BA107521096B9BBC2B82268A3D897428968216362017F967866598D8A1559D067FCDA8018A7245ECDB70BF96738EE7873E146D2E9715A6ABBA07413FF9F902A3D966D3C794FAC83D7937034DB0CE645B0CE8040AF9A5A8713503F07154945C0BA8059780557A0A1B8475681FF1B73FEE227091D377782993299C02F5E9A58291A7403C8620A401459BB01643C623590B685BC2FFF28B2806613E2926C8A802B51CB8ED1005ACB255DF5006CE373C83C54E3CE15977BC8C8E7515498A3F1B58594A2248B4F450F6879FEE66C214BA4C65D586E1EC0E44D8445DBC8A60755459D1C29D3A25D753C54D721D248102D9B171823232767C5F4CD73EDC3553F2F1BA940096EF154EBB6700F4218CA9405F918996681C59897C868BD56E5483376A89649393B7B6E3BB53C9701BA02278877A53546E6B38008555A81CA91F47E05B40348E2A16CAE03507F66BACEE8741ED1B38704267CD7C29ECF13F9BB072C81A716E89651D575D6FAB5FDEBBC0C9860FFFCAA19399C690B2184EBB8EF4F2A8FFC149B5985C7B3AA0ECF64B13EA38013B5701B49004052DCEC7BF1044C800F86B5CE1317F285673985DEB34588FEC259683C7B08382A877AAFFCCCB06B21CE7839607CC2E7A13B7B5268FD314424740864FC10B5552641FAA410FC633F9030DB1602A8487A664F252F1E1936C647912D8205DA16CFC9A6F89622F3BA4BBEF22343F408C6FB25F90037944E057925C05E7CCBCD02041E1CB9C029B9B125582E4F7B62D3243A5ACB50C50364B27341B9C2E101742CE8927BE7B8933F6027B2145DAAA311FC3C6DE80441DD47092336BD834BD77A2A5974156227ACB24252C0FB35616015D2CC6CC33E9328A49868AB630F1CC14D8530BF0A68DA1D244AD960FDE1A63BB880F5BF67A4D8889D7102851E85D80130B344181A69C23FB34620A9ACA78C124718982940AB57C570CCD7368E3B8BFE47A6ED0F838929BC68E558296FC1E0ED46B9C401F7068B1ECD28626F37779B3C950B914D7447D041C79AA1C72550B08FDB13829D05692406D57DA181E772C2C79329BE81DB20B8807CA460DBC1B68A49E4181CBCBFC1924DA167F9202A777B71E7B794B0B8FF54375FCB4231B648B3AC229CA9C1215168553A6CD1EB9AFCD299C0A96266AE09C06DA5641FB72B15B9F26D79FACE24C26E67A33B28B1A80538AC9BA943A7EE239AB6E3349D65674E9212ECF7762DBD0A23119AF810897FF331970E0667BF07999A531B596B0D4116B24476BDB9757D4B67BFC99A4D3282BF415A544753934552A1C0519A132C84804803CFC2721A62D848A07DED647B0246947D003B5D014C44BBDB4D3BFC068C099364495937224216B6DFB79DC870686E5A5CBBC366268B8CD24A3CF6101C2D6537C57252155AAE570BBCD958D25D51BE95B545A24AD29D6355C34A81E758DE7E671B932A9ABA80987E63781DB367CC0CED8987C688428416625A97C77DD3251726716D375B0FFD8836D6A606DFC7A92A727CFD0BD5179A55E6206BF83983E756BC150B9BEF52D127226A106C8076B91EBA32B4384224F970FF0393936E89AA04B864ED73572194A628A053D526F5FEB580C4270F1226D1EE907B047791210B3E388B0753970957706F1864FB7EC2A314B812494AD9A3B6F82C567ACAC2DDAD6A05D720D8EE80819CB47819A21B64C0633644CF230BAD92920B451711C286A04BBAE34E1B55E737F487B37D33274B591272F562E271A884854AC3D2C35E2949937E0550D10854B4613FED929972A240DE08A2BBC76FDFCBD13F91C3F074EA6FB814289739FFB464D7CB9CAD280DB16B35C23548D7C0C44C76541B701F99AAC04BB1743B467788A836DB96E3D530CC3929FC424705A8632F1B437DC45B86B3328B15B1CD862455D991E14699537EB94E766B509D1CEBFE411E3D14B92099A803250F5466397B2439BFA159BE250E7D14A72E4CFCCD24AA4998EC775A8E031B9691980F50A0407CA221DCBC3880C3A25A54164D6913D016B63D27B66434BEA65C80F3A753C57318EF98D36A80272A0AA7148C8761170AC97979094AFC5485FFF10493D1B1E09A7149D353B253C1B6ACC04A2D7C9C0D39F693A7573E853B55846167214C6886928CC844397503418AC414924A2FA37BAF19DD33232F9C9F9DD1AFC78318CF6A37230D9E5CC178179CFD2D08189948550B0A7516EAEB161713983097A7D58C144E1853C9ED002913413441DA27BDEAEB1EC1ABD9E2646B05A311109B11DD7EF25E93ABBA1345F106C6C", + "D6659CED5978246739F1DF34E2B87199C7ED98DC02DBA276FEE6B14491F3D958DD59F9108A560B2149D0A31D0723EE21D06FE75AD924A778B2B020D5B3D675591B6C4336B81BC2A5F9A5AE5B0112685C35F3B1404ACC223AB5383E213BEC1BF9514724AFEBE69C8484C6BF287EB6FDA8681CD4552AB2E4E0C30139F435F4057BF9A8844226E4854A8D4ADC08441B71C94CDAA4054104895D096F3F0993C6E0C9FDCDFC0B9ACE1A57441910EA73F0821289DE798FDD3B01682A03E5203215E2DEA2B5766A10D6C8B5308AE9DD2A7D8408363C8802400AF21387BB9CDC850B2E7805808D4DBE3F12275B3A980DE2401B62F6CFE0C9659A9D185CE11C5EDFBAB0390B58533E46480F2055F1FDA93B6BFF0A9BF8954C72324D64D9C24FCD2B13199610E6892FE4C436A84B615A99E141895E47480B9135513C2EACC1F45881255C0FC495FA4988A02A2B62696554822D637C9AD14F4032A38E30A751B2974CA618959BD8F6C71FC35CE024D7FACECFF8511145DF9643E84774092D6BD78A3F216DFDE5E46EA1F7DED9AA7D5BBA46033ABB16D41A0FCE60E51C2CEB99448FD5B56C0AB256852AD4C223EEDD23A94312EB3168A958A143B7770A326F00D268CCA97D232A6B6C566501243F80C9BF97E9FB24AF76191D122E60B75986A32D483974724FAF5E9D4D909895E4C01C8848D7D5EED3F506F16AC1E9706C6BB3CAC5F097CAE88383BB6D9CE1FCC91E011907F7292462DA88254450D23D2AEF3EFE4C3A28C59BF9596A22A54BC5CC6BA66BC3299043D90CC0362ED4712CA9623BBC1A22BB9AF195200F60E5BF16898F48BA60681A5F2F2702413A71892AD488C689AA9D98BB013EDF091D900EAF2E6F08645A5DCD72A885F3261CB02087039D65922B650E80EC937C2E071F8E039DC61CF9C9F0EA27355B7302622A82395C4B087EAD072A27EC276C0B19976B0AA2AD76C885B8CF7759AEFFCA82CA0576DE8F86264E3F566237A436516CDA35E4F0CCB12143245138A8A0C3CBB75A330FF5EA7FD83D0BE5FA09B8C95150F4BDD2406D2155E26F082841FACCA531C0572C1F969AEF1BF22DE8C742687913BC52E880B231C097AEB92992008371DB707BCC2C912F08F196D4F36DDE0686809EE8BAB0B3AD64CA61EA8993BDB89339AAF8EA2278820FD584ED3FB2B267DC0625BA6431FE82D54AEB21EE801500CA883BA94E51550B4CE2C7BCB534586388944B5561524E0C2435330C03C735DB5A823CA05A85C38EE2FEE5833A6EA9B0331F0906CE90CC3D18A24C9E1BC0417795F9A0D1BC5F1AE1B92B58D442DEBD054ED900F24D46EDA9A5ED49C8016440343B0530D9A1148FA561EA179A55E2A8534C7F9E65C58A37FA5093626C2934C4D971CA71BCCEE4967624B58721D8422DA54F5EBF23B645B49220F66803C09C3BB726D48B2FA508CE044F8C9695F8E7A947B14863F4C3F4C7AC8964AFCB834205A06E6217E676B0D475666A4FF2579884F7B27906A420BC29D1E80035E6B12A868E90EC144B1A7C36C1EB57547920951BE4D47D7237A479BC96CADD2BBDF9AF5434DAD9527F0D13B3BB9D8C6A29318CBA882B81D621F4AE9A2FFBFF7F16986EF5A2514AB744BF92E9B55BF913AD0EE590E2065D9953BB003B35A5B8EB1B9AD65593B441DA63F206C444CE3C4A9F33B1F90EC115E7604557BDB42A5CD33CF7C54E081BC2D092229B22261F9B2FBA0EEFB354DB0D1DF54CF2AB9D747AA3BE86B2C4C3FB1A998341490C35E39D143966267EB5ACDC7DAD71AC2D72C53FF14D38A88E6014406D961A69A82DEF636D95F0A0771AC249C7D9E275C4D8C50CEB336E684D08453CD52BE6613E03909A4E7B172BB7B8B2F9458FB1526187FC80EAB53819D09F10A9BADB097C69BFA9B23EB099DC6E6167601228A18065D92F6CBDCF56A0DCB195964F33BB94EEFFAF3C986665DDE54F876BFFF0D066A648E6EEE3407BA7464D7425C212DAF9A92A1504310BC71000A64FCA459D56DBA81B6360856600CA1EC765061EC35F20D78E69160F31953B32079D0F7E6A426B19F3D6CFFE9E08672E712D76BE09F0A9F74F942247CF6D2CC24B3464D120325F405AAE7456A8F5D13FE3182FFC93F8EC64B9DB4505091F471927C5B505F79C8DC6CE3F668869CFA8A1BBD76ADB98477877EBF644A69D393782E6B06F2AE427F5EB08F2AE7DDF0202B6F080EB14F2BF97953E450CABC922D9", + "AA820E3C3D1E72BF7A93B10D856780E853FCF098870A62C7DF07B8F0BAD93555" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "E80B4738ACEB3ED9BAC18CFE16151B91FB34814594369002C4A92232409BBAB226E302551C01CAE01ED07759FE5EB79FB3CA262C9B55475179A789E92FAA7812858082281405659D163A593F61F15F07EC945941E0DC2AA3DE1EE12EF9041933BF9BBA268C447E81541BACBBECE207AF25199CD8A6E4C2480ACCED8DF80F8748C6AFB26C55542E73EA0D42E9F01218E78A6F21B19BD4C64B2FFCF510C953AC9E05ECF8114E91878FE6437A296DE8AD37BB4B634382FD76D039C006E3AEFB1E85CF1510D24EFEC428175601E5C78A3583E52134A69A2EE5DDC1B33EA2AF27287EFB843271C73D31F78152D8103136DCB655F483B5F4AF2BCE96FB730855BA929A59A5BBAB7A45732026E6FAD23068A1D8C57AD634E63CC92BF7A3B83B72476B5488172CFE6DEEFC62AC13E33A3C67EF1A360C5E671555B389D884E5B159BB43EEC56D3B1B934F8E6E339C5DF6A53777472557EFFB3A6E0695F09A8161AF7A3374083F1BA16BC17EC5C550CEC84BB00B550864348F82679BA32CB9F174733D0A874F15C39837A5CCD54EEC16D783053369B860F34EA5E339BD48B70F0C7A2E6FBAA8CB3CF4D7F0AAA204CCD5042D8C77E8D73DBBD8DDAE719DA6207C92DB8DCBE258EAD6C67E9AA66AF817B005A83C39BEF8CED728E569293F92310E75D0C75BE298BE201BAADC319FB33CCA65C725CFF71D02D33727B1AE30080C9895D5C5C2AF301FBBDABC3F23047AD6BB4F1C5E41D9935519E091885A3BF4EA3F1794C79AF719698D49AA7786A0554577D90FAB6F86D1ED048E35E1711BB2D597E3D13BE3079C2E8AE931BD15D6E7B2F805A339B1E88257E1EEA7D84FCB5DCA1E4C304139DA752A19C0E01376D94E9223DA8C298A63A60145E2A732001D6596F12156048977FB2A348237C5B82ADE97626A7BAF264768A593B0E908A3836843ED936BB037ED4A41B0F1EACDFE101CD0A7EA18CD3B009AF5ED2DDD450A2FF456373041981C6479A5EEAAF1D4453281C6ACCAC590B7B0A4B8412A2DD2ACCCC321BE10FC369789F21F3A53155F9E493CBA6C9651710F45928217E2345386D6C559CD0CEDDF9C2BE2F500A637F3A3C423D3D832782BC4A871FD8B1E95099B23514505A1527C504683D9E3AE37FCB94C67C5B3C08BDB6A2B17A612258B5B1570AE36D829D62C108B7C5C0E3DFAAEDBC00D49EE43CC4E360C44BC2E5403D0E17B514B3D055C4772EF077AB733DF9052CACD4A2025EF42099D06EECDC3B12086BA38C84B733E793662CB5F4A09AD25C6BB7B0DC51912DB42CBF7CC457B9E85D6EEE03CBA2A1E17DD61BAD8B06694443CBAC0424B83DE4DC153A4FA13011C2D5EE86839AC0BA531E4520F8482E94D92BB14FD54BF218B2731F426F24C6F015633C884F78656E23678AD34D63E67DB6F8F8A1185C3C31632CEFF78F17F6AD923A0BBAA3ADE397D61D35C86D36B3A915F705CAAB1B72D51B5A4771CD47593D73626BCE0B8491951B0E160B7370AD062E7BFAC5C1AC81165C3386B386D181C0C12C05CE332A6687080523A1A493AFA7E106FF9DA419B7A04075FFD4849E6EAFA0DBBEA0ED8140D6CE551268AC6CC161B024601AA012332FE9D02B5AB632B2B2EC5D7665B6580ACE5C819A1A857AF163F5E9CA93370BB5D07C86A7367B5A35029D100A81AD166FDF8B4CF96E9D9B43EDB8AC40846BA5A33C7FD314B0BFA84D89FD5A5397C9B4148499B75F290FECAAA06B88BC48B07994EEF65917CE4F69B72A8E3AE6C8EEE9C6CBA65EDE2493EB77975B67DC8779736F68E6D59BC6618E09B855D9F85E85F5C8B64EFF4B13B0A643540F7685A95F51F5064E34DEA21BDFB7DB6825FAD8614C08CC5CBA89661E1AFA7FBACB992AF7E56EE4758A90ED28261EBBC931920B2765A44043CED4D3758D71A0D6114A25DFAEAE551764A93A536CFBDB27A0BE464BFE978830B6EF0AD9C962582576515A1345436407E9625200D57F5DB90254D40D3EF006A5361D907ED473BDFD2371769F42DBADFA52201D63431BC6AD691D755CEA136B1524D3D19B833DD9295B327CDEDBA4D6B8EE5CFBEBB49166FF85C2A40CAE024051C23433A3C62000BD3AFE9FF51518547000A78D31B08D51803A8AD4FF04DF7AFE15152D3FAD850D7742ADE9ABE1C1216AC0BAE559194026DBD1D7217D8B76212E4C5462B9EF29A6976FF216D98E3F3EAEF7BE8AB432E1B6CCEEC83CD46D621EE4CD532", - "458A7BB577EFB1BD795037BD062CD5C90766A8885ED8E8EFF24FB166EB8BC0E7" + "34214407C69920DBA6D13C5F0C604B5C3A14706485289A59FA13347D2954BF93C6D9A8422BEA42AE03B52C93B34E4B38F2A8802D9C097DE0018A0CB3455332897559772B3DE476518BD9438A8558AD02676C387EBBE696EAEA0CA8F99ECDB3AC426A3F1DF8175D7CBBE8F7019F5C0EFC73C131299A43E3A6BFC02FB481A67DE8AA8BE507CBF60C98712D8F500E86D0B76690922E5B6D191A2A70B09C6DC7AFDB689F20627A96B41C14F687A1580BC245700E719B96F3C1701792E33C62A3AB544D01B2A080844B274BC39B289557658A886AAF029DA770BA6502857F2929B2B60A530CC6FCB247672C85B312B80ACC83DB8A689137BAD832C8CDB55152B54120E16E07A9414D651BC74AC13637B7AEC71E78F6AEF2E45C28CA9FE2BAC911327DAF628312472B2746C9DBDB35A517A3A5F65D0378BAAA4B6CEDA515FD868AE96665F624A83F0AB36825C9ED0323A825AAD64BBCB479972967C1C5ACAA7B82C2DF629974C3643FDB417321A22BD4B87DE264CD63BBF5C3C1DC6B2F202CB2680239C7135CC2D2A50398615790BEC8D556F310C72363AAD22003037706AF2A0944151868AC623348508717AF8FA65B4C01521D769F5181B820C67BA7210D62F9AB48D111FBA402E8E40D984CCD817196BD9148AE5A751751B093B1622E8A5CCDCCBB7879C4D70A01CC84267CF5463667226911B06B548448B54A44959941B6C744F1308F029AD786210877619DDC45A92A5B9989A7B939185FCA1E2715CC29B59E2D2591A8BC51D51A214CBC28DDF249F81846516410E63788C24B1B3BFA4BD7C08D38A3202DC05EA24570DBB64A9053550A495B009B2BDB142B64829CB46CAE77770C5AE40149365B70A9C65A77C354673428D42F15704E2F33255C06887B844EBB6B1AC4C3A013FC7B84A396EC9270F21BBC54201C1785B2B779442454515AA0787FF942DD8A33261B3163E13FFD9242964626C4EA38178695C3D59577C1B69899CCFAB5CAD5BA8BBCBB0F0222C552B695EDC701956874622354979C0F1FD02CEE957487B16A6B73BACF59599C84A0371573576B9557D61D702C0541B5CD3C0008867328ACC94792704439377FF516581E0BA0CC9C64E3C0C9350858FE466405633C3CF515617B5E22572202BCA4854B0EE66876342B2F0F87397305A4B8BC0D62BBB4DC821C79B232654455E1F4AE163155440297B75B01ED11A5AB0A268AF54FBB8C6F0DD190CBB78A85CB055DAC95AA893700C504CE7431CCD7331A251D0BFC0C2DA5BC5DF6407AD41E7610C165255452AC9DF79108AD48A7825ACB0A1B6A9133C02AC173458243528278411392C10A83B82744E826B444005D1A61AAC8F829CEDC4419DCB740F07FC7068FE513A00B1684847501D94411BDD715BB004AAB084BAA5B369FBC4D5289B17E3079E362944A498DB9A5544CC23BAB662C28390102BAAC6EE3C1010C8D18865C1548C18852A22D52325D752EDBB65DA1E61C62F95BB2633A9F1275693CB8F3A8CCC5D7425EC50389725C934B5A1AA3324646247C3255AC452C917B54CAE39EABBBC26A0143457957D7098F1C47B089C76D402A04B4001E4A4078C0F0CAEE6CC2E92960FF39BE90C14C45E25CBE948BB68B35EA406EFC462757D5A7D229BE9B5924087A7FDB042D4DB7962F359A4FBA01C60079157ACCE06B9779F2AF475B1E56C3A144B123EBD2B128A00CA10242748057E4B7976B68B12F4482BAE48665F3B0E9AB06AC8431B074BA790A388AEB12E2495E147B2C68A961B080B81C74B546E62D0D9355AC4C59717662DC74B620A75C7FC24B3A932AAED2BE1A4A74F250118508636BC0327455285876167ACA92C57683BB868AEAD9B789986B9BC4BE3F2C0B63C39C1A62223DE202C01A62B48172C3C461E90065138B8EDBB24A640216F5EC8D3E617F4951A09C25263E60C4BCA69688D7491CF394AEDCC814B746946396416B29A2A2C683BA1DD6E9606114BC3E0C9E0BB5A020A1771A2B7CED7A1CDFE6B4E264BE6126A30A27A4351659A827C84EDC1877023F66660AA4229B613C658D450928D10721D596A3B7A4BBCA221CA206F5250DA82B2CFF0B79BE386456746A98F37544EB67D8B291B0E862EEA231A6D048D7A737201111080979BED52BE8FCCE9BEB993D5B49EAE1B70C45593BD1381E4267BEA05B6ABD9865A8046FC716F9E7C14D6933048E1419D0D16C27E38D1D8908FF60CF2E", + "08265D9C0A335CEB667057C49418C445940F883A6ED314979AF08E0D9AC291F879D5B87220AA3AA752BFCDFA1D7D232179365862B351ADFA26C516C05946BDAA81914E26A2E10C453FCC29265B95BE3415F0524DC44A1855FAA33C0438B041B8D6769D62237EDFB45E4A208974806365E636C7A0AE683C363B27CDA9835A7DD911382A581FA6B227470B946611F30ABF00EA8648A9116BD522ABD6404AA8BA56C5B2E4A9B99AA4799E0B5B3C686724BC645AB4AFD72715CA5BBF3AB7210C24C41A273663489F0FE38CD426463EF54C1C8A84D6CB80B918879185AD169B5A023968CCF28ED46AA50579B1FD18CD08E210420B47E4F1B742D5A305D5C90D96528AB9758928BFE501244D63AA5B30A5FEA90A682064190139B0B23F8EE7B27D5794733C184A498B006C3B29166241FAA32A731317DC1D5B17A2F3B8CE6DD21794C86A11223E4C4316CFFB5C40A87F169C8E43D0C22AA76C08C657DFD7BF26777B47EAA93DA66CD1B669B2AB92ECBB0494709B6AC463B1843B2E4784A4C7C0CBF835CE263C2E6C921F429E8EDB8267F64E389463FA7A982FD994EA190DBD243C363B58F7B6554F862FAA6565F20174F3E27548453B146434C2F3615F0A09DEBB2A29E2C0C05856014A799950CFB1AB6E52960F7E35696ED267C0F9572AA973E020BD052B1CE1075820559F7F15A746AC6CF4F70885873F172673343127006B17CF97A7C72410D814A13B54842B1C5EF8707FDC8383054B7597C36007D442D87C1595298BFE654BEB453923CA1120B60E7F426006E4380240CD3F07663837B117A676602703AF034999600F82E1B0D8DB2AF5C80F69721804F1AB0B5940E7F781E97316AC211093C6229EE0467D77A3DFF77547D81BB758A3EDD6AC3B5081B52AC5FCD160EC22AE28703D3F7C06ACB25288D3CCCB65C440C0C04215488D731D8B705D67106D9AA19491C080B2CCC713FC598B5012134558D6E08AE45425B5210DA9F1068A7863EBE3A72F08BB93A7A7F87511B483AF22CA691149574C752FA86C3F4ACC1FF0688FD939BFFA865AD37470AD657A9A45423670205BE69D886A1AE8C9B311337D3461A28A5C5F5A66060EBC85BF464839316E1BEBA123F7CC4CE11F314A8A62D35678B2C875980CCF9260C6AB55DF0C8E8E2C2BD29768012249BB9A4750D250C8C84622F6657FAA481A7451897405C560CD7AC63C3FF0AA17154155732BBF653D7BBC055F127F043BC41226AE4E14BD5433BED32CBC05B82222245ADDB454BDE2BE67C1465E8765B865C058A5A12CE3B25FBA3CC451B04007898367B56C516F2BD9C28F56A23C3A50FC9826F6084EDCE3294F299A50498A244431515349D6809CBD7264EDC639E9DA492CA487030024D933183C803444C39094B5B882801A87D1AF9E59AC394A711E7A40F2FABC0C3B74E72551F450497F21849F5820A70246676ACEB3AA9848C980129574C86BB8BCF496218113E4372A950327F4A77A52C648171B36D4EACA63CA0B3C196F7FAA0B7AB982BE3126419899EC2618EA04A36C452555674D2AE214D20A11837A8FC80B8BF1A3050CE559CBA35FB6B0C8942761B57A0765536E44219955E33D26F32FF07B6DD9E11251695CEED594D388440A5950A55583B760363B6C17622A5DBE97A41E8177373056E999643173C453B445E3A1438C39AE21A36268B4CD71E3351AEB3AE0451A764274E9A24120635F84E345AAA2403A7885CEAB56E2795D56C29291500A09FB55B5F938095392B3D3125C556E7DEC08E295234B784C9B7A54C87C6A1810097494A2CDDA5848483C7DC120AC787C7B8C1DB2DA39EBD7509C02A7D9CC644129586FB66E4E6C2F8219A6489C02FB4B7A2A04B2427113039A24F35C8B97EA3860051A05F4132F6699D5777CBCE9253AC1B085E306189575E853CEED6423566943CA193414C47D3A55A05EC37ED38C4225EA35B9F17C5DB84D4045CC4C520C84E3338331CDB0E10251E2679ADABC8F41BAA1DA8A1908BEB2544740B92693BAA1B5FC6498280B694414A341284447C4D0606167B44B04AB5E5CCC45DEE39EFBB105D2DA41A5B4AEC247CC863B4BA91AC74BE745F6E9568515CFE266945F715E0CE5B2A595B514F532527581D83BA0E1A76D800BC237550A84CAC77B24A05E5BA148282187067ABA0B7BD98A4B34214407C69920DBA6D13C5F0C604B5C3A14706485289A59FA13347D2954BF93C6D9A8422BEA42AE03B52C93B34E4B38F2A8802D9C097DE0018A0CB3455332897559772B3DE476518BD9438A8558AD02676C387EBBE696EAEA0CA8F99ECDB3AC426A3F1DF8175D7CBBE8F7019F5C0EFC73C131299A43E3A6BFC02FB481A67DE8AA8BE507CBF60C98712D8F500E86D0B76690922E5B6D191A2A70B09C6DC7AFDB689F20627A96B41C14F687A1580BC245700E719B96F3C1701792E33C62A3AB544D01B2A080844B274BC39B289557658A886AAF029DA770BA6502857F2929B2B60A530CC6FCB247672C85B312B80ACC83DB8A689137BAD832C8CDB55152B54120E16E07A9414D651BC74AC13637B7AEC71E78F6AEF2E45C28CA9FE2BAC911327DAF628312472B2746C9DBDB35A517A3A5F65D0378BAAA4B6CEDA515FD868AE96665F624A83F0AB36825C9ED0323A825AAD64BBCB479972967C1C5ACAA7B82C2DF629974C3643FDB417321A22BD4B87DE264CD63BBF5C3C1DC6B2F202CB2680239C7135CC2D2A50398615790BEC8D556F310C72363AAD22003037706AF2A0944151868AC623348508717AF8FA65B4C01521D769F5181B820C67BA7210D62F9AB48D111FBA402E8E40D984CCD817196BD9148AE5A751751B093B1622E8A5CCDCCBB7879C4D70A01CC84267CF5463667226911B06B548448B54A44959941B6C744F1308F029AD786210877619DDC45A92A5B9989A7B939185FCA1E2715CC29B59E2D2591A8BC51D51A214CBC28DDF249F81846516410E63788C24B1B3BFA4BD7C08D38A3202DC05EA24570DBB64A9053550A495B009B2BDB142B64829CB46CAE77770C5AE40149365B70A9C65A77C354673428D42F15704E2F33255C06887B844EBB6B1AC4C3A013FC7B84A396EC9270F21BBC54201C1785B2B779442454515AA0787FF942DD8A33261B3163E13FFD9242964626C4EA38178695C3D59577C1B69899CCFAB5CAD5BA8BBCBB0F0222C552B695EDC701956874622354979C0F1FD02CEE957487B16A6B73BACF59599C84A0371573576B9557D61D702C0541B5CD3C0008867328ACC94792704439377FF516581E0BA0CC9C64E3C0C9350858FE466405633C3CF515617B5E22572202BCA4854B0EE66876342B2F0F87397305A4B8BC0D62BBB4DC821C79B232654455E1F4AE163155440297B75B01ED11A5AB0A268AF54FBB8C6F0DD190CBB78A85CB055DAC95AA893700C504CE7431CCD7331A251D0BFC0C2DA5BC5DF6407AD41E7610C165255452AC9DF79108AD48A7825ACB0A1B6A9133C02AC173458243528278411392C10A83B82744E826B444005D1A61AAC8F829CEDC4419DCB740F07FC7068FE513A00B1684847501D94411BDD715BB004AAB084BAA5B369FBC4D5289B17E3079E362944A498DB9A5544CC23BAB662C28390102BAAC6EE3C1010C8D18865C1548C18852A22D52325D752EDBB65DA1E61C62F95BB2633A9F1275693CB8F3A8CCC5D7425EC50389725C934B5A1AA3324646247C3255AC452C917B54CAE39EABBBC26A0143457957D7098F1C47B089C76D402A04B4001E4A4078C0F0CAEE6CC2E92960FF39BE90C14C45E25CBE948BB68B35EA406EFC462757D5A7D229BE9B5924087A7FDB042D4DB7962F359A4FBA01C60079157ACCE06B9779F2AF475B1E56C3A144B123EBD2B128A00CA10242748057E4B7976B68B12F4482BAE48665F3B0E9AB06AC8431B074BA790A388AEB12E2495E147B2C68A961B080B81C74B546E62D0D9355AC4C59717662DC74B620A75C7FC24B3A932AAED2BE1A4A74F250118508636BC0327455285876167ACA92C57683BB868AEAD9B789986B9BC4BE3F2C0B63C39C1A62223DE202C01A62B48172C3C461E90065138B8EDBB24A640216F5EC8D3E617F4951A09C25263E60C4BCA69688D7491CF394AEDCC814B746946396416B29A2A2C683BA1DD6E9606114BC3E0C9E0BB5A020A1771A2B7CED7A1CDFE6B4E264BE6126A30A27A4351659A827C84EDC1877023F66660AA4229B613C658D450928D10721D596A3B7A4BBCA221CA206F5250DA82B2CFF0B79BE386456746A98F37544EB67D8B291B0E862EEA231A6D048D7A737201111080979BED52BE8FCCE9BEB993D5B49EAE1B70C45593BD1381E4267BEA05B6ABD9865A8046FC716F9E7C14D6933048E1419D0D16C27E38D1D8908FF60CF2E2F8DEA3AE8653BCB9935DF628B9A6072360BB5CAC4E5971670CAF4E19AD3D7758AAC6671A36120298D71E16ABB51CABA153F9FF216BD99165F51467DD36703DD", + "3EE66A1955100C98B610E6A4A18A9EEB852427CBEC4AE60539AC8553AB512D70281FE78763837C36D991B4391E67B299864CE3D10DCE75F4831DEF03E4C34C2B8EF7054DAA12C8DE0E61E67325FAC1CDBAA3108635F620F203BC0424F605E435CBC879803628DB6F4B7033097FCCA11E1AE5398C805C7C6B2F19B1ED00601F4F66B72BDB41047532225C3FAF52A64FC0D095BABAA4FA60740D96C0E0C17BBAE6B53447BDF35DEBB477E0A5FF14370F3A53441AC1E7A9B33CEC34FF41961D0C48AD86B0FAB158228A0CCA2E10639761AD8A7172AAF4469FC35FAEAD99CE8A564CB8588C4A9A177A22684FC90B0B90A0EE5F40565E2CC557092BA6770E698C2709D00E1D593F97D80CFD586BF003F2FBB1098C20D209E150389A686A00D481F976F8F38515E31C43A94936F56C4E424FF283B09E50462A550F1619DFB56EE1622DEAE4D867813DA2B057FE08A3BBEB95635186EBD38CC644327B9AD4114F88D1CD8FAE5623DE5BE95650BF56310FF9AE99032A0968EBF61B3EB51ECB3A307FDDEC5BFB4D977A82DB57FF7B2EF680124A51A6B9F9650AA0D2D64D65DF7D2FA0D10E7B6260DAAA9FEBE23975F3C8D80A90F429F64CE08593183BDA4560B81F0C14882FBD4EAD6B74E716CA829B282E516170A71A50279FE8F77656819186E2F0E4BB87CE237DD8959EA5114098480C0183616D23503C4E2775B5133A773351417AA8EF3B7176D16B2BAED0F11716C098F88DA261596436AE6DB4A8A02D0858EE0DD7B8399947C084CBA0177633BCE810557ADCEA9FB33B767E859AE90435634EA45165C190DCBC073BAA44CF653E7A1F28C9ECDCE96A5234C46A61CFEFF9032214FF5B95FAC29175F5E341218A32FE3E9580F48F38A0A73173502AF970164617EF8D8BFE74375E2E370A96C1202F7C57D91AA0392E84165BFF96DBBEC4938503C7FF072226E171DA842C09259F04D2BB7BFE9B8C575D7348756D808F66C7BA7349ECB01D771C035B49EFA010E4ED3461D33191FD66BCDF5B703D87B0EA284AA5B6C3376ABB8474410ADDC2451C2869914626087DFCCFCB934CAC02125E380F2C164089BD7965A23CC362CC5B91B8BEDB4D5DBDB704211DCAB31A2DD3C9AC507A28B6C4341E35746CB857F60B42FE80DE5DFE3B98BC9E5AF2269A4E411FB87B5BE6CCFCA65B05605A0AED7BD320A7C63C073308EAACFA0C9EF41B23FC76905C1DE314CF333D48A7D31BEB2B6077F75BA41FA1BE8066B099EB68BA343C2C7388E834BAA13300F1B732558B9F2A61B565459BF3EA4EB012F081F6EF5293E3F02F1B00582B2F1FB1F9F7618C1D712D39CBB391AEB20A17DBE1F7EF6D1124FAF725BE1B62BDDC3C213A88A882CEDE31E89F91E9728CD0040832592AA148FCF74474382DCE42C07D6884C4F806F1D67A1048B4450EC80D129375FB54115F27800E157F998E8C72D6E94C114A23A78DABAE57DDF13A478050F01406471B94CDBEB68F993CEDFCAF946F50968210E08BF3F28A6D5686B4421F0B463CA41BA6FB76045BB406B6A53111B85107278AC03B6090457953F3B28E7E31B9815AF5CF25C708ABB577A7A590CCE4CCCE086F6D29344A6B8144505AFE76275FD074916DAC0ED888213D99C8904BFFACC546F6222B3D9F7ECC811253389E814170AA372E90FC90BDFD52502BBD46237B7DBE9327EC23EC71A510D1DE47CDAC0EFC8C0F0F9DA84C6C3E03C075467C3CA1ACDDF997C940A21D2DF516CA8275580351826936454D35CA0EFAE86E6CFEE66F97035592D567E63B176D7A7C96B3881381E5F5195ABA9658C935A7FF2CB2E7CC7F2F9C1C60A4CD1C8EDFA55F6ED1FECCCA088BCC75D7C5AC42FEF26DDE63E3CF5B00409EE80CAD5AB8544757D2F1CF59207451FD8366509B620D5C14ADB500BB54B0BB8EFBA5BA4A47AA1CF7C588EAD5939BAA825D1C45519BB15935CB901177770D1C4A6D1CE11DF7037452D95C64F744690B9831985EE63FD73C73EE20EABBF349798F267ACA6A852D3FA6B108E774106D48F465D3A739554E8BEFE9BC2CE1BDFB90755482DBA8461F72F7BE1180927DD7FD8D8DCBB23AC488FF171524C0948302F81D542FEC3451E056B14D81D81EE2300133B2616823A99E42E34FE319C644D8976EA832A73951FF6528EC42B0B6960F88C384A0B85D3030ABC5FC38DF8F0D2D1E77811E8E6A4B14E8B6DF3BDE605E7B241525D5E8A5A0CF93", + "33B4D18F7CBAE3FB6D79D39C4728C543BAB7D40B6BF20637FB27619FAD4DE514" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "40C229A23E71E694C2154594D972A719206BDB236B79C2401E7D67C80BCBB4EDAE122352AB5CCD69047FA196C24C9E00D7E9A7F803F64C0B6E48BB60977AA532FC399E70E457347607C4CF143AF741EC437F3F35A90656E581D592A9913D8B59A05D156DA4CD8A4F47F7522E90F68C49B0EEA77102111C343ACBA4108F32BD40E9276528D59084AFE7E8D13051C909C11BF5A4950BDA966AE5A0DD9370DDD4B7C5AE5DF67A388B4B5B4C6E988515A1C734FD6E4EF14A933320F43A1DCF45A94D8636C5B664D00260C5EA4A149600BEDCA87F6D84A8208EA08569F0BD18D9A273710147F83C1E6F932CE732BF83BE24DCB1A9B7DEB176049665E28FEF039DBC1A94FC8285635D6C5C7EA905632A0448F3083C3DE9477755552657DF46DA79B3BABBCBD14B74E74CD9F86A0971E4881D778FCBF6E7FE2D69F662CA956AF2B71340AF14866336809E223160651DA19878107AA511FDD21ECA681C942ABCE8D8B73BD115036E56AB9773FE48829D92922AB686D4A32A74AD62A131F5062CCDD45774A686677AC42598A07B416BCCA695A10D79271CFBCAD2F8DE73674912E3C0C77FFEC70A4A9EE37462FE96D0C90FB90CBAAF00B2909AA8604B21501376C20CA7DDABAD95792EFC4F0689D9A10125EB002959824E1DD99EAE87BD0A2895768EAD9835DA4BEF9371228166EE433CCB4D3CC45D57B28FB06DD27BF19986C1902BA229E49EF89DB36EF7BBFB3C542E00B9AC908734FE05865783D2A492005CE9B6E0825F4A2C9F4C2990AD59B51FB6D664FE34ABB33DF8A23A614CD735747265D18B93936F80D47A01AA04FE841BD466825201BA91E8432900F46FF16E3D1D6DF3240C8D59FDB87F8402A7216B2151360FC109E77D8AA624C757640C010633C7F0334F98142A411A98ED20EC986F4ABBA76D58A4AA5DE534B26E01B30421EB2823990DDD87177F869B3EB97EB3B1AFCCF3D77A00E1B94BB13B952E68475010FD13ECE8846690807DEF4B7191B9902E44E6C35639EC521EFB56BCB72D72C5E1C3BBA47258D64FD9E098EB6BD30E7C7D7A92F3DA526A05FC15983D5D79A47F749792D8B125BC61250CDE347EA4BF69EDE22F4FDA412476CA261F01E08E1BFECE625E687B6C2828D07B9CF51F46BE6B58E010A2EBDAD09F43254AD0F221E263703B60513398439FD8025AAB3B40A959786B86599E48DDDF35AF8C4C5B9AFC0C8FF4E084DFECAA7EB738BDF499323262EA0BB8A6319777ABFD9666EBEAB7060EB3DEDEFE0C8379C15D7B2EF6F5ACAFEFC6D575737C085BE884BF01AA5B7F3F275DFD39971C627EC56FFDC78D62D4CF8F52CE9399F7F4F5D8AB9F134F041B894520A277E272C2D5A0D7DAB09DBF81EE358F85A6470F42BC1DCDEC1FE87D6A13C58579C6507FD8D494FEC91CA089F4CFD90A8DD439262027103476CB54838A06A3BB4390713653D4DDF903D93748F95A260BF65CB9802B1423598170FFB4F24FEEBF53E974A85C6F0DF4E9191B07B7C8FE780F0A0F1058BEC9257FE32915D0E6A1992E895CFE097E7877BA12C1627683CAB2D974A7033954732DFDC69B455CA3F927273C294AE8B48813640CF691D68CC86DE9CF1D56B79C7B26860039161719894CDA2FB26147A90E60FCF0C7C0D516CFEE7F9719A8A36BECB2B8BDAD33CA4A6CCF5B39342DF89229FD8404C2D5C25A9B771B1B9A3BA588E47838AE1D9EB8392294F561BE9EE83F89FEB3D48882C882C08552B64FC95D5A7084736F9C7A0C9448853E47DDD8819C0927642CF49FE88E8DA02B0528B32CA5BC9DC85B558A4821B1D7DB6E779CBD2D78787DA23DE5EE5ED2A965D5DCAA1491A663E640736096BF703CCB2FD42342937101C536DC74D31D8E51D376AD20ADB51DF34E0B69CF4783BC1D2AA592B2C6AFABE7D9394FD7EF2A3C60F22B68ED4F31CE57F376205E6F0292D1BB5CEFE52ED30CE526EF14382F8BE594A7EBB401FAE8DE7980E8AB83D90503B9228DDBD4198917B77F507C96B7CC58A073ECA250D33FF55071A633F99C57F3ADB2ADE11199104D80A98B36A509406DC77AD8766A4432992D5921CE05617E24F7CA025D03D451FD9F8BA8FBAB41AB6A801B53F1B593031E596C465180923AF867AE30C02A127DC76E9D60F3CA7C24DC536DB2C2767D2560D2C35609224ABA7952F9B620562C7E954A94258CAE9A13E71DAD2A204395E024E4C13D30129B7CA676990176E3", - "AFBE52F2DD9F6575ECB165CFAD5F5646D89C1B8DB398A1C51CBD6A532D0D46F5" + "B5947AC486A788C55C95633FFFC33923A051F883B68E144C1392896D065D748406C4AB71C09102730C6BAAECCB0D249CA0935A9C936233B27F941A4F1DA291B56B02629B2FF7094595962AA9BA4172578F650750A11305C7C390837A5C48A5B892962C30A38DCF1947E343CDE8E314F5816AE6E70125C2BB400BC426617954AA4437799E6EBA8605843776A4755A313C88F176B924C71FC993AFF95A0AA266813169540064AF119BC26A9074D3B6B874113A56044AE76E644A0AC7E4045A8965A4A1103011865DC153D008833C665A5B4A490068C02E979E8A4B18A43BA283B8B13A190585CC5D2F2BC9423BC1C51C0EC6344A8A675D646874E5D01B994A52834208876A2F3B2C09BB0B4D4401956208D0DB5275146305CC851BBAC31C40B5C59406251715A50C6BAAFD21A7E80C4AA90BC6708C491C3161BDB955289172E3249F81402FF9C53BBBF3A1C1C7A678F508B9789A290943FEAC2B093A3733874DA8BB00E5F81B3BF30B216B915D78A689C726CC9629B0A83987275FF065923B7060E94161E42A46D194679D6790ADA04759405D8D0A5442B1194F364969EC321BA4907AB442225A5393A3CCCD020E63184091D53DB0A21C55D6086A45939DB4A4F23C9382B2A91068662B818EB7924013141DF94947492B2BA4771D490AC210C2805445C40D5B526452349FC984C67B73D013AD3869C7570C7A160030979B6E0A293B5CB2082924865263762FB16B3F3BBE482B53DA585AB325A3E6B130D7AC337EA7AFB6502B8AB61DB9E7BCE3343708FA62F9B8C3C306AC4811A0B1B4BE853577D3382F86534192B22EFC8B6A41498670067B8D2A4A6B627610272E3C6488FB198EDD1C7300E46CA18C652F8799C2CB2D7424C1540C81A12463B16895D66B4268E03ECDDC0EF648C12434A8B8D8C580ACCD43BC979060CC14BC40514266723B7B7284A5BDB6B6F1994CD1938958B61147FB1856967EDB406D9137525FFC198D520E8706185484707CAA82B6A0A1D7C40AD0AB8198F8AFD530A398042606ECBDC380988B554B1E2C0DD4490E3DC6310F20C0D7B866A4D3439604CF695361A0002A9DE95818E50A1D614472A43559A167ACA2C75DEB0AE7082BD76373CA697E538B26B5E36BE69C6905DB5902A60EC3FA846D3A7ADEAB415766176F91316E3CCE0A03B29CBA0A1E93387299B4DD9C6281628944914B6C388046EB5199618FAC9034F38283B111CB9964CBD1A071734140BE6B4256E280418867357111D477A14313502C8719B8584385050E2735AE8E6371EF96C135F5A89FA44D71706E15441ED5C316098CB00F37174586418D340BCCF8731F33A22008C059D7289A42B4278C5499FB60AFFA58B30B7D28D72EE0433E8D6A9E5D8612271399DA7522E84187104317A13BC58DB2CB768059CEC5A0C8586A0FE0867A691F5EDAA65BC19B0A6C7F6E8247B455ADE334184A287FE8E6C9F62516400B86D1528BD13C419E80B8367CAAA7F6961B729FFA64A244D0BA2EBAAC5C291B0B745073569E6A85316B0823F73C782A59964116CEEDA9758B800CFDF78544A312E898A7019A00C36C0B4E6576F3657363DB4461504CAB162D520073D511AB1E6A49C7D2B13AE60B5DF2014B2712C872311F57CF19548A42B65951782625A68A1DAC5A70049FCCD9822A971259D255F5BA3D1C66C18758C797107771559DBC729DFAE95548E8CB95EA18E2940FB2F191A8E191B515B9C7EB775E0B4AA0E745C73A49D03389FBCC95AC769AF0BA3792B92EC42BB320B53BD18CC15A86A97DA4C8C9A339F849712975B040D283853B753831C43F13B89655363D86535AE38A1B51001FEB0CD1B05938B287217232817B33A5908CA92CBE688516E23B452D2328ED4A95112ACB8A18A8E6440A16B2CC643A9391C38C521A73783B631DD1A15E4823CB6BB7ACD12E25113266C873CE5774451605D949B75C5A38D6BA275EE6CE84619BD6CB10F4964249F60C9C062A7A52BC15A188494C132DBC36A657363117C852E113733CC208089298D5A3211904E7AC1C501A51720985DD20CD50BB07F3CC933444A79205C05FD22D1A533CFBB11D75039C17820F167A8417D029ED1BA46F086A4E39C9BEE7084D71B636F3B62AFAA64F32A0EA519CABB3519867107EA9829A245800F2A8A7278CF2E52001C63AA8E872961966FD63FF1C1284A2EC73E91DD388D5112F94F0778187C118A2B197", + "CBC478372B69E289C9BDD753A9A636F490B4732564D70A15D169A4961950D618210A156DB9F89F41D230668619114C92EF53AC54CB5424984CC8ABBB6E6BAF6304A67BA997E819208194CAC23B53CEB2BB41873352326FC2B4A405471B43A646E4A1924734151EE85A68C4B65C396666985205222D212B452BA3ADACF8454A42858D4690ED4A3ABC19A9F381B21A551CE4804664F644111151444C156CA1A87C6C0F9E6281F22ABB93AB32EFC77996302DA905386BA362EC709A130A1811EC8B88C4CC7D168AC0F2A24C5276BEFC1E3766CA27EA3134A55FD3B3C87CFA197F406FE14864DC628227E40A8A10B89482C7F90B008DC011523881992482F7AB2C35952BE82A0E3741CD637003FC66811F944C24207FC0684F2A39B0A8EC73EF3A3FFEB6BD4512B27362AEE5371D9107295534BFF4DC461351097B8B877114CF9C9933E27CA51F842EB81A8EA981597FB0C2EA17288B75734294302355CAF75BC9F093727DB629ADF87DEE8AA54BCC97940652A8449F5FFC2A65F031624A239B250256A7468884600B270C444362BF3569DC49146C7072E9636F4A7639626ACF3CECB796025B51959078115ABB9B8DCC469DA4C00978AC5DE418A0ADFA0FC8281324DB8472C44EC6A053A86B5EB8430BC6ABBDC8EA5099F000F24B62571C996506C3DEE1339E6CB6F968072829A99AD60733898800200E32AA5CE2F926990C1B120C3A149814C03B76759275FDB631B293A5D51A0BE2CC8B8AC513A9B950B185526A35CFDF44077B138F8FA86D5E935F0CE548041A516963C47DF6CB8A9A1D065AAD6C48CA2CC1B206375A2001071F699CE1E505C13BB589D150FE43433812B3812C50AD9956332793CC972C89DC7F376C95DBFB53F4490375B947C8E362B872327CB46F14524D65503B53E6219E3998B7F59F0259C8BA121A0AB51533389504E5227D89BF3DC71DD2BC2E105269F66111B0F15D46647DBBA27A90D2A182089B06C65FE24B5D275759215270233A74E4C455676A2A7E8C51F5170208122EB5C9714C3C23F0B88BC522B533294058CB82FB3C3272E17B3E28133EC2698E941932D66B057798E80517922016C31649328551F32A938E791650B4C34C54A5C2B295BFC67F371C84F46197890B1510BC0DB5AB17710642255C8980DAC599105A0FF848E08C629FD8935372C17AAC8469492CA27970B5C603E9191A8A172EA8A9993C5990C7129059E0248A1C178687900A797AC83406B9F95213E606CA3A8880C3273F960447BC00CA14473FF4A4E637AA0F638BD2EA502F04BA71D12AD3E8445730733F983F9BD17FF7E77B82CBB4E4FBA4766A779E50BF53AA0C9F1986CF1090331177E84A367F455081EA1E2BC96650D81B9C09B8055074F364CF7BB62A78CBC92F80A00D10CBFCA093CC57C3DA963025BC819C2CB09D33331A2B2612658E813875C6D33984B6806269B5167B7864D56CD1255B05122E17C1CB687C3164010B5ED81C7F803085469DB5B3CC0AB431CD28378A5B9BB411280627A9638C1D57F2675A6815D5934FF93B9FD347AC50EBC8D1DB723ADC9C0781033E805B663004C3143D859411AD2C23D9089248A7B000472B2D08988F61056D038272BB2215D05ABB459F0137BEDC916511D3C3A3694C3F2068F2508B44F5857D814522528AFD01CD5A26C58A3118841A80C8D649D6AAA64842676CE3C9E1072299A948C5B4C807370C9AC24E4113927D584F8EA9227ADAB5DD651A9FD237E124B9DB3B2A08315F22A954FD46B374847C465CB7DDA931BB400C66FAB97EC1355B213B03DC74D8193594B4A33F3000B8273A5F8077FCD5299F778305C4A8D0548C4EC50D31FB0CB1758BDB7B572C5913A1D4ADA94A8925D089B7CC38CCC4817CA7894E25012D897EB59276C92B9859569793B93829472FBBD317A8DB928D77C2B9A34CA31B6A3A919F9581050421030FF50D2F970E5E491EE3D9558F5847B0201CD3FA524A7B049126833AF67929CA1B3C4A145C664747A1627E40B3DD6247BD4A6595CB571405907699474D2C63080023E59888A3E5736495C8A75C8E3BFBB35787625323A583E322DA43ABA975B0B468733C6AB5B9D6148AC61245A9C1D2B880425CCDC0EB8BE4D763688B7059D404E0CC7A60FC2881EA38D19AC98A4103EBD7422C91AA1EE516CEE398B5947AC486A788C55C95633FFFC33923A051F883B68E144C1392896D065D748406C4AB71C09102730C6BAAECCB0D249CA0935A9C936233B27F941A4F1DA291B56B02629B2FF7094595962AA9BA4172578F650750A11305C7C390837A5C48A5B892962C30A38DCF1947E343CDE8E314F5816AE6E70125C2BB400BC426617954AA4437799E6EBA8605843776A4755A313C88F176B924C71FC993AFF95A0AA266813169540064AF119BC26A9074D3B6B874113A56044AE76E644A0AC7E4045A8965A4A1103011865DC153D008833C665A5B4A490068C02E979E8A4B18A43BA283B8B13A190585CC5D2F2BC9423BC1C51C0EC6344A8A675D646874E5D01B994A52834208876A2F3B2C09BB0B4D4401956208D0DB5275146305CC851BBAC31C40B5C59406251715A50C6BAAFD21A7E80C4AA90BC6708C491C3161BDB955289172E3249F81402FF9C53BBBF3A1C1C7A678F508B9789A290943FEAC2B093A3733874DA8BB00E5F81B3BF30B216B915D78A689C726CC9629B0A83987275FF065923B7060E94161E42A46D194679D6790ADA04759405D8D0A5442B1194F364969EC321BA4907AB442225A5393A3CCCD020E63184091D53DB0A21C55D6086A45939DB4A4F23C9382B2A91068662B818EB7924013141DF94947492B2BA4771D490AC210C2805445C40D5B526452349FC984C67B73D013AD3869C7570C7A160030979B6E0A293B5CB2082924865263762FB16B3F3BBE482B53DA585AB325A3E6B130D7AC337EA7AFB6502B8AB61DB9E7BCE3343708FA62F9B8C3C306AC4811A0B1B4BE853577D3382F86534192B22EFC8B6A41498670067B8D2A4A6B627610272E3C6488FB198EDD1C7300E46CA18C652F8799C2CB2D7424C1540C81A12463B16895D66B4268E03ECDDC0EF648C12434A8B8D8C580ACCD43BC979060CC14BC40514266723B7B7284A5BDB6B6F1994CD1938958B61147FB1856967EDB406D9137525FFC198D520E8706185484707CAA82B6A0A1D7C40AD0AB8198F8AFD530A398042606ECBDC380988B554B1E2C0DD4490E3DC6310F20C0D7B866A4D3439604CF695361A0002A9DE95818E50A1D614472A43559A167ACA2C75DEB0AE7082BD76373CA697E538B26B5E36BE69C6905DB5902A60EC3FA846D3A7ADEAB415766176F91316E3CCE0A03B29CBA0A1E93387299B4DD9C6281628944914B6C388046EB5199618FAC9034F38283B111CB9964CBD1A071734140BE6B4256E280418867357111D477A14313502C8719B8584385050E2735AE8E6371EF96C135F5A89FA44D71706E15441ED5C316098CB00F37174586418D340BCCF8731F33A22008C059D7289A42B4278C5499FB60AFFA58B30B7D28D72EE0433E8D6A9E5D8612271399DA7522E84187104317A13BC58DB2CB768059CEC5A0C8586A0FE0867A691F5EDAA65BC19B0A6C7F6E8247B455ADE334184A287FE8E6C9F62516400B86D1528BD13C419E80B8367CAAA7F6961B729FFA64A244D0BA2EBAAC5C291B0B745073569E6A85316B0823F73C782A59964116CEEDA9758B800CFDF78544A312E898A7019A00C36C0B4E6576F3657363DB4461504CAB162D520073D511AB1E6A49C7D2B13AE60B5DF2014B2712C872311F57CF19548A42B65951782625A68A1DAC5A70049FCCD9822A971259D255F5BA3D1C66C18758C797107771559DBC729DFAE95548E8CB95EA18E2940FB2F191A8E191B515B9C7EB775E0B4AA0E745C73A49D03389FBCC95AC769AF0BA3792B92EC42BB320B53BD18CC15A86A97DA4C8C9A339F849712975B040D283853B753831C43F13B89655363D86535AE38A1B51001FEB0CD1B05938B287217232817B33A5908CA92CBE688516E23B452D2328ED4A95112ACB8A18A8E6440A16B2CC643A9391C38C521A73783B631DD1A15E4823CB6BB7ACD12E25113266C873CE5774451605D949B75C5A38D6BA275EE6CE84619BD6CB10F4964249F60C9C062A7A52BC15A188494C132DBC36A657363117C852E113733CC208089298D5A3211904E7AC1C501A51720985DD20CD50BB07F3CC933444A79205C05FD22D1A533CFBB11D75039C17820F167A8417D029ED1BA46F086A4E39C9BEE7084D71B636F3B62AFAA64F32A0EA519CABB3519867107EA9829A245800F2A8A7278CF2E52001C63AA8E872961966FD63FF1C1284A2EC73E91DD388D5112F94F0778187C118A2B197BEA6091E1C84EC506C2DBA85F06A3C883B351B68C1F88DD22A5B8D715A31FA076D75A0A5B9CF72985A33022D52E1E6E48F9BEE0BF8BFFB7CA184579815CF8198", + "879871CFD21BB57F46B6E96AF4ED88C8A5BCC36DE10D9ECFF4C43A37366092ECCA6298379E97EA3BDA1C7E2ECAD560DCD56D1C9F1E5808888D72E78CE3968F7BCD883B73AF503A4967ED7BB2158B74ADEACB327120603E8DC121C51401D61971ED85BB1EAE35A0584C9FB7BE6FBB357F36BCBD14C3979C759D4C05DCD122CE431078D067A371CB41B54A42BFB9B74556E778B4BEBFEDCF8685D848EE1A22EA758CAD402E1FD8E33D8F3726849006113F08B33A51BE65C9094EA3D1FB52E1E71BABA047F0A114DC50626689440F8303BF1A9CF1DED1C6451492D11A76F6BD438477960AB7FF2CC0673B38BA04C69973E881030CC41DFD994CFFC4CA86E0E7CE7817EB100D2637BA1DC4D54531D2AD989519401D7F776B2EB5F16430F361D93D91E1D70F376E1AE319BFABCD5785485462F39EA65D0C49E856CD7A1FA3A6143C38DDF47754717085040C1F64F6C38310549E64944B500070A478BBE6228B7AD282D408C5C759DEC7CE78FE2FFD4B721382465FF1C033C7103143922EC00FD7D2A65DDA8A1DC77E7FBC3DBC2366734085BCA80305B6BFEC5D439E4517778EAD5416A78B852816CBA245EC9BF58641BFD29A9C54FD23A37FF3F767F6B6DC4A9A63F30F9B198CF8BEAD29BF319C01096DC506EA53C21B5E8688BC4C5FC75D5D3AA3AC29C98D5C56EA8C31E90A746C6CCCF729FA8D65376D53A469D1D279861256C96233E47413F3FAC263AF542FF6CA0B82DAA2FB9362692E8BF7C135EB0709022B58513B93AE33F254D7D19667DCA97F3F015EE2D96E64C89D2F45432DDE0708533096BB6EC2E1C8F06376A86F8DA121351DAB44B3B226731520F1A7E709755F3B531CDA072B110FAB7B1D148C13113BD0457AD77CD7FADF74A437A393AFA3C93AA66E0A0A76C0019C0FCEAAB85641EC7AA05A847AFBE74F01DC686D48291E69F98DE6A1EAF56F3452C4F70D62298CC234C5F700BBE190951DADA8DBF725CB44F50394A0D3717778E0DCE7FD72FE26685236D04FC8E9EEB0EA90365D181AE90B7D0A7560DD0B00E1BD55F9F4FCEF3AB393A2AE2A13345588CA6CBAF9A30FA58E3725844F38980D689D1495D159ED5A9C4F557A728E016B87816F40CD22789784859F1FDC39FA30BA72D25B1A14E74AE35F6D52F05745E92EF64ED980F3655473B5CE84491E791A9490CD995493E9E79D9F2EAD20FD204EB67218786161D5F7E5090523FA861817377F013A131A51B3DB0FCC6A845D340E86C7B686A47EE7503A552E0FB0100A6C3DA1CFED6F8EAE04A67C479415649560289C2010B223A107A27DA2F0546EFDE378FD5503912034F6ABDBBC966A47F28A9FFBE7FFDCDB2EDFA19F4639E2FF9C1F4E448F94A8A246AAA17EA9E641E194F53AC24EE125DDF34C759DF5B057423551D3CFB9A1D7B803306E1187CD50E81B1CC4B2AAD0D753CC6319A53DA37AFD47066AA8BDE900632FD7AAB9D93B67A6589DDD14FA7B048CF5022EA51516F9D258671BF578D2E2ECBE5D46BCC165C19ACD3D17E1C923DE1F926E56DD433D861CA64D1F9F622595C42DA1A9880192125308B9A0182C068F218B8E266EEC3AA506D5D85782D6394A9A40F10C3F55B5BE3E13C6FB0B7F5BABD078632C7689F4A49A523CD1B5792F0D5BFF8CB4ABF559220788E560DBBA3C30606EAD7F11B77B5C596CAAEEB28EEEB3C6B92B077C7688229B4394F7F297F1D084BB20D600075727BCB41741580F6FFB832CAC1A91558FA6BE5BC30052AFAAB00399B67897F8208F3FD4D7D8CCDEE652612BFC8CAF4D8C9D9DA35205F599317B35E5BC41070F4E228AA1C3294EC7A2911E02190F2B6697AD05D71208794003B414C96F671350C9DB52842F20E36372646F58B02E0517035157E1C389EAA2801AA8F3B749FE6C98051EC218247071EDE5903C55627424BD4AD546135BA7BD013AA38EA8490C0CE849CB2C5F38F11306894D64419E1B3DC4E2B6B267BF10875224D7EAA7F01DB4A02CCA953282178CB1FADDBB889869BD5CA9A188BE9C01303545E11AFC47B304B175FAB76AEC5091E6C6F5C65BC90B9DC7C6F853285CE436C2AC703928D41B08BFC7B89FC4EF2C39570877A7D7E25E762CCCD09E79DD16EBBD1A50C9021931F9D84153080E8EFCA7E2EC9A8E0CA7344DB6EA1C776F996F65C232F0E6C0F0D612E40C3873456385282080D6F4DEFAE7B82C75B6826A8A9AA68E1983F7D9FEA5CF", + "BDEF9A36C2799E4D58AFDC0509C15023398BEE0D27C1D3C9829475041B52FA1D" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "9523B02541D5005CF145D86EA3A697313FCD491D30DC16E0913F518444DE77A78BD70B2B0E5B155DC83CA7C0EB250BC6B4EE649022FFAD6A7EF7ECFE5D48C10DF6FAAABED91CF12830AF3E8B12FE4EE4D8E60D70729CDB32AC8617E1FA95D21419FDDF5FC16F72FC97D083C198220FA2C1351E6D2D6FE68C2B21087A629BE2C7060CDF002531A28E4DB769A592C3E65420B5BD53DE0431A961B9E52A9FC53CD8DACA088444C97E710282AA880DC7275362CEEAF2AB57BBD6D1DCAC1C84176563BD2E36EF5832A0CDA96ADDFC7FF8CC385D1ACAC69242A23BCAE7A1791DC3E4D114B8D4843B587CFCE504996F362AB5D48F171D28507F5B606DD72A038BBEC5D5DA13FFB3E9BEFDF1B821F2FEA3DDA7408A0261598DFBFD0FFF4E60401241C9A85FC2B321229C3D38A13A9FAC868026B0FCFEB55B7D143268EAC680C4B86F5807771BDB33560A1808808B186DC2AA9F72206590FD15B149FEFC6E6FA6FE8CD286D6DC6F71B2AC44D008A8817CE7F12C4BFF9A4DF9F4224D85BA32D16C3E8FB3A17AD3D4F4AF081AE31C2B6856B72225265A41CB374BAAB6D41726FAAE615E0F875F0996BF0893E7ED27C434F3EE36F24197069ED2BCD683F7995C204064A13E35459CE5987D38165A2E1B83DF82D2C7A2E4887B11F89D91A63714F4FBE1F92D1CF212F6D1DD6340301E66BFE2301DE8266BEF53B2F50D001FB05833E46E55859C7EA95E8D18EC11917CD02A17C0A8551E5606E5BBC038047136401A8EDB6C63CAE400B03F4F38DEACE95B7A046EE9641D7C1AB15EBA9F6E6CB067194C7EC6A16A9D8CCCBC182F68FC862CB5B92CA3BB817261247A0F9690930AFEE80272F11F774C556FF3B69D5C2BAD61057FB4483A470D51F332CD279EAD27B335C7188B8DE176E06284172D511CC3872F29193D157F0DB74D5C7AD28AE23132F0928983E7CE21CF2318332F5676C38B01D912BDC7592DC667F218C6785C91CCF0FE61791E80C5C02E3ED16897ABF0F44401F296CDBB29DC6E8FEAF2CA27CDBDBF4297148B260E64AA3121295D1BA38646C5FC614510B73B067798C479214B847799AA39DF423CC11AC8E7C5990840FC488946DF08C20A8B95E7356E2BF83EA45F61F4DF34F2593177D6A6FC5D1240CF6C96F873391D7BAFC3D65FA106049CAC0D97E7B1B93E3AFCE3DA5C71A48260A7114753C0ACDF18A9E945A25E0B3EC7E765AB95BDB9F41E1D2E9E928BAE1B287D954A489BA289135F2E12D79D3EC2D3E92C62AA2B94CE23AFF987CD70764702732E8DE36880A60AE0B12EA6CA974ABF4734120425E3FF3A313373AECDF1F07B523400763BA26F85CEF1C24DF96A3161D5CF4E50D0D9278DA25DA99D267B1F635504DEB2816194698D5F92056ED4F535B5EA3BDF6765DB131B93BEBC00020980E9E282BCD8528BB973E9A1B62548C645228428496AE50CA8875EDF0321C7D3E67B46109B49C1780C0A702E99FDCCABEDF2DA22F6AC2CA7612283C4CF9D24A5A1173C1387DCDE0CEB4D18D34FE4220B0A6BF333432B064F9B5E2E8D259119063FC12A169D1A8EFAD064603AF0C3C66B44BA8760085DFB89434F5FD32DE121226719A014BE785680E5A26E7C9E76F028B027CF030C430A47FCA785F1585F6F04C98792DAE168CE7B40CF27E5E7E11B6171E441D71A371105CDF9EE857F9393D8F6C86A163CA5B67EDB2BE2E26C01369149E13520781896D580834CAAB024F212C6CAD02FFF6D4843437FB851674EA00AC199E0C06410183B6FFE771A28D23B7035ED78912DC1D17F79D1A705627A3069AAB7089D4152EC1E2E3EE1EDD97F185C4214691B71FACEC1264E1EBD911DD2CF015911CEDC13462786023CE96C82288336BB7AA3D138B94EFAE190A69647C1C8143212B5B0C6B3DED79D9EC3042FCCCE7CF6C6214152E08B784DF321F7E3F633E3F6AE3CCDA5F72B37C287673B73F25CFEE7AF6CA242307B09A1486841CF56949F3E1087D619D1FECB08C9647F15B256C21DBF4E23587437D6C68BDD3B5479D9DDB22D532D44E388D27981C9121FE914ADAEA5063927D78C6EEB3878828DFDE4B3E7065F63272F162601CB458D644177B8BD3CEDA62049E85E28A0154816B9C9719F77ADB5C329578ED5768FEEC8C40160A89BA0319D1CBECDD974547A31AFF3397AD3037D9836C97F02D9615A0D61C4FA34369494129CF1D72B0E38B9169987635081EBD4391699", - "CA17438D4B82B0CBE1007EDF321C1D128DC9BE1AB1D1E7A82E61413AD321B31C" + "02043AE218AF1092A508077B6CC43EADDA1C508289CA850D8DE984672587E74743B9422C3CC21998E94BA98756C34A6536989F5255C98253981B710452456217CAC68294410EAC7F463B3316C5B701E5AC79590C9D260BE3AC67534A7E89CA3F96107D3D935DD5039A429B1F0D00C9072C623E554C94C688489B0D551311CE35379394CCAD552B59276B7FF831FB2C33B5443D29E82AD052C806952584C5BDCA3C2CE871441A80AB3BB994C9FCBA502A957D3B66668A43C1E5AD48F5677823311E4117DDA822E3E775EF0165C9277084743D89912F622CAC63438375E7412F9AAE2914B7FF2B38887BA03BEB56FDF18CF4C0486EDB00353636E6F44F6D4A4E4FAC097BE141A6FAB0A773872B747F32C51D9DE257021A36F358BA6377877322820BB497C8077535360AFF6C6460B71D913C77110987D04B1B36815A231AA62866205A0C4DFCEBA5C44797BE40A8427C842FB091BAABA8F62930FCCB73506810929939904105A62A46E7B2C0A09C73C0CA8D18F6C7DB7B20A67C6C0263B54FF07A0620C998F5CF8519ABA855085705C05109CBF653A919E47140168729926AF51C37FA195060B9525C900A80B55E850598E2B5120539105E60424DB93DD0B281BF59CD627984564A48AA61CC9EFBB98AC9342C042BAE6AA49494816CC1B2E2A5A4D250A92EDB9593754CF9792C8187997C6C5DBD957BC44BAD6D21A3A3D97C16A47B677B50116313081481DFD209D7A2B63DD011F0058E4F3824F08C003E76486301C97A63522CB783C49B62FF54C746CB9DC8DCB7F7E83D6E4B88E1450A2332379A0999F5E0B93DCBA630C4A724468F61A44A627C4A99BB5B95F1603171C0703980C2607F246A2C2DB7BAD66CA27C016E1806CCC79B826054BA0F363DD0A77EAB499EF6924CE384A072CB55BE166EBD60BF680B59773597A0B8B255230911C50F160798BC0980CB7393876038F69C3358B44AD3356FF380A70193B7D10C990683CF62FC2E7EB176C2E4C365B1559CE72B03214B34DB183DBC9431AB3D41FA624A01C10E95C687D00CA994658A70CBFF83A60F057202CC61D5C659AAFC7C86021985E380E4E861517583BD71AE7A843A15586E51073FEEE8CB627B0F15130FE182B728020348F5692B84339FA1CCB7D1C85D3868943A0611B122A39AA3FB499784C8C1E3B7A64D2434B0B498320721AD0A0589CC13C89A178CD99105EA819BE904E1AC54DDB47F774CA02A514C513851A9A64E19560F9800C7C835C065D3C6FC59717F262089AACE51842F5E130041FC094D11310A79B872D63F0B58A3D0443008840E5807ABDEA0A5878C5EB0D87EA0330F27DB2470C9C511D56AB43C89E4EA14B46C229E9B2A22906C9FAC533782A632997F198854F2AABE65FCCD877165024358AD4C35B7F778B697B26D89B7F935184103C13B49AA74E7C388390340D77775F84C397645F6E863B28016052586CAF2740C491F4FE16368DB9D89120C7D1481AE647367200400FA4DACF99571E6085F59338D33753763577374C945DC9268998CD9F5BBADA64D67B201AB688DBCB34FC0C1AE05A8370BE00B4B07622A2A97EF661F8A937B5E014264B088374C91D54B72442A4DD50BA0849CA234178B8291A5E4926CAD4A9D9F966744D402CEC274CA84675A77049F822165309212926DE0E6C2D4808C502C94E0AA4851A022C72AA2E467B1298C8121A0C2D6E5BF21837B7FC45357E35580270E6FE9BF2B60553FDA4E838591F1F12DD2C64A6513B78469AEEAB29FAC8504B321855E29715DCA95BAA383B8A1B6A4936DD0524E0B0A9E622881FCB9C7AB882D339CC9DDF1CFF29225A7021FFBB43617771D26109C5B487C2F3558A9A589A8361EC5B4638F5C56BBAA0469F8572BA4BB75F77A4FBCB212D65B5AA28A5B063C8768977678B28D988D8415BF8DD63033183E2D969572779540318909F66C236341C3A1017EE1319CC30815B00543641679A6A2FD3C537B1C3C16DACED7EBACD8C37E36DC420AFC3931346FB3CA0D65787754BCBF2EB4BFD98A8496E9972E747369FB59DAE9B00CEBCDE324684A6989DCE7B5C80099A164832C9778F5C773A9E45D3087733B7A5DE045A9D1463DC8E92A39577018A6BE587C3CEA792C18BB41A6C0A2EB3AB15639C5890C6B7B84B109F04E6EE86A22874AD4457BF85AF2EEA0003CD55F3A10A5B50EC333A6F81576E4E1BD9DEC94D3D2A9E12826", + "1AC53F5F7319C8334FBF791AE9E21F339C1304A9AAA8709141BB7E1603CFB4A4C09834523CA12E5A2797B19406916B57D2309BDB023C1F650CA4CA976E3B09F4848D2D710B44EB646153898A089BC168238D6B4E3FA73FDA088DB3B9A8CCC39A5CAA646DC97FA5DCC2A8C3276B508FE5FB9931D3B6FAF35569543592AB3AEEEB614A9A4AD6B691F22530B3660C1DCA99EBCB498BFC7119A3652E9836D7440E496591C8F7BFD196643DAC4DF0F247E9AA492D23BCF8EA2774E55270919F9A15242D2762A4882F056BC5046C265BAB1031B2004B514FBB389E16C7CF6FF03E41B8674DD4847C56B5D1E9132E78BDEB84B656A9544D1B965FB739EB467810736F3A519FCDA8411BC5805FF89350C56E97BA5B2F3124567087D9C7C2C00C71898445FD15321AA7341AE70623688237931717AAA443441EF7A01DB4E29055C73D8B9526C2204B20309E7CEC507C70A15C6B028628A79735479F5B25AA08AF98615A0F4637A109B4F3C19FF0C135FB172117397FAA03CA3058CF3FF52A0C9859807131FC27C787C31AC38ACB2F470075C9746474816B8C557EB1937DEAB8D1275FB86232CF837CE7A36274435B90070BE53A02B1658E97E66D148191AF60501F1C168D31A456822951289BEC795F9497428F5552F7F95B83CB687149237B0542A8A445146B155DC062B9842A0A44BFB3304D77BC145F0B6B52576FC75AA46EB60E39593BAE35234BC91D80F2488C70670BD001A611399258CBFD247F6CAAB506AB8D64EB54C7230F86D81F25771D61F35331A421C01510A437A22FE642DF9CCC7B31C7A4196576059A83AB9C32538B171A7490011150E1CA628B1CE87AC4C99B7ADD073DDD1517004D77BA4563D55AA168F067C1EA47B673A75FFB664E443C01C1CE340B4756549C84232497279A52A42D53B5AE6F377E063C2EFE6834476739D8972F74A9B4A23A8B864211A83C48378038D5954AB6D64B7191265F0B04910A74C68A4A03EC9768211A0FA5147E20CD4CA97403B634142A62867153422CAF996B967A6B3CCBF646D4B29EA55C1B845B27DEDC65240B846DBA68B36C1C9295587C7C7DEA8610F904AFCC85988A22302CC1B495717C5E661CD8478E05271C6A500DD0543F8AF1541CE25E648B23FDD9CD44174E53858371C4A8E6705E39441148230989C40D034B3764A054A62A50CD2965A3740264C0B9FD47B44BA0224CC44EE7B4257D9A04F5B01499606BC2566F692BB2592950049607009A7734710E15437B7E3A0658D928868112C1A637FDD4089D5BBCB460B939960DF06950B905CA79D3200021533F2B1E65F3B381F512847C1B24FBC141758EE72A35BAEB0648F00798F4A0BAE858C7B71198986C5BAB15C3D04198D18DA17C58294AC9ACC489F224173EE4B6491560EB877C512694A6E90A0F23731DA18A029000B12A2DC0193CC5976365BB4D383BBD36B7A938506019782F40F0839F3C2548E60A07175FDCA336B00A4FC7276D1A72504C222741F0BC8FB94402592018068CBDEA3589715ECCA77D86B7549DE72EBC9BC1FF6AA292B351041075DF6B4EB0A04CD6BB51F968989BA9339298551FE4467BC231312A5D79326BC267B6ED567FA405660910221C0343FBB36350B4CFC923514089408B974DA1F684D659C22769584C375E1465A7265C9208924E117957418254E50572F80AA58678CAB7CA4894F20D82088CF646B5C55C0280817371469C67B09BF67AC6E5BBB0BCEB626A057710D514ACE01298C37749B2A8F04B58D0F65F914A16B5108C7D44921130CE986690B5794414F6BD5C27C03DC96878185CF88415AC3260CF41378AF8A5E4E7C7F6392E7971671A5A3E0C5748741CB10A943F49C062DEC071538ACCF36A71D7D94A22860CF9AA223F6211481369A8CC6FD97C55B690860893B8C766172630A84DABAEE2D38B2F59834ADB7E1F189D42897107C9913EF53211BB5F660B2A63D89630199CD8C241801A87ADD373B00B134FC10162CB3B61B6C284F785650000ADFB60F3432653326ABD10060496A3CE629EE0D301FE1A8B4BA82E6692221E5ACD30351CCE7A6F65B04B1666A808E59C7B2325777C1DF6A0487B266E75280EBB01367EEC05194B5A71AAA28A65CC9687295F6A77B6D3B64BBC66BA11AF7D5CA764D4567FB039EFCC0AF43447A3E1C602043AE218AF1092A508077B6CC43EADDA1C508289CA850D8DE984672587E74743B9422C3CC21998E94BA98756C34A6536989F5255C98253981B710452456217CAC68294410EAC7F463B3316C5B701E5AC79590C9D260BE3AC67534A7E89CA3F96107D3D935DD5039A429B1F0D00C9072C623E554C94C688489B0D551311CE35379394CCAD552B59276B7FF831FB2C33B5443D29E82AD052C806952584C5BDCA3C2CE871441A80AB3BB994C9FCBA502A957D3B66668A43C1E5AD48F5677823311E4117DDA822E3E775EF0165C9277084743D89912F622CAC63438375E7412F9AAE2914B7FF2B38887BA03BEB56FDF18CF4C0486EDB00353636E6F44F6D4A4E4FAC097BE141A6FAB0A773872B747F32C51D9DE257021A36F358BA6377877322820BB497C8077535360AFF6C6460B71D913C77110987D04B1B36815A231AA62866205A0C4DFCEBA5C44797BE40A8427C842FB091BAABA8F62930FCCB73506810929939904105A62A46E7B2C0A09C73C0CA8D18F6C7DB7B20A67C6C0263B54FF07A0620C998F5CF8519ABA855085705C05109CBF653A919E47140168729926AF51C37FA195060B9525C900A80B55E850598E2B5120539105E60424DB93DD0B281BF59CD627984564A48AA61CC9EFBB98AC9342C042BAE6AA49494816CC1B2E2A5A4D250A92EDB9593754CF9792C8187997C6C5DBD957BC44BAD6D21A3A3D97C16A47B677B50116313081481DFD209D7A2B63DD011F0058E4F3824F08C003E76486301C97A63522CB783C49B62FF54C746CB9DC8DCB7F7E83D6E4B88E1450A2332379A0999F5E0B93DCBA630C4A724468F61A44A627C4A99BB5B95F1603171C0703980C2607F246A2C2DB7BAD66CA27C016E1806CCC79B826054BA0F363DD0A77EAB499EF6924CE384A072CB55BE166EBD60BF680B59773597A0B8B255230911C50F160798BC0980CB7393876038F69C3358B44AD3356FF380A70193B7D10C990683CF62FC2E7EB176C2E4C365B1559CE72B03214B34DB183DBC9431AB3D41FA624A01C10E95C687D00CA994658A70CBFF83A60F057202CC61D5C659AAFC7C86021985E380E4E861517583BD71AE7A843A15586E51073FEEE8CB627B0F15130FE182B728020348F5692B84339FA1CCB7D1C85D3868943A0611B122A39AA3FB499784C8C1E3B7A64D2434B0B498320721AD0A0589CC13C89A178CD99105EA819BE904E1AC54DDB47F774CA02A514C513851A9A64E19560F9800C7C835C065D3C6FC59717F262089AACE51842F5E130041FC094D11310A79B872D63F0B58A3D0443008840E5807ABDEA0A5878C5EB0D87EA0330F27DB2470C9C511D56AB43C89E4EA14B46C229E9B2A22906C9FAC533782A632997F198854F2AABE65FCCD877165024358AD4C35B7F778B697B26D89B7F935184103C13B49AA74E7C388390340D77775F84C397645F6E863B28016052586CAF2740C491F4FE16368DB9D89120C7D1481AE647367200400FA4DACF99571E6085F59338D33753763577374C945DC9268998CD9F5BBADA64D67B201AB688DBCB34FC0C1AE05A8370BE00B4B07622A2A97EF661F8A937B5E014264B088374C91D54B72442A4DD50BA0849CA234178B8291A5E4926CAD4A9D9F966744D402CEC274CA84675A77049F822165309212926DE0E6C2D4808C502C94E0AA4851A022C72AA2E467B1298C8121A0C2D6E5BF21837B7FC45357E35580270E6FE9BF2B60553FDA4E838591F1F12DD2C64A6513B78469AEEAB29FAC8504B321855E29715DCA95BAA383B8A1B6A4936DD0524E0B0A9E622881FCB9C7AB882D339CC9DDF1CFF29225A7021FFBB43617771D26109C5B487C2F3558A9A589A8361EC5B4638F5C56BBAA0469F8572BA4BB75F77A4FBCB212D65B5AA28A5B063C8768977678B28D988D8415BF8DD63033183E2D969572779540318909F66C236341C3A1017EE1319CC30815B00543641679A6A2FD3C537B1C3C16DACED7EBACD8C37E36DC420AFC3931346FB3CA0D65787754BCBF2EB4BFD98A8496E9972E747369FB59DAE9B00CEBCDE324684A6989DCE7B5C80099A164832C9778F5C773A9E45D3087733B7A5DE045A9D1463DC8E92A39577018A6BE587C3CEA792C18BB41A6C0A2EB3AB15639C5890C6B7B84B109F04E6EE86A22874AD4457BF85AF2EEA0003CD55F3A10A5B50EC333A6F81576E4E1BD9DEC94D3D2A9E1282695171AC1199A0987DB1E120B5C26CCA663D6EC78D83739F99F33B11714984027E634149D28457E74D8FB433BFEBE4C16D56DB37AA2CD0AA5BDC813A29BBDB030", + "90B7081362EDEC1698E74A36B8C07D7ED6FFE24FAC57A934EFEEC0080B617FB1FAA5A5C7CB33BB6F7D4539864EBEF1F43ED61C2FFF6512D587E0F2D185387B6A924260F45F28D3374FF4AD5090FD3E167153FA0631C84F2EF94138ED56EB606924EE50A5329C7533D56297C0AC3E67C4D03780B378B4C52AC377624D6BFB7A6BC8C4DED581CC6499B4879B2D2AA977AC9113A2AF99A4160A07BA9FC5A93EB8CD8FB242C7B00B462C696699275F70A9290D39914A1C28612161B6AC4AFED3428177789B52096E856CF28C96AF1E8DE8D6A014F14F2B6582BBB4BE5FF80F2B9E141E9D66ED203BCA9DE0CCEDC8AF0B45D602888A4A8B8568DA93C7BC532E2BBCC47E69CEE55E8E127ECEB7463A715190DDAE48853CD25F1FAA72EDAD7D8035F6DCDCC69003A421E009C194A92F7DED987728B425E2C883641E0695DD6E32BD95ED774C586B94F2A4E8E9E66CA9CEB8E71A8E126219A397E80C1039CF52A5F914D1D9DE1AE2C486ED7FE94DB84BF27ABAFB39980321D80DF7E9C7AA6FB4F4FBFFF14902A267A25FCD6EE96B6F377EB07D593C436C725FE2E587BF786B4C29247889910A3FEF19D8A2448C54D1C2720ADE7317A5406094AA9144A25B847FD1569CE8A40D31DEF65229CF0CCA5C3CC4F58BE14A97F35FD35C07687D76CECBF76D11DDE5896C9AA447F3229361863FC9E8CD2258765A00567CC696073EB66F0583341E1337F4DE2FBD46904D0812522965352191E7854A2CB2E7B8D0C2F37792A11AA86DE8F8428FD8D6AFD8285F117F653C80170C202E1D4E1FC71093FB4E21F84090FF40E9A1F7D2A314212F95F8C68E024B37B34FA1317ED134CAC60B756673BFD39E3E19CE9858B7663BD10E98D72F1868A40FB4D7965AE84E6B5AF3E7A856B2494E4FBC2547ECF915C3023467A4192EB9D86331A26610184B9E32B5F4FA0AAD84FF97E748889BCDD97C82AEFE87A2803808457E42D36F7B1DDD9CE83C7A6D758CC4A5F726D4A060B0CDD67F5B2DBD427E7509F1FF6AE1C08220EFEFE3C9803AC905BD9937D5E3C16DDBFA7E5F966FABA8932A8B3A39BB439F8D61A0DBD9BDEF86E7E00159DE66FD6BD279CAADD0904DEA27848454D924CFF42C73C05A09BDDC6697F561F2B7504E686A4BAE4421CB7535301B9E3D456FCA5E1DEF138B2D43C1F62B94EE0949F00B00A63C2FF9888CC3FC5D97571B42F39C5514647F7A64FD903424999FE861238A27F8162D98E24F158248E2366F7B79EA4CF22194AA33B6687C2760E24F506885D12C6977D644F65870BC972C06E7EF025F92934F8C436AC8C9816CDBF94F884F7CA4C77AB19AC75C97D1A39E4D8CD417577F3AD8844509E4099AC275172004ADABB12E11AF71C30DF76685FD269018091B3867C2EC2A2F1D2B094EDFE505D5DE0F7900D5C66E3E7280D608820522E19BCA736E6F719545B201270BD05D5E46B5886F8F7E488F65298E5120699585CD197955E8C2E7186E544E3C7D87A4F40192A91E49565D3C790FAC7E11D3A9723E5409C71154F6C41E62550C1DA3F025E78952569FEB4FBB9AD037E8BC7F7684379033EEB33BD8DF5C176675D0450C0D4D766E8FFB8D7061E2B28F2B63BBA5103CAD764754447497A7F96836187A74766290B5F10D3651BF2E7D0116C58324A5B8DA2E133D3C364AFD3BA9F7045935B200EF44C01BBC43C4DDF0D701517B9AA945F83068BEF1C8871D2C6FDEB3A8EFEE456BE79F2F7D87CDE8A274D43AC05F7EB44604DDF92C7263E32CFEF4FF8B249E0672B0B8A329C3ADAC1F21F77C389B011DA787E8ACFD321F9E2D3F8B81B38BBC2D69BD7921084CC9D3C51D4D44BC0B144A5766132BD612A54DF11555080FA1AF8AEB009F2A55EAB6565DCBDA7B046A02EC586CADDD4F3879CA2F7B50C8431E4E5F86A9C350ADED9D44C2BF663802E67EE48869780EC91B77CAEDBA71AC209523605FB4B3F830C2A12B5C80987025FD39805489378DF80E5422735C3F941D406CAE4DB8265E610F29AD221E7EB32CDF476F5DBA489ADF8B064B1A8CFC1707696C4ACD464C730520CA605F936EE47A671E1CD9D023853EC5AB9E354CC189D3B06F2EA227B5BC2BE6E87041519438C1555F57F8891B834B144006DCBF8FD244894CE5CC98E7BBDB9A8F3F6ABD19467AEBF16D1177DC5C2ADA47CD713A5117F00901F3B463F0DAF549575DCE610977538CCB616C9C10176DF3B89BF948", + "AA6E16BEC77355AB3223DB7CCEE88983FEF389837B073567A72697BE11BA8C5A" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "C5A8C763C511EE6848FE90241B7358BFF186BBC4B6C0B696EAE1A9CE9B388C1965DF06F76FFC7979EEA1812FCCB17E307E971115CA491DA1793D63CF514062092D284B9C180669CBF357B87CCF45D6FCAF1AA539822BD1992151057C70C81B4D00C6085A419BD7B93D4F6D708CE9745F1C7007F37B57C654C0BE8B951847271494FC23DE9DEC4454A3C0A6107D53A570115430EE2330508DA9B67A915C6391BA12FF56680B8C8B5CF133DBA70198B788B5AF664FF776910AFCA238A4861267ED9B0E42CB4920B8011B1A3797C214B0715F7EB164D6D1D3C67BAB22E6C07BB617608740D98A1F381FFF9C43DC17CD1A568C2B6FF9FC0A081ED729CDD6D8B5A9FC482321400A2C0F0FFE1F9E5469BA4822AD6C967E854CE4155541D84ED6D1AFA6CED139E876AFD711CF0B732C4969BB4D5E940BE686D8E0336AF3B6C1566E49FEB3BAFDCA994E262DF17FA85596E8544D56FEA430B93C99770FF155DA4DF18F45F2EEDFD07349CD467FE522EE9E7AFFA2059DEB3D812C981B4D45FE0519FC5115940AD9E0BC36FAB95EBCEADA29442D8A2912D765A5D72EA88B7D043AB94F0240387FCD3A462148042F5DF105AD3ED9951253EBEC64CACBC7089B450E74EC8E0C84A5748CDD13664F91E830DEBA7D6A7C79A394420E26DDE66585D8A90456964C8D1933C959071D6688F979CB7D60F8FDBCC17D9177B395E12BCFA372ECA0B74CDB264299AFB6AD57F720A10E1B08695C9838791972AAE361B61BD191AF410505ACA62E9EB055D73443CB2003B77A486EDB58451CAC8204AA68DCC489B40F0098FE426B156C4C4B8C23610D682DBAD6D2F74566409C9DAEC9739DF320DE679CB432A55434AD4B8AFF5FC0A544CA275742EED6917CB6B3F9916A8458C7F5063246EBF47FF20EC8FE04B7E5CD37E9A11C654F964D5E3BB34404572B7C2EA39BC482696BCDDC76EFBE3820E4CC662D3340A4FE3DC85F44EC4599F813B0C14F3B9540F906E1DC40BF9634743937EA4F34D79115077F0AE09CF317C0E004A21901911F26632A826F65476732BBFBF15B657029DDDFC1F333863332C67C415FBED95F078DD3B66D650B6BC78EEDDAFC3BA2C47337C0AF44BF1AE8539377C1655330D68B97527CF9DF13A2A418F6E5E1C61089E09717D6CA06A9B4546E0E9CA4C78A533AB648A38914FE9E8407A5404D687B86694E3EBB5342A54100DC5FC81ADA0FB01A3A9440EFD4C9C694BC5F29A9AD513C0469BF85ECAD67E4C2F725DC6FBE0A926EECD77E5A4F6D08F30A9621D24215731B81C1039AC1E7D92917EA2BF686DF95C7FC2BE16DEDBCD6142291C025BEADED6A7B8D17D20E2712DFB4985B351C9EDE71495C7A759776627AF670C4107431441489352B0852258AF90E53F8BDA2A95A84113358C3896D11043928CDFA6E293315A2BF58B5310D47C7901D7498E5125F498F265D4F3F525E1C2A1CE5CDB76F27A803E8CE907DC87F95A676D1A6D009A9FE1658A6AD162E14EB571547940020F45949ADCC4372D0E10122BB4DDDC7BD461B93AE92B7A735B7297D8432FB2B52030D470CE3C7F703AE04F4059DB091E5A51DEB02C87DE63E796B74A640F7B61E06BFEE6EC20DE6C84E0A042FA2138B769F052FAF408725AB40728A183141FE3D72DAE6FE456FC6855CEB6F274A221F01E2F7221A6980465079FAF749415653DF8C681AA2760E116EB08D988E22CCBE85498023B9E49DC59D08BD8805BB34EA1625904F220DE43754C081CE1BCFAE84CCB370B9C6E39B3C325C7E4A3270A78E91ED7ED89EEF8FEAAA471869E5DCCA09E027B07028149CA55E873855CD5C0CFCB6F3F71A9070FAEAD3ACC0B8B59DFB553C275FE138061CC42976B2C68F461090B7BDF1FA7EEF62C2ED16C42FC20A53A984492E579125F0CAB1A22A11E8ACDE90B657A4BFDD66931985EEACE6616259D8A70FC2EE622DF95F081C134ACAD18DD420C12870F577AC9AE4C882994FE19E4AEA6282524F8F7784F47AF9463B5BCEB37E6CFED95999D38A0408C91D6E609698BDFD0ED7E3B0369ADAB16A1CC2E44F9F803F5C8F7CD87B1190DBE05DEC987C3760C472A5C43011C98B6D6EF6909927A81DB3AE40EBFF9DB6D7C49C34C623482277FF608AC8DCB63B5402BCBF279E1F996D743E756F8FF74513B6107007A4F2AAB970E87FEE06A9C1AC2C6763AD407FC8429A52F6FBBC1F3AF31D1AFA4F7B6B47D40BDE", - "0FD1E5C9576B598CD1A90B7749A31487E996470FF9C234127A6DDB7D2DA22B27" + "6D425036E686687B92FA3B5D80A5A066452B762783B3D09744B819CB8BC7A97B26AA912B533A0492451940DCAEA9A410020C55FF0984B0819BBD54C1BAD61C0E456F81F81CC4F5B181666DF091CB478909C1946DBB998FC151B8666C9181D05247143E884464B70776FDB740516412A48321DB3588418B0F43B44C889C6950CA0C746BB9D22C22884664B65A7AD8D5403E6C5871155458A8619506163F125581351EAFFC5AF3107A153A1397B07E9E817CFABA9C5F654AC27C8244E30AF94A1351F2414DF40AD8E9A24CC46E16869F61B9014E4A6B030605151624BE8ABD40540D81E232AA48A861D680D6B3950511049CB80697F0131B15C25DA2408A64044DEC856F01C6B827695EEB4D0EBA9F9F309EDB20551E9B48F1B7899ED2764C265B63668AD8E877252B53CDDA125FA603AB3C5BE9286DCB88668DA5817761B65778A68280C817A4A22B782DDEF15D6B674E19B9882CC415BB9A18175906A77428780205C01C9876D338696B310F1A7B62DA0129C4BA58289357493865F935B2F005BFEAB570C46B59C0195FD82968B7B233E086E38B28BB6B5F67E4B20B224527309F68549A9E5167842C62AA805C3A5A0194277631D36197E32F3F480F5C7B4863B5889E795C1BA6252136C2EB7289EA2781363C220364CF66D2CC7D16AE58D14F21C3BD9199669BE6B903F677ADCB3DFFE22F40911011C6BD8AFA0EF1359A6B027640C327B4C859592071480A134FC06B2D024F209561EFBC2F0A0B65D649AE0DE82F3352C4698B2F4393882403827DFB9B9F25355FDC3E2A9863E68C8B3923A821113C86348FA20B356B69C35AE0A6AF432C14F70465AC8902F44CC5D50D0F3C95982758055924A8285B23345C400B7F517B27E1A79C1F8959D027A18C75B6AB8107201BCEB8EC7D11CA26A823074BA12A05399B132BAD09B16978C5BD2DDA2CD82B0AFDDAB5A2EB6A05F31EDD35820EC839B6524256778E10D666659932125681EDB1A534094890772977A993D409626D47A78E78873401B232CC30FCA10E4B4CC1A5015DF969B04B049BD1BB181B15A8FEE5A339D41F462322077B55CC17C70259954DA4CECE3942E0D2801C4A55E64607949165DAF575A15087A358AF023440C58930EEA06C59C74473B8A85840849AE51E68449BC1788C8343193989B96BE0924CE44239D180384286FB0841D99653C16A2AA2414A6E3815B0FC4A1DF34035B2A3D85AA4A725B945904125FC5EB2EC53F6393E10C9B78C35C658A27EF8E092D20C3F5435AE21C930D3B7512E9470CCE0C11FE0091922195906BAE7069F47F6726C48ACADA6B01DEA4C29F14422D367E0E216DCA511F4F2000B1A8E04103DA9D27224C6BF77682C347A47DAF525E5C6A8728A4FBC1078E2651BA3AA250AB63AEFF6CD2D3406EBC74BBA70894A651192B7A509A26B028786FF3623082626F00CAA3B55176A24299242CD8981A102757BB29B8179B7832E8716F3CA96928C43BEC91F8546A22AD325D665499C8A5EF126A6E238847EE328AF0177EC06C3CEC931EAD96E8883702421459F633842E39E9E51A8840289D2D5C4E4DC09966441FED735C0D174DD3B68B94A9CF23A6D4DB83D625AA04034B3409870F77B8BCB362CFF7891622B2FC3D90CA9CB8084B610B1A907F4D4B0BFE24D9D24C0A053C9194A3FCFF3ADCF956540022179576B44183062937C430886934BCB34734B79E13DCCA6B1967502A132BAEF88B9A972216F488E2508464C2C6A4BE333A3397D4C9792D9091788553464229151E52A2C2604C171C5FCE0AFA139C9CEF1B453835DF6472A4B400126EAC38E96B42452187FE1C62D8B177EB97ED2281FA8632B95A71199E896679B7512A9BF3D7714176BA9C87988653BA392004516829DF8351D15157C90716AA9ABC17BA86AFB4AAA77B154B9A1B9F18BA0E75C5C9EE97097A05E7AAA243E058D19174315CAB9737532DDC50E99730F53E239094786CF726380C8894236131609CC50B441AC0B6C60512FBDE19732796F9047BFAB401E56C097D23C3CE528CE851077ED6824514AAB11302087AA22C9D13DF0F2C57FFB916B46B1FF82304756CC376647B37A25C181863CB38F04415A661B33242482A579A19B1B1E4CE98D64040283172180D609DF323D64C99BE2220B6AC16D4CEC15B72C485A529CB821197101D439BA2DB6154E6E30579E754169857091D9D7FE45F6047794947B", + "A8E9AC28865FB8B9B659A12B1FDB2A83141FF1E09DF513B835350B76D5A43AAC54500A56E42215E8A88F14F69EC1287671868D88F1BB8C9381D23C157798C62EAB48AE92694F5577984A774E6962C0717C6604B2CBD4502C627E3807AC56B6A8C876B8847368276BC19CEA8CC7E13FB479A3379959C0FC3126CA565175B2D7909C46966235866A8BE4BBF8636661CC10A7D28780A571DB9B7C82576C7901AB93F4889147CB144B546EE539A213071168BAC92C6987D26DF09A518B442449989D02B54346E2614B9256B73248CEC04C63FC6B6DAC61D3B87A25D80398E2233D383113F2AB31053973277105D02E139029FB56AF9963BBA5AB4CA29A0669F0A6D3D3283F658AB015C86FC8AECFFC91954C6A75C266D7B38D243655D4801DF4385C818764850212EEA22A3B1725CC231128428A7C48854CD815C2752D4D883E3F150FE8F9164306C3E1F6273F460EF7C9856FB53EF248BEA8912C20E1575F26A6AC19444980A6CBD988125A7CF715037DB36B0B34349E93AAD519150D983DF402CA49A41AFDE60AD23C7E19E57235D71BE73C6E61D0328560121847CE0BF66F53C76BB39ABD8ACC6A003B9F163075F056A657FA1B3864066D3CABF2F722818879DF847D2E0401F102612A2192B6856EFBF9BF68033B934502539556EEB14518303078F0399AD777FF204E8D92BBA05ABB2C95C72441183ACCCFBD71952B43970BE492EE9B6ECD811092C800A01476BFF4152760C752231662BA90AC55C705965C8BF7477AA801614BC8ABA59BA2EABC5AB8B5DCEC9335E32C079B9B6AF03735B011F8249C23F6415D9190EA070BC34041B67592B5A0995F482E17357671D122E16134E3AC42CED6CF2DC186D556B59975AF80B958A2EB672214671183132FAC465A0456725999D81B0E27F4494514B7DB76CE1C307229F4C2063584A1B4C40D07551D560228C1174BBA14BA99200402597C319BB23434203935FA9C6CB3702AF6373452BB743033CDF08301EDEB770086735AD0050D870DAB338510A20F823032522C8E66120DEDFB9962C7C661944492C029F4E97DB9B8718E04B1186ACFE18B3685A0C8EB07B5EF30B01E8A1CBE732A948B7902111D74783F5244866611231FABC92D296D4ACC57A2F52CCDA33141868F0474B42A57507165176639C300CA59E4897CBDD824E1C78614537D57941B2F950480045A9593C4A7859DF3516784FB17FA741BC6506F5CCBCAABA4C9A9F49EAFF45B69E919154B62FA41AF0D9B11C9613342A63157C67E2D7052DD997E7419660F810C27732FBDC99E9840BB2DE1678DF795681CBF81B178D94333831A27E1225EDD75B330021CB9720ABD26B554C60226995E5E63C14C5C4E8916866D571C6CE7522253565EEA6CEB95ACE11514FD08A42A349237E835723588D568A8B2B1875FAA1A8B1891CFF081D269723806339342B724E0603A7407F4A55EA85355CB89077BA06653EAAE8FD640518026F91B74D6457FC97769897ABCC750C031A74FE9F48C94B06591554167C92624636F558710CDF64FABA2A165B56605011BC1FC9ACD4976CC4697CF21B0B76168C68227CFFACB291A23EB144B95A7694C434993D8996AF46C35788639B48A084500FA27675AF35966297871A76DFCB6A70DA1C44DB37117542DC42C0EDBD60C17DB62EA3AA06C554C1B3566399B77F9EA816E6C121CB827593B42C6A12AA8491F4AA59E8976ACADE8546CE0C690D6C013975E8F2B7A6E1020CF3659D750A7B271B8C2B17D14B07E420726B93B040B300B661A7FC6B8723F4A127FD8AD0BCABF23B03FAECA7997811E14609D34A17FC0D50ECC9A4A69DA30BA440A9990470E78B8CD077D33B36B3B9AC0FB9517E73A5E2A49C650C35C2D8A9E2B961B2DBA71C8E93558300FF09584D143B0CF213629C8A5D754C712F1BB12A06C813718B26C34B495A0FABB6BD434324DF11588DA9C29A84D1295CA7475AACA63C3ABD9064D4928580A9371D6B317E5B1274A5BBF25C600637CBA9C3F8E8A805B4A5FDB240588367987389F028625B66BBFA74ABC9016BBF9EC347ED9AFCBC4073599BE40B75D43653B5404156F083441E20C8DA408EBB27FA00AB1C476586D566DC20723FAA4657C2170D6CB66A0DB8380E314B0914978D97DF974B738719E715B842CF53CB4AA98F316456D425036E686687B92FA3B5D80A5A066452B762783B3D09744B819CB8BC7A97B26AA912B533A0492451940DCAEA9A410020C55FF0984B0819BBD54C1BAD61C0E456F81F81CC4F5B181666DF091CB478909C1946DBB998FC151B8666C9181D05247143E884464B70776FDB740516412A48321DB3588418B0F43B44C889C6950CA0C746BB9D22C22884664B65A7AD8D5403E6C5871155458A8619506163F125581351EAFFC5AF3107A153A1397B07E9E817CFABA9C5F654AC27C8244E30AF94A1351F2414DF40AD8E9A24CC46E16869F61B9014E4A6B030605151624BE8ABD40540D81E232AA48A861D680D6B3950511049CB80697F0131B15C25DA2408A64044DEC856F01C6B827695EEB4D0EBA9F9F309EDB20551E9B48F1B7899ED2764C265B63668AD8E877252B53CDDA125FA603AB3C5BE9286DCB88668DA5817761B65778A68280C817A4A22B782DDEF15D6B674E19B9882CC415BB9A18175906A77428780205C01C9876D338696B310F1A7B62DA0129C4BA58289357493865F935B2F005BFEAB570C46B59C0195FD82968B7B233E086E38B28BB6B5F67E4B20B224527309F68549A9E5167842C62AA805C3A5A0194277631D36197E32F3F480F5C7B4863B5889E795C1BA6252136C2EB7289EA2781363C220364CF66D2CC7D16AE58D14F21C3BD9199669BE6B903F677ADCB3DFFE22F40911011C6BD8AFA0EF1359A6B027640C327B4C859592071480A134FC06B2D024F209561EFBC2F0A0B65D649AE0DE82F3352C4698B2F4393882403827DFB9B9F25355FDC3E2A9863E68C8B3923A821113C86348FA20B356B69C35AE0A6AF432C14F70465AC8902F44CC5D50D0F3C95982758055924A8285B23345C400B7F517B27E1A79C1F8959D027A18C75B6AB8107201BCEB8EC7D11CA26A823074BA12A05399B132BAD09B16978C5BD2DDA2CD82B0AFDDAB5A2EB6A05F31EDD35820EC839B6524256778E10D666659932125681EDB1A534094890772977A993D409626D47A78E78873401B232CC30FCA10E4B4CC1A5015DF969B04B049BD1BB181B15A8FEE5A339D41F462322077B55CC17C70259954DA4CECE3942E0D2801C4A55E64607949165DAF575A15087A358AF023440C58930EEA06C59C74473B8A85840849AE51E68449BC1788C8343193989B96BE0924CE44239D180384286FB0841D99653C16A2AA2414A6E3815B0FC4A1DF34035B2A3D85AA4A725B945904125FC5EB2EC53F6393E10C9B78C35C658A27EF8E092D20C3F5435AE21C930D3B7512E9470CCE0C11FE0091922195906BAE7069F47F6726C48ACADA6B01DEA4C29F14422D367E0E216DCA511F4F2000B1A8E04103DA9D27224C6BF77682C347A47DAF525E5C6A8728A4FBC1078E2651BA3AA250AB63AEFF6CD2D3406EBC74BBA70894A651192B7A509A26B028786FF3623082626F00CAA3B55176A24299242CD8981A102757BB29B8179B7832E8716F3CA96928C43BEC91F8546A22AD325D665499C8A5EF126A6E238847EE328AF0177EC06C3CEC931EAD96E8883702421459F633842E39E9E51A8840289D2D5C4E4DC09966441FED735C0D174DD3B68B94A9CF23A6D4DB83D625AA04034B3409870F77B8BCB362CFF7891622B2FC3D90CA9CB8084B610B1A907F4D4B0BFE24D9D24C0A053C9194A3FCFF3ADCF956540022179576B44183062937C430886934BCB34734B79E13DCCA6B1967502A132BAEF88B9A972216F488E2508464C2C6A4BE333A3397D4C9792D9091788553464229151E52A2C2604C171C5FCE0AFA139C9CEF1B453835DF6472A4B400126EAC38E96B42452187FE1C62D8B177EB97ED2281FA8632B95A71199E896679B7512A9BF3D7714176BA9C87988653BA392004516829DF8351D15157C90716AA9ABC17BA86AFB4AAA77B154B9A1B9F18BA0E75C5C9EE97097A05E7AAA243E058D19174315CAB9737532DDC50E99730F53E239094786CF726380C8894236131609CC50B441AC0B6C60512FBDE19732796F9047BFAB401E56C097D23C3CE528CE851077ED6824514AAB11302087AA22C9D13DF0F2C57FFB916B46B1FF82304756CC376647B37A25C181863CB38F04415A661B33242482A579A19B1B1E4CE98D64040283172180D609DF323D64C99BE2220B6AC16D4CEC15B72C485A529CB821197101D439BA2DB6154E6E30579E754169857091D9D7FE45F6047794947B474ACB46790D527994365E95B582F5A89A0CC64CA298A6964F498921363C94A816B646E0CAA1B5BBB32A770713E5252E5E9398734EAE0CC99BF38927036FC44A", + "CC3BCA4285451200842ACFFA022C8EC7514C489D68D995187A062E12A4432C3C51E5373A5E63BBC2BA6F197E086CACE11FAE53DC7836E8E9AC389B1F4DE175D82E5C6BDD2EB3650443EB873D23BB71209CAD3A42A1EAD2C571181C1FB18F3269C671A6CBC29EB058FFD64E1C2CCE1D6946B3ADCC66DF896B11D7DF980B76B5E12CC6AA2CBD1F5489FC7F116726659C8AA3724F6D673C68B18936D0F7801E416863192DF45CA25C9A380CD9A061F58E8AEE18041732CF05A2C7BCEE0349B2020FC3FD8F55FBD0BD5321D77E7206D70AE03604F6EE3102F5EB3C5B04F63A352CBD8FBE95C915C3E47166787ACF2E7B751E626C8CFB40EABFC462A6C90409FB5CFBB36267CCEADF34809CCA3D716A15CC8C359307EE4CBFF0541ADAA9E3A36B5530D1A7CF880F78F1B46A5537994949004867385EC2536C4B77BA016416BD851F67AF6B6F822F97A8D627C45F69609C9DAF066154F1F1A759923EE26D68F141128CC125A5A91F0DC0AA084C4873A34D382CA026B2DBFC414DB7FDBE54663F8D69F9DDD84271EA27E1344B5080287E9FEF2960407100C94678260CA2D6962C7FE448EBA813FFCA34BB441C895C9514BC3EAB1B08979789FEAE3FEDCCC214073DB018FB2575B0974B3D5ACA44AD519213390EBA67E3E9C3A0325C136FA0693314938CC4373F4B5C91609437EB9F621315122C8796CF8DFA74291CDBDC2D09821C0C9F107164FF3ED66C9D5BF3FCF70FB9360C3BC1FD42E689E034E585C640139B2729032FD048C98C8B2C8D63037BB12941D61395D42BD1CB51BE5FBF1B5B07E04C21E4A9A45FC41966943F8DCBEFF1B100DE3FCD0ED8BB97CD9FA8BCA29FF487A2F4AEDAAA51CD082F60F9D66D9D12DC1E7775CEA470BD2CE7ABE2CD99C43FF16A0EE680189EFBF288F131C657587566EA75D24E921B56DCD67307F281299EBF415B871A6880E7AF7ABC108E5CB431C0E605A5D2DD7DF87E82FA1B7C4957B7EB28C2A833F37B508D2B888FD71F381B6E3225AA95201C34EA2FFB38C6B1D055062F0CFD34F285DFF7C6DF08F7705E1980B45D0DAD3464CD337916E2ADD3890D53D7C9A23C1FB3B794302925A6A9C5BAE749EDC9704E7E68CC2E952F2AD1817DC55E4199923282E691077DFD6AC9CD1DFCEBEE3810923ECD9ED1A0D4339475569147476C2C1B28FC37419B621C6FFF17F169720F80882CFE80D112BA3C16AD634494D4D598D245C328BCED946FA0F8368AF188BE37B286535ACA9739105C19D71BC60FFE03D6F4C8FE71E1BB6BFC1596827E0179E41CC6E070A02711D2D867B66F0B95099F4B0C17CADED30E008AC718DA9E8D9B8977708BEC407C05C0CAA0518511F57C9DCB952D5222952BCF777BEA53F0B290988258AC692018620FF57D894380A68F4A88DFFE8424846920332F597E3D2B35460B3DFC19569B771C4ACC12D2A45E294618C1A59C6F05355B85F0AB955AAF7F504572B0D4DDA1CB60B5D6C5A092B1BD2DABA010280FFF02B816487C7E0739287041DA5C4B11B01DD780A5975474DA56EE69F4B58542E90654A5F7782CA17C6F406D58162C77B139DF5352D1EBB118FB4E356E8AB5BFB5ADB6FFAB48ADBEEF1E8FF1BC2BB8EAB82CD82D59AAF83DDD6695475A59A26AF2105D87B4AC18ADD0E5A498C39E7F6E34E4DC083B095C3B5604FDCBEB824A3F8343CB5C8DF7894E84D67D6CE16A9D1000B2A18833DA14ADF3A15BB73BCFDC44597F1FA4EC5CA715D7C2BCB49D9DE14620D61F964FCFF47491E5E1805E3CF1ACB15E15D7454080E52F2B23A4F41A1018167A1267769D7E8100AE7D646512B9400B56FBAF796CE680A0F2F46B55223566B3A89261D4D94986E22328F20E49488B454E222D55CB012D9A6D8E02B78ADFE41658DEA2F2FF55918C5DBB28B39593DDDC9EB307DC09BA62AAF25D85208AFF056793BE6DF2A0E4BDFEA4AAC979C492F51E26DA3C762E23A834AC38A401BD806C63E457DFAC59DE940069B22240BDE06DC04412CCE8B2B363292AB61EE3958DE4E11CBB4637D0F514A11261803B1F0EEAB36B3B238AEECCF5E0DA02C415BE7D598B9D142EAA087A63B125F80F5A7AE3B94A623666EB246DDFA5D41B238A51741F441DE8386A0B5C3A52455B424F2C72A9EC647F1D2EE9452EFF078AB1FB086ACCB8F41CB34B96A555A504F607BBDCA5B95353600A0584AB0BF4534C375AA377B564422A125912D17CA0", + "5C7B5FB8B30A4F816925C8B7038ACFCCC5C82FBF574F501FD394D0C5E2F3D9D5" ); } } diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs index da5a2d6a7e9..791c64ff9f8 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs @@ -178,7 +178,7 @@ public abstract partial class X509CertificateLoaderPkcs12CollectionTests #if NETFRAMEWORK X509KeyStorageFlags.DefaultKeySet; #else - PlatformDetection.UsesAppleCrypto ? + PlatformDetection.UsesAppleCrypto ? X509KeyStorageFlags.DefaultKeySet : X509KeyStorageFlags.EphemeralKeySet; #endif @@ -301,7 +301,7 @@ private void LoadKnownFormat_Fails(byte[] data, string path, X509ContentType con Assert.Equal(contentType, actualType); } } - + if (path is null) { Assert.ThrowsAny(() => LoadPfxNoFile(data)); @@ -749,14 +749,19 @@ public void LoadWithDuplicateAttributes(bool allowDuplicates) { Pkcs12LoaderLimits limits = Pkcs12LoaderLimits.Defaults; +#if !NET10_0_OR_GREATER if (allowDuplicates) { limits = Pkcs12LoaderLimits.DangerousNoLimits; } +#endif // remove the edit lock limits = new Pkcs12LoaderLimits(limits) { +#if NET10_0_OR_GREATER + AllowDuplicateAttributes = allowDuplicates, +#endif PreserveCertificateAlias = false, PreserveKeyName = false, PreserveStorageProvider = false, diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs index b2005ab6052..2c58efcda33 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs @@ -179,7 +179,7 @@ public abstract partial class X509CertificateLoaderPkcs12Tests #if NETFRAMEWORK X509KeyStorageFlags.DefaultKeySet; #else - PlatformDetection.UsesAppleCrypto ? + PlatformDetection.UsesAppleCrypto ? X509KeyStorageFlags.DefaultKeySet : X509KeyStorageFlags.EphemeralKeySet; #endif @@ -302,7 +302,7 @@ private void LoadKnownFormat_Fails(byte[] data, string path, X509ContentType con Assert.Equal(contentType, actualType); } } - + if (path is null) { Assert.ThrowsAny(() => LoadPfxNoFile(data)); @@ -744,14 +744,19 @@ public void LoadWithDuplicateAttributes(bool allowDuplicates) { Pkcs12LoaderLimits limits = Pkcs12LoaderLimits.Defaults; +#if !NET10_0_OR_GREATER if (allowDuplicates) { limits = Pkcs12LoaderLimits.DangerousNoLimits; } +#endif // remove the edit lock limits = new Pkcs12LoaderLimits(limits) { +#if NET10_0_OR_GREATER + AllowDuplicateAttributes = allowDuplicates, +#endif PreserveCertificateAlias = false, PreserveKeyName = false, PreserveStorageProvider = false, @@ -788,7 +793,7 @@ public void LoadWithLegacyProvider(bool preserveStorageProvider, bool ephemeralI // EphemeralKeySet is not available by name in the netfx build. const X509KeyStorageFlags EphemeralKeySet = (X509KeyStorageFlags)0x20; - bool expectLegacy = (flags & EphemeralKeySet) == 0 && preserveStorageProvider; + bool expectLegacy = (flags & EphemeralKeySet) == 0 && preserveStorageProvider; using (X509Certificate2 cert = LoadPfxNoFile(TestData.SChannelPfx, TestData.PlaceholderPw, flags, limits)) { diff --git a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj index c6d5337565f..97e90e69a91 100644 --- a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj +++ b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj @@ -57,6 +57,7 @@ Link="Common\Interop\Windows\BCrypt\Interop.Blobs.cs" /> + @@ -75,7 +76,6 @@ - diff --git a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx index acec0d88440..9994b32d5cc 100644 --- a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx +++ b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx @@ -162,6 +162,9 @@ The specified hash is not a valid size for this hash algorithm. + + HashML-DSA '{0}' cannot be used with hash algorithm '{1}'. + The size of the specified tag does not match the expected size of {0}. diff --git a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs index feb43d2caa4..9344f75762f 100644 --- a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs +++ b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs @@ -6,6 +6,7 @@ namespace System.Security.Cryptography // Strings need to match CNG identifiers. internal static class HashAlgorithmNames { + internal const string MD5 = nameof(MD5); internal const string SHA1 = nameof(SHA1); internal const string SHA256 = nameof(SHA256); internal const string SHA384 = nameof(SHA384); @@ -13,5 +14,7 @@ internal static class HashAlgorithmNames internal const string SHA3_256 = "SHA3-256"; internal const string SHA3_384 = "SHA3-384"; internal const string SHA3_512 = "SHA3-512"; + internal const string SHAKE128 = "SHAKE128"; + internal const string SHAKE256 = "SHAKE256"; } } diff --git a/src/runtime/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs b/src/runtime/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs index 3a83e2ba346..0face5c7c0e 100644 --- a/src/runtime/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs +++ b/src/runtime/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs @@ -13,6 +13,10 @@ namespace System.Diagnostics.Metrics.Tests { public class MetricsTests { + // We increase the timeout for remote execution to allow for longer-running tests. + // Ensure RemoteExecutor.IsSupported, otherwise the execution can throw PlatformNotSupportedException. + private static readonly RemoteInvokeOptions? s_remoteExecutionOptions = RemoteExecutor.IsSupported ? new RemoteInvokeOptions { TimeOut = 600_000 } : null; + [Fact] public void MeasurementConstructionTest() { @@ -53,7 +57,7 @@ public void MeterConstructionTest() Assert.Equal("v1.0", meter.Version); Assert.Throws(() => new Meter(name: null)); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -82,7 +86,7 @@ public void InstrumentCreationTest() ObservableGauge observableGauge = meter.CreateObservableGauge("ObservableGauge", () => 10, "Fahrenheit", "Fahrenheit ObservableGauge"); ValidateInstrumentInfo(observableGauge, "ObservableGauge", "Fahrenheit", "Fahrenheit ObservableGauge", false, true); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -99,7 +103,7 @@ public void CreateInstrumentParametersTest() Assert.Throws(() => meter.CreateObservableUpDownCounter(null, () => 0, "items", "Items ObservableUpDownCounter")); Assert.Throws(() => meter.CreateObservableGauge(null, () => 0, "seconds", "Seconds ObservableGauge")); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -169,7 +173,7 @@ public void SupportedGenericParameterTypesTest() Assert.Throws(() => meter.CreateHistogram("histogram1", "seconds", "Seconds histogram")); Assert.Throws(() => meter.CreateObservableCounter("observableCounter3", () => 0, "seconds", "Seconds ObservableCounter")); Assert.Throws(() => meter.CreateObservableGauge("observableGauge7", () => 0, "seconds", "Seconds ObservableGauge")); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -228,7 +232,7 @@ public void ListeningToInstrumentsPublishingTest() // MeasurementsCompleted should be called 4 times for every instrument. Assert.Equal(0, instrumentsEncountered); } - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -280,7 +284,7 @@ public void ThrowingExceptionsFromObservableInstrumentCallbacks() Assert.Equal(11, accumulated); } - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -376,7 +380,7 @@ public void InstrumentMeasurementTest(bool useSpan) Histogram histogram6 = meter.CreateHistogram("decimalHistogram"); InstrumentMeasurementAggregationValidation(histogram6, (value, tags) => { Record(histogram6, value, tags, useSpan); } ); - }, useSpan.ToString()).Dispose(); + }, useSpan.ToString(), s_remoteExecutionOptions).Dispose(); void AddToCounter(Counter counter, T delta, KeyValuePair[] tags, bool useSpan) where T : struct { @@ -723,7 +727,7 @@ public void ObservableInstrumentMeasurementTest() ObservableGauge observableGauge20 = meter.CreateObservableGauge("decimalObservableGauge", () => decimalGaugeMeasurementList); ObservableInstrumentMeasurementAggregationValidation(observableGauge20, decimalGaugeMeasurementList); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -875,7 +879,7 @@ public void PassingVariableTagsParametersTest() PublishHistogramMeasurement(instrument as Histogram, value, tags); return (decimal)(value * 2); }); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -963,7 +967,7 @@ public void MeterDisposalsTest() listener.RecordObservableInstruments(); Assert.Equal(13, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1034,7 +1038,7 @@ public void ListenerDisposalsTest() listener.RecordObservableInstruments(); Assert.Equal(7, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1102,7 +1106,7 @@ public void ListenerWithoutMeasurementsCompletedDisposalsTest() listener.RecordObservableInstruments(); Assert.Equal(7, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1147,7 +1151,7 @@ public void MultipleListenersTest() gauge.Record(1); Assert.Equal(15, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1184,7 +1188,7 @@ public void NullMeasurementEventCallbackTest() Assert.Equal(2, count); Assert.Throws(() => listener.SetMeasurementEventCallback(null)); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1225,7 +1229,7 @@ public void EnableListeningMultipleTimesWithDifferentState() listener.Dispose(); Assert.Equal(4, completedCount); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1268,7 +1272,7 @@ public void ParallelRunningTest() Task.WaitAll(taskList); Assert.Equal(loopLength * 17, totalCount); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1337,7 +1341,7 @@ public void SerializedEventsTest() Task.WaitAll(jobs); listener.Dispose(); Assert.Equal(0, instruments.Count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1441,7 +1445,7 @@ public void TestRecordingMeasurementsWithTagList() expectedTags[8], expectedTags[9], expectedTags[10], expectedTags[11], expectedTags[12] }); } - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1529,7 +1533,7 @@ public void TestMeterCreationWithOptions() Assert.Equal("10.0", meter10.Version); Assert.Equal("Scope10", meter10.Scope); Assert.Equal("TestMeterCreationWithOptions10", meter10.Name); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1662,7 +1666,7 @@ public void TestCachedInstruments() Gauge gauge12 = meter.CreateGauge("name9", null, null, t1); Assert.NotSame(gauge9, gauge12); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1728,7 +1732,7 @@ public void TestInstrumentCreationWithTags() { Assert.True(string.Compare(insArray[i].Key, insArray[i + 1].Key, StringComparison.Ordinal) <= 0); } - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1748,7 +1752,7 @@ public void TestHistogramCreationWithAdvice() Assert.NotNull(histogramWithAdvice.Advice?.HistogramBucketBoundaries); Assert.Equal(explicitBucketBoundaries, histogramWithAdvice.Advice.HistogramBucketBoundaries); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1771,7 +1775,7 @@ public void TestRecordingWithEmptyTagList() counter.Add(1, new TagList(Array.Empty>())); Assert.Equal(4, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } private void PublishCounterMeasurement(Counter counter, T value, KeyValuePair[] tags) where T : struct diff --git a/src/runtime/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/runtime/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 032dc286c46..c82d7803598 100644 --- a/src/runtime/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/runtime/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -442,6 +442,8 @@ Link="Common\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.X509Chain.cs" /> + diff --git a/src/runtime/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs b/src/runtime/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs index 3bd0c7142c3..48ece237432 100644 --- a/src/runtime/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs +++ b/src/runtime/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs @@ -10,41 +10,14 @@ namespace System.Net internal static partial class CertificateValidationPal { internal static SslPolicyErrors VerifyCertificateProperties( - SafeDeleteContext securityContext, + SafeDeleteContext? _ /*securityContext*/, X509Chain chain, - X509Certificate2? remoteCertificate, + X509Certificate2 remoteCertificate, bool checkCertName, bool isServer, string? hostName) { - SslPolicyErrors errors = SslPolicyErrors.None; - - if (remoteCertificate == null) - { - errors |= SslPolicyErrors.RemoteCertificateNotAvailable; - } - else - { - if (!chain.Build(remoteCertificate)) - { - errors |= SslPolicyErrors.RemoteCertificateChainErrors; - } - - if (!isServer && checkCertName) - { - SafeDeleteSslContext sslContext = (SafeDeleteSslContext)securityContext; - - if (!Interop.AppleCrypto.SslCheckHostnameMatch(sslContext.SslContext, hostName!, remoteCertificate.NotBefore, out int osStatus)) - { - errors |= SslPolicyErrors.RemoteCertificateNameMismatch; - - if (NetEventSource.Log.IsEnabled()) - NetEventSource.Error(sslContext, $"Cert name validation for '{hostName}' failed with status '{osStatus}'"); - } - } - } - - return errors; + return CertificateValidation.BuildChainAndVerifyProperties(chain, remoteCertificate, checkCertName, isServer, hostName, Span.Empty); } private static X509Certificate2? GetRemoteCertificate( diff --git a/src/runtime/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs b/src/runtime/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs index a510fedaf47..7bbd1359d04 100644 --- a/src/runtime/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs +++ b/src/runtime/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs @@ -378,7 +378,7 @@ public static IEnumerable HostNameData() yield return new object[] { "test" }; // max allowed hostname length is 63 yield return new object[] { new string('a', 63) }; - yield return new object[] { "\u017C\u00F3\u0142\u0107 g\u0119\u015Bl\u0105 ja\u017A\u0144. \u7EA2\u70E7. \u7167\u308A\u713C\u304D" }; + yield return new object[] { "\u017C\u00F3\u0142\u0107g\u0119\u015Bl\u0105ja\u017A\u0144.\u7EA2\u70E7.\u7167\u308A\u713C\u304D" }; } } } diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs index ba8aa0aff49..fb08996f02f 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs @@ -97,33 +97,7 @@ public ValueTask ConnectAsync(EndPoint remoteEP, CancellationToken cancellationT saea.RemoteEndPoint = remoteEP; - ValueTask connectTask = saea.ConnectAsync(this, saeaCancelable: cancellationToken.CanBeCanceled); - if (connectTask.IsCompleted || !cancellationToken.CanBeCanceled) - { - // Avoid async invocation overhead - return connectTask; - } - else - { - return WaitForConnectWithCancellation(saea, connectTask, cancellationToken); - } - - static async ValueTask WaitForConnectWithCancellation(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken) - { - Debug.Assert(cancellationToken.CanBeCanceled); - try - { - using (cancellationToken.UnsafeRegister(o => CancelConnectAsync((SocketAsyncEventArgs)o!), saea)) - { - await connectTask.ConfigureAwait(false); - } - } - catch (SocketException se) when (se.SocketErrorCode == SocketError.OperationAborted) - { - cancellationToken.ThrowIfCancellationRequested(); - throw; - } - } + return saea.ConnectAsync(this, cancellationToken); } /// @@ -1210,12 +1184,13 @@ public ValueTask SendToAsync(Socket socket, CancellationToken cancellationT ValueTask.FromException(CreateException(error)); } - public ValueTask ConnectAsync(Socket socket, bool saeaCancelable) + public ValueTask ConnectAsync(Socket socket, CancellationToken cancellationToken) { try { - if (socket.ConnectAsync(this, userSocket: true, saeaCancelable: saeaCancelable)) + if (socket.ConnectAsync(this, userSocket: true, saeaMultiConnectCancelable: false, cancellationToken)) { + _cancellationToken = cancellationToken; return new ValueTask(this, _mrvtsc.Version); } } diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index bd7ba1a90b7..369860de37b 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2875,11 +2875,14 @@ private bool AcceptAsync(SocketAsyncEventArgs e, CancellationToken cancellationT } public bool ConnectAsync(SocketAsyncEventArgs e) => - ConnectAsync(e, userSocket: true, saeaCancelable: true); + ConnectAsync(e, userSocket: true, saeaMultiConnectCancelable: true); - internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCancelable) + internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaMultiConnectCancelable, CancellationToken cancellationToken = default) { - bool pending; + // saeaMultiConnectCancelable == true means that this method is being called by a SocketAsyncEventArgs-based top level API. + // In such cases, SocketAsyncEventArgs.StartOperationConnect() will set up an internal cancellation token (_multipleConnectCancellation) + // to support cancelling DNS multi-connect for Socket.CancelConnectAsync(). + Debug.Assert(!saeaMultiConnectCancelable || cancellationToken == default); ThrowIfDisposed(); @@ -2901,6 +2904,7 @@ internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCan EndPoint? endPointSnapshot = e.RemoteEndPoint; DnsEndPoint? dnsEP = endPointSnapshot as DnsEndPoint; + bool pending; if (dnsEP != null) { if (NetEventSource.Log.IsEnabled()) NetEventSource.ConnectedAsyncDns(this); @@ -2911,10 +2915,10 @@ internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCan } e.StartOperationCommon(this, SocketAsyncOperation.Connect); - e.StartOperationConnect(saeaCancelable, userSocket); + e.StartOperationConnect(saeaMultiConnectCancelable, userSocket); try { - pending = e.DnsConnectAsync(dnsEP, default, default); + pending = e.DnsConnectAsync(dnsEP, default, default, cancellationToken); } catch { @@ -2957,8 +2961,8 @@ internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCan // ConnectEx supports connection-oriented sockets but not UDS. The socket must be bound before calling ConnectEx. bool canUseConnectEx = _socketType == SocketType.Stream && endPointSnapshot.AddressFamily != AddressFamily.Unix; SocketError socketError = canUseConnectEx ? - e.DoOperationConnectEx(this, _handle) : - e.DoOperationConnect(_handle); // For connectionless protocols, Connect is not an I/O call. + e.DoOperationConnectEx(this, _handle, cancellationToken) : + e.DoOperationConnect(_handle, cancellationToken); // For connectionless protocols, Connect is not an I/O call. pending = socketError == SocketError.IOPending; } catch (Exception ex) @@ -3001,7 +3005,7 @@ public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType e.StartOperationConnect(saeaMultiConnectCancelable: true, userSocket: false); try { - pending = e.DnsConnectAsync(dnsEP, socketType, protocolType); + pending = e.DnsConnectAsync(dnsEP, socketType, protocolType, cancellationToken: default); } catch { @@ -3012,7 +3016,7 @@ public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType else { Socket attemptSocket = new Socket(endPointSnapshot.AddressFamily, socketType, protocolType); - pending = attemptSocket.ConnectAsync(e, userSocket: false, saeaCancelable: true); + pending = attemptSocket.ConnectAsync(e, userSocket: false, saeaMultiConnectCancelable: true); } return pending; diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs index c517bb70fc4..a5527972a43 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs @@ -1536,7 +1536,7 @@ public SocketError Connect(Memory socketAddress) return operation.ErrorCode; } - public SocketError ConnectAsync(Memory socketAddress, Action, SocketFlags, SocketError> callback, Memory buffer, out int sentBytes) + public SocketError ConnectAsync(Memory socketAddress, Action, SocketFlags, SocketError> callback, Memory buffer, out int sentBytes, CancellationToken cancellationToken) { Debug.Assert(socketAddress.Length > 0, $"Unexpected socketAddressLen: {socketAddress.Length}"); Debug.Assert(callback != null, "Expected non-null callback"); @@ -1574,7 +1574,7 @@ public SocketError ConnectAsync(Memory socketAddress, Action socket CompletionCallback(bytesTransferred, SocketFlags.None, socketError); } - internal SocketError DoOperationConnectEx(Socket _ /*socket*/, SafeSocketHandle handle) + internal SocketError DoOperationConnectEx(Socket _ /*socket*/, SafeSocketHandle handle, CancellationToken cancellationToken) { - SocketError socketError = handle.AsyncContext.ConnectAsync(_socketAddress!.Buffer, ConnectCompletionCallback, _buffer.Slice(_offset, _count), out int sentBytes); + SocketError socketError = handle.AsyncContext.ConnectAsync(_socketAddress!.Buffer, ConnectCompletionCallback, _buffer.Slice(_offset, _count), out int sentBytes, cancellationToken); if (socketError != SocketError.IOPending) { FinishOperationSync(socketError, sentBytes, SocketFlags.None); @@ -81,9 +81,9 @@ internal SocketError DoOperationConnectEx(Socket _ /*socket*/, SafeSocketHandle return socketError; } - internal SocketError DoOperationConnect(SafeSocketHandle handle) + internal SocketError DoOperationConnect(SafeSocketHandle handle, CancellationToken cancellationToken) { - SocketError socketError = handle.AsyncContext.ConnectAsync(_socketAddress!.Buffer, ConnectCompletionCallback, Memory.Empty, out int _); + SocketError socketError = handle.AsyncContext.ConnectAsync(_socketAddress!.Buffer, ConnectCompletionCallback, Memory.Empty, out int _, cancellationToken); if (socketError != SocketError.IOPending) { FinishOperationSync(socketError, 0, SocketFlags.None); diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs index c98d0cede11..a764b070544 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs @@ -285,7 +285,9 @@ internal unsafe SocketError DoOperationAccept(Socket socket, SafeSocketHandle ha } } - internal SocketError DoOperationConnect(SafeSocketHandle handle) +#pragma warning disable IDE0060 + internal SocketError DoOperationConnect(SafeSocketHandle handle, CancellationToken cancellationToken) +#pragma warning restore IDE0060 { // Called for connectionless protocols. SocketError socketError = SocketPal.Connect(handle, _socketAddress!.Buffer); @@ -293,7 +295,7 @@ internal SocketError DoOperationConnect(SafeSocketHandle handle) return socketError; } - internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle handle) + internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle handle, CancellationToken cancellationToken) { Debug.Assert(_asyncCompletionOwnership == 0, $"Expected 0, got {_asyncCompletionOwnership}"); @@ -313,7 +315,7 @@ internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle out int bytesTransferred, overlapped); - return ProcessIOCPResult(success, bytesTransferred, ref overlapped, _buffer, cancellationToken: default); + return ProcessIOCPResult(success, bytesTransferred, ref overlapped, _buffer, cancellationToken); } catch when (overlapped is not null) { diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs index 97f0d016b9d..ac90675f515 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs @@ -676,14 +676,20 @@ internal void FinishOperationAsyncFailure(SocketError socketError, int bytesTran /// The DNS end point to which to connect. /// The SocketType to use to construct new sockets, if necessary. /// The ProtocolType to use to construct new sockets, if necessary. + /// The CancellationToken. /// true if the operation is pending; otherwise, false if it's already completed. - internal bool DnsConnectAsync(DnsEndPoint endPoint, SocketType socketType, ProtocolType protocolType) + internal bool DnsConnectAsync(DnsEndPoint endPoint, SocketType socketType, ProtocolType protocolType, CancellationToken cancellationToken) { Debug.Assert(endPoint.AddressFamily == AddressFamily.Unspecified || endPoint.AddressFamily == AddressFamily.InterNetwork || endPoint.AddressFamily == AddressFamily.InterNetworkV6); - CancellationToken cancellationToken = _multipleConnectCancellation?.Token ?? default; + if (_multipleConnectCancellation is not null) + { + Debug.Assert(!cancellationToken.CanBeCanceled, "Task-based connect logic should not use _multipleConnectCancellation for cancellation."); + // We registered a CancellationTokenSource in StartOperationConnect. + cancellationToken = _multipleConnectCancellation.Token; + } // In .NET 5 and earlier, the APM implementation allowed for synchronous exceptions from this to propagate // synchronously. This call is made here rather than in the Core async method below to preserve that behavior. @@ -774,12 +780,9 @@ async Task Core(MultiConnectSocketAsyncEventArgs internalArgs, Task } // Issue the connect. If it pends, wait for it to complete. - if (attemptSocket.ConnectAsync(internalArgs)) + if (attemptSocket.ConnectAsync(internalArgs, userSocket: true, saeaMultiConnectCancelable: false, cancellationToken)) { - using (cancellationToken.UnsafeRegister(s => Socket.CancelConnectAsync((SocketAsyncEventArgs)s!), internalArgs)) - { - await new ValueTask(internalArgs, internalArgs.Version).ConfigureAwait(false); - } + await new ValueTask(internalArgs, internalArgs.Version).ConfigureAwait(false); } // If it completed successfully, we're done; cleanup will be handled by the finally. diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml b/src/runtime/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml index c0523c4d646..39fc710bc49 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml @@ -29,5 +29,12 @@ M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String) This warning is left in the product so developers get an ILLink warning when trimming an app with System.ComponentModel.DefaultValueAttribute.IsSupported=true. + + ILLink + IL2067 + member + M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String) + This warning is left in the product so developers get an ILLink warning when trimming an app with System.ComponentModel.DefaultValueAttribute.IsSupported=true. + diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs index c890bbed83c..c103bd8fe43 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs @@ -409,7 +409,8 @@ internal ref TValue FindValue(TKey key) if (typeof(TKey).IsValueType && // comparer can only be null for value types; enable JIT to eliminate entire if block for ref types comparer == null) { - uint hashCode = (uint)key.GetHashCode(); + // TODO: Replace with just key.GetHashCode once https://github.com/dotnet/runtime/issues/117521 is resolved. + uint hashCode = (uint)EqualityComparer.Default.GetHashCode(key); int i = GetBucket(hashCode); Entry[]? entries = _entries; uint collisionCount = 0; diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs index 9bc99f7ef4c..ff903b17f07 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs @@ -112,7 +112,7 @@ internal OrdinalIgnoreCaseComparer(IEqualityComparer wrappedComparer) : { } - public override bool Equals(string? x, string? y) => string.EqualsOrdinalIgnoreCase(x, y); + public override bool Equals(string? x, string? y) => string.Equals(x, y, StringComparison.OrdinalIgnoreCase); public override int GetHashCode(string? obj) { diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs index d6d79bb96b9..e613eb8614d 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs @@ -102,7 +102,7 @@ internal OrdinalIgnoreCaseComparer(IEqualityComparer wrappedComparer) string IAlternateEqualityComparer, string?>.Create(ReadOnlySpan span) => span.ToString(); - public override bool Equals(string? x, string? y) => string.EqualsOrdinalIgnoreCase(x, y); + public override bool Equals(string? x, string? y) => string.Equals(x, y, StringComparison.OrdinalIgnoreCase); bool IAlternateEqualityComparer, string?>.Equals(ReadOnlySpan alternate, string? other) { diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs index d10102a1507..12a04b63a5c 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs @@ -33,7 +33,7 @@ public class DefaultValueAttribute : Attribute /// culture as the translation context. /// public DefaultValueAttribute( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, + Type type, string? value) { // The null check and try/catch here are because attributes should never throw exceptions. diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs index 5cabd72975e..c114427965f 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.ComponentModel; + namespace System.Diagnostics.CodeAnalysis { /// @@ -165,6 +167,7 @@ enum DynamicallyAccessedMemberTypes /// /// Specifies all members. /// + [EditorBrowsable(EditorBrowsableState.Never)] All = ~None } } diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs index c607bbb05d5..9df46043178 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs @@ -314,15 +314,22 @@ public int QueryInterface(in Guid riid, out IntPtr ppvObject) } else { - Guid riidLocal = riid; - switch (customQueryInterface.GetInterface(ref riidLocal, out ppvObject)) + try { - case CustomQueryInterfaceResult.Handled: - return HResults.S_OK; - case CustomQueryInterfaceResult.NotHandled: - break; - case CustomQueryInterfaceResult.Failed: - return HResults.COR_E_INVALIDCAST; + Guid riidLocal = riid; + switch (customQueryInterface.GetInterface(ref riidLocal, out ppvObject)) + { + case CustomQueryInterfaceResult.Handled: + return HResults.S_OK; + case CustomQueryInterfaceResult.NotHandled: + break; + case CustomQueryInterfaceResult.Failed: + return HResults.COR_E_INVALIDCAST; + } + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex); } } } diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs index f909cd61615..d725b3d06f6 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs @@ -473,6 +473,85 @@ internal Arm64() { } /// public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Rounding add narrow high part (bottom) + + /// + /// svuint8_t svraddhnb[_u16](svuint16_t op1, svuint16_t op2) + /// RADDHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svraddhnb[_s32](svint32_t op1, svint32_t op2) + /// RADDHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svraddhnb[_s64](svint64_t op1, svint64_t op2) + /// RADDHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svraddhnb[_s16](svint16_t op1, svint16_t op2) + /// RADDHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svraddhnb[_u32](svuint32_t op1, svuint32_t op2) + /// RADDHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svraddhnb[_u64](svuint64_t op1, svuint64_t op2) + /// RADDHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Rounding add narrow high part (top) + + /// + /// svuint8_t svraddhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// RADDHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svraddhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// RADDHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svraddhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// RADDHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svraddhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// RADDHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svraddhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// RADDHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svraddhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// RADDHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Saturating add /// @@ -1166,6 +1245,58 @@ internal Arm64() { } /// public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Rounding halving add + + /// + /// svuint8_t svrhadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// URHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svrhadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// SRHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svrhadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// SRHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svrhadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// SRHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svrhadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// SRHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svrhadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// URHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svrhadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// URHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svrhadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// URHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// Interleaving Xor /// @@ -1265,6 +1396,546 @@ internal Arm64() { } public static Vector InterleavingXorOddEven(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Multiply-add, addend first + + /// + /// svint16_t svmla_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// MLA Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmla_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// MLA Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmla_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// MLA Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmla_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// MLA Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmla_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// MLA Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmla_lane[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_index) + /// MLA Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-add long (bottom) + + /// + /// svint16_t svmlalb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlalb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlalb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmlalb[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlalb[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlalb[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlalb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlalb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlalb_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlalb_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-add long (top) + + /// + /// svint16_t svmlalt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlalt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlalt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmlalt[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlalt[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlalt[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlalt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlalt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlalt_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlalt_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply + + /// + /// svint16_t svmul_lane[_s16](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// MUL Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmul_lane[_s32](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// MUL Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmul_lane[_s64](svint64_t op1, svint64_t op2, uint64_t imm_index) + /// MUL Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmul_lane[_u16](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// MUL Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmul_lane[_u32](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// MUL Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmul_lane[_u64](svuint64_t op1, svuint64_t op2, uint64_t imm_index) + /// MUL Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-subtract, minuend first + + /// + /// svint16_t svmls_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// MLS Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmls_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// MLS Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmls_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// MLS Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmls_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// MLS Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmls_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// MLS Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmls_lane[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_index) + /// MLS Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-subtract long (bottom) + + /// + /// svint16_t svmlslb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlslb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlslb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmlslb[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlslb[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlslb[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlslb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlslb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlslb_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlslb_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-subtract long (top) + + /// + /// svint16_t svmlslt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlslt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlslt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmlslt[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlslt[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlslt[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlslt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlslt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlslt_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlslt_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply long (bottom) + + /// + /// svint16_t svmullb[_s16](svint8_t op1, svint8_t op2) + /// SMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmullb[_s32](svint16_t op1, svint16_t op2) + /// SMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmullb[_s64](svint32_t op1, svint32_t op2) + /// SMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmullb[_u16](svuint8_t op1, svuint8_t op2) + /// UMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmullb[_u32](svuint16_t op1, svuint16_t op2) + /// UMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmullb[_u64](svuint32_t op1, svuint32_t op2) + /// UMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmullb_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmullb_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmullb_lane[_u32](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// UMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmullb_lane[_u64](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// UMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply long (top) + + /// + /// svint16_t svmullt[_s16](svint8_t op1, svint8_t op2) + /// SMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmullt[_s32](svint16_t op1, svint16_t op2) + /// SMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmullt[_s64](svint32_t op1, svint32_t op2) + /// SMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmullt[_u16](svuint8_t op1, svuint8_t op2) + /// UMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmullt[_u32](svuint16_t op1, svuint16_t op2) + /// UMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmullt[_u64](svuint32_t op1, svuint32_t op2) + /// UMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmullt_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmullt_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmullt_lane[_u32](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// UMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmullt_lane[_u64](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// UMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Polynomial multiply + + /// + /// svuint8_t svpmul[_u8](svuint8_t op1, svuint8_t op2) + /// PMUL Zresult.B, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint8_t svpmul[_u8](svuint8_t op1, svuint8_t op2) + /// PMUL Zresult.B, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Polynomial multiply long (bottom) + + /// + /// svuint16_t svpmullb[_u16](svuint8_t op1, svuint8_t op2) + /// PMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svpmullb[_u64](svuint32_t op1, svuint32_t op2) + /// PMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector PolynomialMultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Polynomial multiply long (top) + + /// + /// svuint16_t svpmullt[_u16](svuint8_t op1, svuint8_t op2) + /// PMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svpmullt[_u64](svuint32_t op1, svuint32_t op2) + /// PMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector PolynomialMultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Rounding shift left /// @@ -2198,6 +2869,36 @@ internal Arm64() { } public static Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + // Subtract with borrow long (bottom) + + /// + /// svuint32_t svsbclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// SBCLB Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector SubtractBorrowWideningEven(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsbclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// SBCLB Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector SubtractBorrowWideningEven(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + + // Subtract with borrow long (top) + + /// + /// svuint32_t svsbclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// SBCLT Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector SubtractBorrowWideningOdd(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsbclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// SBCLT Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector SubtractBorrowWideningOdd(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + // Subtract narrow high part (bottom) /// @@ -2276,6 +2977,84 @@ internal Arm64() { } public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Rounding subtract narrow high part (bottom) + + /// + /// svuint8_t svrsubhnb[_u16](svuint16_t op1, svuint16_t op2) + /// RSUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svrsubhnb[_s32](svint32_t op1, svint32_t op2) + /// RSUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svrsubhnb[_s64](svint64_t op1, svint64_t op2) + /// RSUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svrsubhnb[_s16](svint16_t op1, svint16_t op2) + /// RSUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svrsubhnb[_u32](svuint32_t op1, svuint32_t op2) + /// RSUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svrsubhnb[_u64](svuint64_t op1, svuint64_t op2) + /// RSUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Rounding subtract narrow high part (top) + + /// + /// svuint8_t svrsubhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// RSUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svrsubhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// RSUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svrsubhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// RSUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svrsubhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// RSUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svrsubhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// RSUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svrsubhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// RSUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Saturating subtract /// @@ -2367,97 +3146,6 @@ internal Arm64() { } public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - // Saturating subtract reversed - - /// - /// svuint8_t svqsubr[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// svuint8_t svqsubr[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// svuint8_t svqsubr[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// UQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// UQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// UQSUB Ztied2.B, Pg/M, Ztied2.B, Zop1.B - /// UQSUB Zresult.B, Zop2.B, Zop1.B - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint16_t svqsubr[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) - /// svint16_t svqsubr[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) - /// svint16_t svqsubr[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) - /// SQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// SQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// SQSUB Ztied2.H, Pg/M, Ztied2.H, Zop1.H - /// SQSUB Zresult.H, Zop2.H, Zop1.H - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint32_t svqsubr[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) - /// svint32_t svqsubr[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) - /// svint32_t svqsubr[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) - /// SQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// SQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// SQSUB Ztied2.S, Pg/M, Ztied2.S, Zop1.S - /// SQSUB Zresult.S, Zop2.S, Zop1.S - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint64_t svqsubr[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) - /// svint64_t svqsubr[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) - /// svint64_t svqsubr[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) - /// SQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// SQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// SQSUB Ztied2.D, Pg/M, Ztied2.D, Zop1.D - /// SQSUB Zresult.D, Zop2.D, Zop1.D - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint8_t svqsubr[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) - /// svint8_t svqsubr[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) - /// svint8_t svqsubr[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) - /// SQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// SQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// SQSUB Ztied2.B, Pg/M, Ztied2.B, Zop1.B - /// SQSUB Zresult.B, Zop2.B, Zop1.B - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint16_t svqsubr[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// svuint16_t svqsubr[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// svuint16_t svqsubr[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// UQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// UQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// UQSUB Ztied2.H, Pg/M, Ztied2.H, Zop1.H - /// UQSUB Zresult.H, Zop2.H, Zop1.H - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint32_t svqsubr[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// svuint32_t svqsubr[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// svuint32_t svqsubr[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// UQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// UQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// UQSUB Ztied2.S, Pg/M, Ztied2.S, Zop1.S - /// UQSUB Zresult.S, Zop2.S, Zop1.S - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svqsubr[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// svuint64_t svqsubr[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// svuint64_t svqsubr[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// UQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// UQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// UQSUB Ztied2.D, Pg/M, Ztied2.D, Zop1.D - /// UQSUB Zresult.D, Zop2.D, Zop1.D - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - // Subtract wide (bottom) /// @@ -2656,36 +3344,6 @@ internal Arm64() { } public static Vector SubtractWideningOddEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - // Subtract with borrow long (bottom) - - /// - /// svuint32_t svsbclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) - /// SBCLB Ztied1.S, Zop2.S, Zop3.S - /// - public static Vector SubtractWithBorrowWideningLower(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svsbclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) - /// SBCLB Ztied1.D, Zop2.D, Zop3.D - /// - public static Vector SubtractWithBorrowWideningLower(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } - - - // Subtract with borrow long (top) - - /// - /// svuint32_t svsbclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) - /// SBCLT Ztied1.S, Zop2.S, Zop3.S - /// - public static Vector SubtractWithBorrowWideningUpper(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svsbclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) - /// SBCLT Ztied1.D, Zop2.D, Zop3.D - /// - public static Vector SubtractWithBorrowWideningUpper(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } - - // Bit vector table lookups /// diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs index bab0e4e55dd..542c142c54c 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs @@ -473,6 +473,84 @@ internal Arm64() { } public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) => AddPairwiseWideningAndAdd(left, right); + // Rounding add narrow high part (bottom) + + /// + /// svuint8_t svraddhnb[_u16](svuint16_t op1, svuint16_t op2) + /// RADDHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svint16_t svraddhnb[_s32](svint32_t op1, svint32_t op2) + /// RADDHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svint32_t svraddhnb[_s64](svint64_t op1, svint64_t op2) + /// RADDHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svint8_t svraddhnb[_s16](svint16_t op1, svint16_t op2) + /// RADDHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svuint16_t svraddhnb[_u32](svuint32_t op1, svuint32_t op2) + /// RADDHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svuint32_t svraddhnb[_u64](svuint64_t op1, svuint64_t op2) + /// RADDHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + + // Rounding add narrow high part (top) + + /// + /// svuint8_t svraddhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// RADDHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint16_t svraddhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// RADDHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint32_t svraddhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// RADDHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint8_t svraddhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// RADDHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svuint16_t svraddhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// RADDHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svuint32_t svraddhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// RADDHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + // Saturating add /// @@ -1166,6 +1244,58 @@ internal Arm64() { } /// public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + // Rounding halving add + + /// + /// svuint8_t svrhadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// URHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svint16_t svrhadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// SRHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svint32_t svrhadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// SRHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svint64_t svrhadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// SRHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svint8_t svrhadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// SRHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svuint16_t svrhadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// URHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svuint32_t svrhadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// URHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svuint64_t svrhadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// URHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// Interleaving Xor /// @@ -1265,6 +1395,546 @@ internal Arm64() { } public static Vector InterleavingXorOddEven(Vector even, Vector left, Vector right) => InterleavingXorOddEven(even, left, right); + // Multiply-add, addend first + + /// + /// svint16_t svmla_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// MLA Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svint32_t svmla_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// MLA Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svint64_t svmla_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// MLA Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svuint16_t svmla_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// MLA Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svuint32_t svmla_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// MLA Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svuint64_t svmla_lane[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_index) + /// MLA Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + + // Multiply-add long (bottom) + + /// + /// svint16_t svmlalb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svint32_t svmlalb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svint64_t svmlalb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svuint16_t svmlalb[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svuint32_t svmlalb[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svuint64_t svmlalb[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svint32_t svmlalb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndAdd(addend, left, right, rightIndex); + + /// + /// svint64_t svmlalb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndAdd(addend, left, right, rightIndex); + + /// + /// svuint32_t svmlalb_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndAdd(addend, left, right, rightIndex); + + /// + /// svuint64_t svmlalb_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndAdd(addend, left, right, rightIndex); + + + // Multiply-add long (top) + + /// + /// svint16_t svmlalt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svint32_t svmlalt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svint64_t svmlalt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svuint16_t svmlalt[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svuint32_t svmlalt[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svuint64_t svmlalt[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svint32_t svmlalt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndAdd(addend, left, right, rightIndex); + + /// + /// svint64_t svmlalt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndAdd(addend, left, right, rightIndex); + + /// + /// svuint32_t svmlalt_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndAdd(addend, left, right, rightIndex); + + /// + /// svuint64_t svmlalt_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndAdd(addend, left, right, rightIndex); + + + // Multiply + + /// + /// svint16_t svmul_lane[_s16](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// MUL Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svint32_t svmul_lane[_s32](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// MUL Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svint64_t svmul_lane[_s64](svint64_t op1, svint64_t op2, uint64_t imm_index) + /// MUL Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svuint16_t svmul_lane[_u16](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// MUL Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svuint32_t svmul_lane[_u32](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// MUL Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svuint64_t svmul_lane[_u64](svuint64_t op1, svuint64_t op2, uint64_t imm_index) + /// MUL Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + + // Multiply-subtract, minuend first + + /// + /// svint16_t svmls_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// MLS Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svint32_t svmls_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// MLS Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svint64_t svmls_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// MLS Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svuint16_t svmls_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// MLS Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svuint32_t svmls_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// MLS Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svuint64_t svmls_lane[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_index) + /// MLS Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + + // Multiply-subtract long (bottom) + + /// + /// svint16_t svmlslb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svint32_t svmlslb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svint64_t svmlslb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svuint16_t svmlslb[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svuint32_t svmlslb[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svuint64_t svmlslb[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svint32_t svmlslb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndSubtract(minuend, left, right, rightIndex); + + /// + /// svint64_t svmlslb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndSubtract(minuend, left, right, rightIndex); + + /// + /// svuint32_t svmlslb_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndSubtract(minuend, left, right, rightIndex); + + /// + /// svuint64_t svmlslb_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndSubtract(minuend, left, right, rightIndex); + + + // Multiply-subtract long (top) + + /// + /// svint16_t svmlslt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svint32_t svmlslt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svint64_t svmlslt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svuint16_t svmlslt[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svuint32_t svmlslt[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svuint64_t svmlslt[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svint32_t svmlslt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndSubtract(minuend, left, right, rightIndex); + + /// + /// svint64_t svmlslt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndSubtract(minuend, left, right, rightIndex); + + /// + /// svuint32_t svmlslt_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndSubtract(minuend, left, right, rightIndex); + + /// + /// svuint64_t svmlslt_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndSubtract(minuend, left, right, rightIndex); + + + // Multiply long (bottom) + + /// + /// svint16_t svmullb[_s16](svint8_t op1, svint8_t op2) + /// SMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svint32_t svmullb[_s32](svint16_t op1, svint16_t op2) + /// SMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svint64_t svmullb[_s64](svint32_t op1, svint32_t op2) + /// SMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svuint16_t svmullb[_u16](svuint8_t op1, svuint8_t op2) + /// UMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svuint32_t svmullb[_u32](svuint16_t op1, svuint16_t op2) + /// UMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svuint64_t svmullb[_u64](svuint32_t op1, svuint32_t op2) + /// UMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svint32_t svmullb_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEven(left, right, rightIndex); + + /// + /// svint64_t svmullb_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEven(left, right, rightIndex); + + /// + /// svuint32_t svmullb_lane[_u32](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// UMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEven(left, right, rightIndex); + + /// + /// svuint64_t svmullb_lane[_u64](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// UMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEven(left, right, rightIndex); + + + // Multiply long (top) + + /// + /// svint16_t svmullt[_s16](svint8_t op1, svint8_t op2) + /// SMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svint32_t svmullt[_s32](svint16_t op1, svint16_t op2) + /// SMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svint64_t svmullt[_s64](svint32_t op1, svint32_t op2) + /// SMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svuint16_t svmullt[_u16](svuint8_t op1, svuint8_t op2) + /// UMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svuint32_t svmullt[_u32](svuint16_t op1, svuint16_t op2) + /// UMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svuint64_t svmullt[_u64](svuint32_t op1, svuint32_t op2) + /// UMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svint32_t svmullt_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOdd(left, right, rightIndex); + + /// + /// svint64_t svmullt_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOdd(left, right, rightIndex); + + /// + /// svuint32_t svmullt_lane[_u32](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// UMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOdd(left, right, rightIndex); + + /// + /// svuint64_t svmullt_lane[_u64](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// UMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOdd(left, right, rightIndex); + + + // Polynomial multiply + + /// + /// svuint8_t svpmul[_u8](svuint8_t op1, svuint8_t op2) + /// PMUL Zresult.B, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiply(Vector left, Vector right) => PolynomialMultiply(left, right); + + /// + /// svuint8_t svpmul[_u8](svuint8_t op1, svuint8_t op2) + /// PMUL Zresult.B, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiply(Vector left, Vector right) => PolynomialMultiply(left, right); + + + // Polynomial multiply long (bottom) + + /// + /// svuint16_t svpmullb[_u16](svuint8_t op1, svuint8_t op2) + /// PMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiplyWideningEven(Vector left, Vector right) => PolynomialMultiplyWideningEven(left, right); + + /// + /// svuint64_t svpmullb[_u64](svuint32_t op1, svuint32_t op2) + /// PMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector PolynomialMultiplyWideningEven(Vector left, Vector right) => PolynomialMultiplyWideningEven(left, right); + + + // Polynomial multiply long (top) + + /// + /// svuint16_t svpmullt[_u16](svuint8_t op1, svuint8_t op2) + /// PMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiplyWideningOdd(Vector left, Vector right) => PolynomialMultiplyWideningOdd(left, right); + + /// + /// svuint64_t svpmullt[_u64](svuint32_t op1, svuint32_t op2) + /// PMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector PolynomialMultiplyWideningOdd(Vector left, Vector right) => PolynomialMultiplyWideningOdd(left, right); + + // Rounding shift left /// @@ -2198,6 +2868,36 @@ internal Arm64() { } public static Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) => ShiftRightLogicalRoundedNarrowingSaturateOdd(even, value, count); + // Subtract with borrow long (bottom) + + /// + /// svuint32_t svsbclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// SBCLB Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector SubtractBorrowWideningEven(Vector op1, Vector op2, Vector op3) => SubtractBorrowWideningEven(op1, op2, op3); + + /// + /// svuint64_t svsbclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// SBCLB Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector SubtractBorrowWideningEven(Vector op1, Vector op2, Vector op3) => SubtractBorrowWideningEven(op1, op2, op3); + + + // Subtract with borrow long (top) + + /// + /// svuint32_t svsbclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// SBCLT Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector SubtractBorrowWideningOdd(Vector op1, Vector op2, Vector op3) => SubtractBorrowWideningOdd(op1, op2, op3); + + /// + /// svuint64_t svsbclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// SBCLT Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector SubtractBorrowWideningOdd(Vector op1, Vector op2, Vector op3) => SubtractBorrowWideningOdd(op1, op2, op3); + + // Subtract narrow high part (bottom) /// @@ -2276,6 +2976,84 @@ internal Arm64() { } public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractHighNarrowingOdd(even, left, right); + // Rounding subtract narrow high part (bottom) + + /// + /// svuint8_t svrsubhnb[_u16](svuint16_t op1, svuint16_t op2) + /// RSUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svint16_t svrsubhnb[_s32](svint32_t op1, svint32_t op2) + /// RSUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svint32_t svrsubhnb[_s64](svint64_t op1, svint64_t op2) + /// RSUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svint8_t svrsubhnb[_s16](svint16_t op1, svint16_t op2) + /// RSUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svuint16_t svrsubhnb[_u32](svuint32_t op1, svuint32_t op2) + /// RSUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svuint32_t svrsubhnb[_u64](svuint64_t op1, svuint64_t op2) + /// RSUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + + // Rounding subtract narrow high part (top) + + /// + /// svuint8_t svrsubhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// RSUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint16_t svrsubhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// RSUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint32_t svrsubhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// RSUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint8_t svrsubhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// RSUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svuint16_t svrsubhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// RSUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svuint32_t svrsubhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// RSUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + // Saturating subtract /// @@ -2367,97 +3145,6 @@ internal Arm64() { } public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); - // Saturating subtract reversed - - /// - /// svuint8_t svqsubr[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// svuint8_t svqsubr[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// svuint8_t svqsubr[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// UQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// UQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// UQSUB Ztied2.B, Pg/M, Ztied2.B, Zop1.B - /// UQSUB Zresult.B, Zop2.B, Zop1.B - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svint16_t svqsubr[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) - /// svint16_t svqsubr[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) - /// svint16_t svqsubr[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) - /// SQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// SQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// SQSUB Ztied2.H, Pg/M, Ztied2.H, Zop1.H - /// SQSUB Zresult.H, Zop2.H, Zop1.H - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svint32_t svqsubr[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) - /// svint32_t svqsubr[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) - /// svint32_t svqsubr[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) - /// SQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// SQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// SQSUB Ztied2.S, Pg/M, Ztied2.S, Zop1.S - /// SQSUB Zresult.S, Zop2.S, Zop1.S - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svint64_t svqsubr[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) - /// svint64_t svqsubr[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) - /// svint64_t svqsubr[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) - /// SQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// SQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// SQSUB Ztied2.D, Pg/M, Ztied2.D, Zop1.D - /// SQSUB Zresult.D, Zop2.D, Zop1.D - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svint8_t svqsubr[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) - /// svint8_t svqsubr[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) - /// svint8_t svqsubr[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) - /// SQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// SQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// SQSUB Ztied2.B, Pg/M, Ztied2.B, Zop1.B - /// SQSUB Zresult.B, Zop2.B, Zop1.B - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svuint16_t svqsubr[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// svuint16_t svqsubr[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// svuint16_t svqsubr[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// UQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// UQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// UQSUB Ztied2.H, Pg/M, Ztied2.H, Zop1.H - /// UQSUB Zresult.H, Zop2.H, Zop1.H - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svuint32_t svqsubr[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// svuint32_t svqsubr[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// svuint32_t svqsubr[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// UQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// UQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// UQSUB Ztied2.S, Pg/M, Ztied2.S, Zop1.S - /// UQSUB Zresult.S, Zop2.S, Zop1.S - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svuint64_t svqsubr[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// svuint64_t svqsubr[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// svuint64_t svqsubr[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// UQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// UQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// UQSUB Ztied2.D, Pg/M, Ztied2.D, Zop1.D - /// UQSUB Zresult.D, Zop2.D, Zop1.D - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - // Subtract wide (bottom) /// @@ -2656,36 +3343,6 @@ internal Arm64() { } public static Vector SubtractWideningOddEven(Vector left, Vector right) => SubtractWideningOddEven(left, right); - // Subtract with borrow long (bottom) - - /// - /// svuint32_t svsbclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) - /// SBCLB Ztied1.S, Zop2.S, Zop3.S - /// - public static Vector SubtractWithBorrowWideningLower(Vector op1, Vector op2, Vector op3) => SubtractWithBorrowWideningLower(op1, op2, op3); - - /// - /// svuint64_t svsbclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) - /// SBCLB Ztied1.D, Zop2.D, Zop3.D - /// - public static Vector SubtractWithBorrowWideningLower(Vector op1, Vector op2, Vector op3) => SubtractWithBorrowWideningLower(op1, op2, op3); - - - // Subtract with borrow long (top) - - /// - /// svuint32_t svsbclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) - /// SBCLT Ztied1.S, Zop2.S, Zop3.S - /// - public static Vector SubtractWithBorrowWideningUpper(Vector op1, Vector op2, Vector op3) => SubtractWithBorrowWideningUpper(op1, op2, op3); - - /// - /// svuint64_t svsbclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) - /// SBCLT Ztied1.D, Zop2.D, Zop3.D - /// - public static Vector SubtractWithBorrowWideningUpper(Vector op1, Vector op2, Vector op3) => SubtractWithBorrowWideningUpper(op1, op2, op3); - - // Bit vector table lookups /// diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs index f9261106b34..458aa815cd6 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs @@ -46,26 +46,6 @@ ref Unsafe.Add(ref strA.GetRawStringData(), (nint)(uint)indexA /* force zero-ext ref Unsafe.Add(ref strB.GetRawStringData(), (nint)(uint)indexB /* force zero-extension */), countB); } - internal static bool EqualsOrdinalIgnoreCase(string? strA, string? strB) - { - if (ReferenceEquals(strA, strB)) - { - return true; - } - - if (strA is null || strB is null) - { - return false; - } - - if (strA.Length != strB.Length) - { - return false; - } - - return EqualsOrdinalIgnoreCaseNoLengthCheck(strA, strB); - } - private static bool EqualsOrdinalIgnoreCaseNoLengthCheck(string strA, string strB) { Debug.Assert(strA.Length == strB.Length); diff --git a/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 17378d29ec3..cc1757f072f 100644 --- a/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -6177,7 +6177,18 @@ internal Arm64() { } public static System.Numerics.Vector AddPairwiseWideningAndAdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddPairwiseWideningAndAdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddPairwiseWideningAndAdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6253,6 +6264,14 @@ internal Arm64() { } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6285,6 +6304,90 @@ internal Arm64() { } public static System.Numerics.Vector InterleavingXorOddEven(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorOddEven(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorOddEven(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEven(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEven(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEven(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEven(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ShiftArithmeticRounded(System.Numerics.Vector value, System.Numerics.Vector count) { throw null; } public static System.Numerics.Vector ShiftArithmeticRounded(System.Numerics.Vector value, System.Numerics.Vector count) { throw null; } public static System.Numerics.Vector ShiftArithmeticRounded(System.Numerics.Vector value, System.Numerics.Vector count) { throw null; } @@ -6425,6 +6528,10 @@ internal Arm64() { } public static System.Numerics.Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } + public static System.Numerics.Vector SubtractBorrowWideningEven(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector SubtractBorrowWideningEven(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector SubtractBorrowWideningOdd(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector SubtractBorrowWideningOdd(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6437,14 +6544,18 @@ internal Arm64() { } public static System.Numerics.Vector SubtractHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector SubtractSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector SubtractSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector SubtractSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6483,10 +6594,6 @@ internal Arm64() { } public static System.Numerics.Vector SubtractWideningOddEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractWideningOddEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractWideningOddEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractWithBorrowWideningLower(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } - public static System.Numerics.Vector SubtractWithBorrowWideningLower(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } - public static System.Numerics.Vector SubtractWithBorrowWideningUpper(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } - public static System.Numerics.Vector SubtractWithBorrowWideningUpper(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } public static System.Numerics.Vector VectorTableLookup((System.Numerics.Vector data1, System.Numerics.Vector data2) table, System.Numerics.Vector indices) { throw null; } public static System.Numerics.Vector VectorTableLookup((System.Numerics.Vector data1, System.Numerics.Vector data2) table, System.Numerics.Vector indices) { throw null; } public static System.Numerics.Vector VectorTableLookup((System.Numerics.Vector data1, System.Numerics.Vector data2) table, System.Numerics.Vector indices) { throw null; } diff --git a/src/runtime/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs b/src/runtime/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs index ff0f1b694c0..069cc8c481a 100644 --- a/src/runtime/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs +++ b/src/runtime/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs @@ -13,7 +13,7 @@ namespace LoaderLinkTest { public class LoaderLinkTest { - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] public static void EnsureTypesLinked() // https://github.com/dotnet/runtime/issues/42207 { string parentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); diff --git a/src/runtime/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs b/src/runtime/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs index 4f5e6265135..e00166fa0be 100644 --- a/src/runtime/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs +++ b/src/runtime/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs @@ -74,7 +74,7 @@ public static IEnumerable MainResources_TestData() } } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] [MemberData(nameof(MainResources_TestData))] public static void mainResources(string lang, string expected) { @@ -131,7 +131,7 @@ public static IEnumerable DescribeLib_TestData() yield return new object[] { "ReferencedClassLibNeutralIsSatellite", "ReferencedClassLibNeutralIsSatellite.Program, ReferencedClassLibNeutralIsSatellite", "es", "Neutral (es) language ReferencedClassLibNeutralIsSatellite description 1.0.0" }; } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.HasAssemblyFiles))] [MemberData(nameof(DescribeLib_TestData))] public void describeLib(string alc, string type, string culture, string expected) { @@ -187,7 +187,7 @@ public static IEnumerable SatelliteLoadsCorrectly_TestData() yield return new object[] { "ReferencedClassLibNeutralIsSatellite", "ReferencedClassLibNeutralIsSatellite", "es" }; } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.HasAssemblyFiles))] [MemberData(nameof(SatelliteLoadsCorrectly_TestData))] public void SatelliteLoadsCorrectly_FromName(string alc, string assemblyName, string culture) { @@ -207,8 +207,8 @@ public void SatelliteLoadsCorrectly_FromName(string alc, string assemblyName, st Assert.Equal(culture, satelliteAssembly.GetName().CultureName); } - - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.HasAssemblyFiles))] [MemberData(nameof(SatelliteLoadsCorrectly_TestData))] public void SatelliteLoadsCorrectly_FromPath(string alc, string assemblyName, string culture) { diff --git a/src/runtime/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/runtime/src/libraries/System.Runtime/ref/System.Runtime.cs index 8ba41f11d65..e27c05b00e3 100644 --- a/src/runtime/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/runtime/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8552,7 +8552,7 @@ public DefaultValueAttribute(object? value) { } public DefaultValueAttribute(sbyte value) { } public DefaultValueAttribute(float value) { } public DefaultValueAttribute(string? value) { } - public DefaultValueAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type type, string? value) { } + public DefaultValueAttribute(System.Type type, string? value) { } [System.CLSCompliantAttribute(false)] public DefaultValueAttribute(ushort value) { } [System.CLSCompliantAttribute(false)] @@ -8894,6 +8894,7 @@ public DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.Dynam [System.FlagsAttribute] public enum DynamicallyAccessedMemberTypes { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] All = -1, None = 0, PublicParameterlessConstructor = 1, diff --git a/src/runtime/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/runtime/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index 5e945c446a2..81bfc96492b 100644 --- a/src/runtime/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/runtime/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -3386,6 +3386,7 @@ public sealed partial class Pkcs12LoaderLimits { public Pkcs12LoaderLimits() { } public Pkcs12LoaderLimits(System.Security.Cryptography.X509Certificates.Pkcs12LoaderLimits copyFrom) { } + public bool AllowDuplicateAttributes { get { throw null; } set { } } public static System.Security.Cryptography.X509Certificates.Pkcs12LoaderLimits DangerousNoLimits { get { throw null; } } public static System.Security.Cryptography.X509Certificates.Pkcs12LoaderLimits Defaults { get { throw null; } } public bool IgnoreEncryptedAuthSafes { get { throw null; } set { } } diff --git a/src/runtime/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/runtime/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index d6a1cb9bd20..88f15f22fa5 100644 --- a/src/runtime/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/runtime/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -411,6 +411,9 @@ The specified hash is not a valid size for this hash algorithm. + + HashML-DSA '{0}' cannot be used with hash algorithm '{1}'. + Hash must be finalized before the hash value is retrieved. diff --git a/src/runtime/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml b/src/runtime/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml index 24e10dd2564..a0d092eccf4 100644 --- a/src/runtime/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml +++ b/src/runtime/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml @@ -229,6 +229,24 @@ net9.0/System.Runtime.Intrinsics.dll net10.0/System.Runtime.Intrinsics.dll + + CP0014 + M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + net9.0/netstandard.dll + net10.0/netstandard.dll + + + CP0014 + M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + net9.0/System.dll + net10.0/System.dll + + + CP0014 + M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + net9.0/System.Runtime.dll + net10.0/System.Runtime.dll + CP0015 M:System.Delegate.#ctor(System.Type,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] diff --git a/src/runtime/src/libraries/tests.proj b/src/runtime/src/libraries/tests.proj index a2b63c15130..4b6c7c027c1 100644 --- a/src/runtime/src/libraries/tests.proj +++ b/src/runtime/src/libraries/tests.proj @@ -226,16 +226,15 @@ - - - + + @@ -602,8 +601,7 @@ - - + diff --git a/src/runtime/src/mono/mono.proj b/src/runtime/src/mono/mono.proj index 2cb4ba6ffec..e0fa813eb20 100644 --- a/src/runtime/src/mono/mono.proj +++ b/src/runtime/src/mono/mono.proj @@ -953,6 +953,14 @@ JS_ENGINES = [NODE_JS] <_MonoAOTCFLAGSOption>-DCMAKE_C_FLAGS="@(_MonoAOTCPPFLAGS, ' ') @(_MonoAOTCFLAGS, ' ')" <_MonoAOTCXXFLAGSOption>-DCMAKE_CXX_FLAGS="@(_MonoAOTCPPFLAGS, ' ') @(_MonoAOTCXXFLAGS, ' ')" + + + <_PythonCmd Condition="'$(HostOS)' != 'windows'">python3 + <_PythonCmd Condition="'$(HostOS)' == 'windows'">python + + <_PythonCmd Condition="'$(HostOS)' == 'windows' and ('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true')">$([MSBuild]::NormalizePath('$(PkgMicrosoft_NET_Runtime_Emscripten_3_1_56_Python_win-x64)', 'tools', 'python.exe')) + + @@ -975,15 +983,12 @@ JS_ENGINES = [NODE_JS] + <_MonoSkipInitCompiler Condition="'$(AotHostArchitecture)' != '$(BuildArchitecture)'">false <_MonoSkipInitCompiler Condition="'$(CrossBuild)' == 'true'">false - <_PythonCmd Condition="'$(HostOS)' != 'windows'">python3 - <_PythonCmd Condition="'$(HostOS)' == 'windows'">python - - <_PythonCmd Condition="'$(HostOS)' == 'windows' and ('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true')">$([MSBuild]::NormalizePath('$(PkgMicrosoft_NET_Runtime_Emscripten_3_1_56_Python_win-x64)', 'tools', 'python.exe')) <_MonoAotCrossOffsetsToolPath>$(MonoProjectRoot)mono\offsets\offsets-tool.py <_MonoAotCrossOffsetsCommand Condition="'$(MonoUseCrossTool)' == 'true'">$(_PythonCmd) $(_MonoAotCrossOffsetsToolPath) @(MonoAotCrossOffsetsToolParams, ' ') <_MonoAotCMakeConfigureCommand>cmake @(MonoAOTCMakeArgs, ' ') $(MonoCMakeExtraArgs) "$(MonoProjectRoot.TrimEnd('\/'))" diff --git a/src/runtime/src/mono/mono/mini/CMakeLists.txt b/src/runtime/src/mono/mono/mini/CMakeLists.txt index a2b3bdae9a7..23b8d15bf70 100644 --- a/src/runtime/src/mono/mono/mini/CMakeLists.txt +++ b/src/runtime/src/mono/mono/mini/CMakeLists.txt @@ -4,7 +4,7 @@ if(ENABLE_LLVM OR ENABLE_LLVM_RUNTIME OR HOST_BROWSER) enable_language(CXX) endif() -include(FindPython3) +include(FindPython) include_directories( ${PROJECT_BINARY_DIR}/ @@ -494,60 +494,60 @@ if(HOST_BROWSER OR HOST_WASI OR TARGET_WASM) install(TARGETS mono-wasm-nosimd LIBRARY) endif() -find_package(Python3 COMPONENTS Interpreter) +find_package(Python COMPONENTS Interpreter) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-amd64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_AMD64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-amd64.h amd64_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-amd64.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_AMD64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-amd64.h amd64_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-amd64.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-amd64.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-x86.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_X86 ${CMAKE_CURRENT_SOURCE_DIR} cpu-x86.h x86_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-x86.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_X86 ${CMAKE_CURRENT_SOURCE_DIR} cpu-x86.h x86_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-x86.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-x86.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-arm64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_ARM64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-arm64.h arm64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm64.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_ARM64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-arm64.h arm64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm64.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm64.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-arm.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_ARM ${CMAKE_CURRENT_SOURCE_DIR} cpu-arm.h arm_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_ARM ${CMAKE_CURRENT_SOURCE_DIR} cpu-arm.h arm_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-riscv64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_RISCV64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-riscv64.h riscv64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-riscv64.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_RISCV64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-riscv64.h riscv64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-riscv64.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-riscv64.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-s390x.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_S390X ${CMAKE_CURRENT_SOURCE_DIR} cpu-s390x.h s390x_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-s390x.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_S390X ${CMAKE_CURRENT_SOURCE_DIR} cpu-s390x.h s390x_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-s390x.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-s390x.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-wasm.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_WASM ${CMAKE_CURRENT_SOURCE_DIR} cpu-wasm.h wasm_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-wasm.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_WASM ${CMAKE_CURRENT_SOURCE_DIR} cpu-wasm.h wasm_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-wasm.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-wasm.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-ppc64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_POWERPC64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-ppc64.h ppc64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-ppc64.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_POWERPC64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-ppc64.h ppc64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-ppc64.mdesc VERBATIM ) diff --git a/src/runtime/src/mono/msbuild/android/build/AndroidBuild.targets b/src/runtime/src/mono/msbuild/android/build/AndroidBuild.targets index 56dd94a5983..886e99635a3 100644 --- a/src/runtime/src/mono/msbuild/android/build/AndroidBuild.targets +++ b/src/runtime/src/mono/msbuild/android/build/AndroidBuild.targets @@ -251,6 +251,7 @@ ForceAOT="$(RunAOTCompilation)" ForceFullAOT="$(ForceFullAOT)" ForceInterpreter="$(MonoForceInterpreter)" + InvariantGlobalization="$(InvariantGlobalization)" IsLibraryMode="$(_IsLibraryMode)" MainLibraryFileName="$(MainLibraryFileName)" RuntimeHeaders="@(RuntimeHeaders)" diff --git a/src/runtime/src/native/corehost/apphost/static/CMakeLists.txt b/src/runtime/src/native/corehost/apphost/static/CMakeLists.txt index 30118f679da..7d7d975d4bd 100644 --- a/src/runtime/src/native/corehost/apphost/static/CMakeLists.txt +++ b/src/runtime/src/native/corehost/apphost/static/CMakeLists.txt @@ -166,10 +166,11 @@ else() ) if(NOT CLR_CMAKE_TARGET_ANDROID) - list(APPEND NATIVE_LIBS - System.Net.Security.Native-Static - System.Security.Cryptography.Native.OpenSsl-Static - ) + list(APPEND NATIVE_LIBS System.Net.Security.Native-Static) + + if(NOT CLR_CMAKE_TARGET_APPLE) + list(APPEND NATIVE_LIBS System.Security.Cryptography.Native.OpenSsl-Static) + endif() else() list(APPEND NATIVE_LIBS System.Security.Cryptography.Native.Android-Static @@ -204,7 +205,7 @@ else() include(${CLR_SRC_NATIVE_DIR}/libs/System.Native/extra_libs.cmake) append_extra_system_libs(NATIVE_LIBS) - if(NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) + if(NOT CLR_CMAKE_TARGET_APPLE AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) # Additional requirements for System.Security.Cryptography.Native.OpenSsl include(${CLR_SRC_NATIVE_DIR}/libs/System.Security.Cryptography.Native/extra_libs.cmake) append_extra_cryptography_libs(NATIVE_LIBS) diff --git a/src/runtime/src/native/corehost/build.sh b/src/runtime/src/native/corehost/build.sh index b7df4cc8212..63c3b6d996e 100755 --- a/src/runtime/src/native/corehost/build.sh +++ b/src/runtime/src/native/corehost/build.sh @@ -60,7 +60,10 @@ __IntermediatesDir="$__RootBinDir/obj/$__TargetRid.$__BuildType" export __BinDir __IntermediatesDir __RuntimeFlavor __CMakeArgs="-DCLI_CMAKE_PKG_RID=\"$__TargetRid\" -DCLI_CMAKE_FALLBACK_OS=\"$__HostFallbackOS\" -DCLI_CMAKE_COMMIT_HASH=\"$__commit_hash\" $__CMakeArgs" -__CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs" + +if [[ "$__TargetOS" != osx ]]; then + __CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs" +fi # Specify path to be set for CMAKE_INSTALL_PREFIX. # This is where all built CoreClr libraries will copied to. diff --git a/src/runtime/src/native/corehost/hostpolicy/hostpolicy_context.cpp b/src/runtime/src/native/corehost/hostpolicy/hostpolicy_context.cpp index b562d0e09ae..9c0c7c0468d 100644 --- a/src/runtime/src/native/corehost/hostpolicy/hostpolicy_context.cpp +++ b/src/runtime/src/native/corehost/hostpolicy/hostpolicy_context.cpp @@ -70,11 +70,13 @@ namespace return SystemResolveDllImport(entry_point_name); } +#if !defined(TARGET_OSX) if (strcmp(library_name, LIB_NAME("System.Security.Cryptography.Native.OpenSsl")) == 0) { return CryptoResolveDllImport(entry_point_name); } -#endif +#endif // !defined(TARGET_OSX) +#endif // !defined(_WIN32) if (strcmp(library_name, LIB_NAME("System.IO.Compression.Native")) == 0) { diff --git a/src/runtime/src/native/external/llvm-libunwind/include/__libunwind_config.h b/src/runtime/src/native/external/llvm-libunwind/include/__libunwind_config.h index 35e5a73de03..ec56ded7e28 100644 --- a/src/runtime/src/native/external/llvm-libunwind/include/__libunwind_config.h +++ b/src/runtime/src/native/external/llvm-libunwind/include/__libunwind_config.h @@ -42,7 +42,7 @@ # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 # define _LIBUNWIND_CONTEXT_SIZE 13 -# define _LIBUNWIND_CURSOR_SIZE 19 +# define _LIBUNWIND_CURSOR_SIZE 20 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 # elif defined(__x86_64__) # define _LIBUNWIND_TARGET_X86_64 1 @@ -178,17 +178,13 @@ #if __loongarch_grlen == 64 #define _LIBUNWIND_CONTEXT_SIZE 98 #define _LIBUNWIND_CURSOR_SIZE 110 -#elif defined(HOST_WASM) -#define _LIBUNWIND_TARGET_WASM 1 -// TODO: Determine the right values -#define _LIBUNWIND_CONTEXT_SIZE 0xbadf00d -#define _LIBUNWIND_CURSOR_SIZE 0xbadf00d #else #error "Unsupported LoongArch ABI" #endif #define _LIBUNWIND_HIGHEST_DWARF_REGISTER \ _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH #elif defined(__wasm__) +#define _LIBUNWIND_TARGET_WASM 1 // Unused #define _LIBUNWIND_CONTEXT_SIZE 0 #define _LIBUNWIND_CURSOR_SIZE 0 diff --git a/src/runtime/src/native/libs/CMakeLists.txt b/src/runtime/src/native/libs/CMakeLists.txt index c90e9b8a45d..cf8b2b47fbd 100644 --- a/src/runtime/src/native/libs/CMakeLists.txt +++ b/src/runtime/src/native/libs/CMakeLists.txt @@ -150,18 +150,12 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) if (CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) # skip for now - elseif (CLR_CMAKE_TARGET_MACCATALYST) - add_subdirectory(System.Net.Security.Native) - # System.Security.Cryptography.Native is intentionally disabled on iOS - # it is only used for interacting with OpenSSL which isn't useful there - elseif (CLR_CMAKE_TARGET_IOS) - add_subdirectory(System.Net.Security.Native) - # System.Security.Cryptography.Native is intentionally disabled on iOS - # it is only used for interacting with OpenSSL which isn't useful there - elseif (CLR_CMAKE_TARGET_TVOS) - #add_subdirectory(System.Net.Security.Native) # no gssapi on tvOS, see https://developer.apple.com/documentation/gss - # System.Security.Cryptography.Native is intentionally disabled on tvOS - # it is only used for interacting with OpenSSL which isn't useful there + elseif (CLR_CMAKE_TARGET_APPLE) + if (NOT CLR_CMAKE_TARGET_TVOS) # no gssapi on tvOS, see https://developer.apple.com/documentation/gss + add_subdirectory(System.Net.Security.Native) + endif () + + add_subdirectory(System.Security.Cryptography.Native.Apple) elseif (CLR_CMAKE_TARGET_ANDROID AND NOT FORCE_ANDROID_OPENSSL) add_subdirectory(System.Security.Cryptography.Native.Android) elseif (FORCE_ANDROID_OPENSSL) @@ -170,8 +164,4 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) add_subdirectory(System.Net.Security.Native) add_subdirectory(System.Security.Cryptography.Native) endif () - - if (CLR_CMAKE_TARGET_APPLE) - add_subdirectory(System.Security.Cryptography.Native.Apple) - endif () endif () diff --git a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c index 5163aa5b121..ef27e7bb832 100644 --- a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c +++ b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c @@ -62,7 +62,6 @@ static const Entry s_cryptoAppleNative[] = DllImportEntry(AppleCryptoNative_SetKeychainNeverLock) DllImportEntry(AppleCryptoNative_SslCopyCADistinguishedNames) DllImportEntry(AppleCryptoNative_SslCopyCertChain) - DllImportEntry(AppleCryptoNative_SslIsHostnameMatch) DllImportEntry(AppleCryptoNative_SslRead) DllImportEntry(AppleCryptoNative_SslSetBreakOnCertRequested) DllImportEntry(AppleCryptoNative_SslSetBreakOnClientAuth) diff --git a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c index 2fba375bd42..2218fdaab5a 100644 --- a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c +++ b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c @@ -416,181 +416,6 @@ PAL_TlsIo AppleCryptoNative_SslRead(SSLContextRef sslContext, uint8_t* buf, uint return OSStatusToPAL_TlsIo(status); } -int32_t AppleCryptoNative_SslIsHostnameMatch(SSLContextRef sslContext, CFStringRef cfHostname, CFDateRef notBefore, int32_t* pOSStatus) -{ - if (pOSStatus != NULL) - *pOSStatus = noErr; - - if (sslContext == NULL || notBefore == NULL || pOSStatus == NULL) - return -1; - - if (cfHostname == NULL) - return -2; - - SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, cfHostname); - - if (sslPolicy == NULL) - return -3; - - CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - if (certs == NULL) - return -4; - - SecTrustRef existingTrust = NULL; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - OSStatus osStatus = SSLCopyPeerTrust(sslContext, &existingTrust); -#pragma clang diagnostic pop - - if (osStatus != noErr) - { - CFRelease(certs); - *pOSStatus = osStatus; - return -5; - } - - CFMutableArrayRef anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - if (anchors == NULL) - { - CFRelease(certs); - CFRelease(existingTrust); - return -6; - } - - CFIndex certificateCount = SecTrustGetCertificateCount(existingTrust); - - for (CFIndex i = 0; i < certificateCount; i++) - { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - SecCertificateRef item = SecTrustGetCertificateAtIndex(existingTrust, i); -#pragma clang diagnostic pop - - CFArrayAppendValue(certs, item); - - // Copy the EE cert into the anchors set, this will make the chain part - // always return true. - if (i == 0) - { - CFArrayAppendValue(anchors, item); - } - } - - SecTrustRef trust = NULL; - osStatus = SecTrustCreateWithCertificates(certs, sslPolicy, &trust); - int32_t ret = INT_MIN; - - if (osStatus == noErr) - { - osStatus = SecTrustSetAnchorCertificates(trust, anchors); - } - - if (osStatus == noErr) - { - osStatus = SecTrustSetVerifyDate(trust, notBefore); - } - - if (osStatus == noErr) - { - SecTrustResultType trustResult; - memset(&trustResult, 0, sizeof(SecTrustResultType)); - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - osStatus = SecTrustEvaluate(trust, &trustResult); - - if (trustResult == kSecTrustResultRecoverableTrustFailure && osStatus == noErr && certificateCount > 1) - { - // If we get recoverable failure, let's try it again with full anchor list. - // We already stored just the first certificate into anchors; now we store the rest. - for (CFIndex i = 1; i < certificateCount; i++) - { - CFArrayAppendValue(anchors, SecTrustGetCertificateAtIndex(existingTrust, i)); - } - - osStatus = SecTrustSetAnchorCertificates(trust, anchors); - if (osStatus == noErr) - { - memset(&trustResult, 0, sizeof(SecTrustResultType)); - osStatus = SecTrustEvaluate(trust, &trustResult); - } - } -#pragma clang diagnostic pop - - if (osStatus == noErr && trustResult != kSecTrustResultUnspecified && trustResult != kSecTrustResultProceed) - { - // If evaluation succeeded but result is not trusted try to get details. - CFDictionaryRef detailsAndStuff = SecTrustCopyResult(trust); - - if (detailsAndStuff != NULL) - { - CFArrayRef details = CFDictionaryGetValue(detailsAndStuff, CFSTR("TrustResultDetails")); - - if (details != NULL && CFArrayGetCount(details) > 0) - { - CFArrayRef statusCodes = CFDictionaryGetValue(CFArrayGetValueAtIndex(details,0), CFSTR("StatusCodes")); - - if (statusCodes != NULL) - { - OSStatus status = 0; - // look for first failure to keep it simple. Normally, there will be exactly one. - for (int i = 0; i < CFArrayGetCount(statusCodes); i++) - { - CFNumberGetValue(CFArrayGetValueAtIndex(statusCodes, i), kCFNumberSInt32Type, &status); - if (status != noErr) - { - *pOSStatus = status; - break; - } - } - } - } - - CFRelease(detailsAndStuff); - } - } - - if (osStatus != noErr) - { - ret = -7; - *pOSStatus = osStatus; - } - else if (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed) - { - ret = 1; - } - else if (trustResult == kSecTrustResultDeny || trustResult == kSecTrustResultRecoverableTrustFailure) - { - ret = 0; - } - else - { - ret = -8; - } - } - else - { - *pOSStatus = osStatus; - } - - if (trust != NULL) - CFRelease(trust); - - if (certs != NULL) - CFRelease(certs); - - if (anchors != NULL) - CFRelease(anchors); - - if (existingTrust != NULL) - CFRelease(existingTrust); - - CFRelease(sslPolicy); - return ret; -} - int32_t AppleCryptoNative_SslShutdown(SSLContextRef sslContext) { #pragma clang diagnostic push diff --git a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h index 14b8d790970..8a73e052717 100644 --- a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h +++ b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h @@ -226,17 +226,6 @@ written: Receives the number of bytes written into buf PALEXPORT PAL_TlsIo AppleCryptoNative_SslRead(SSLContextRef sslContext, uint8_t* buf, uint32_t bufLen, uint32_t* written); -/* -Check to see if the server identity certificate for this connection matches the requested hostname. - -notBefore: Specify the EE/leaf certificate's notBefore value to prevent a false negative due to -the certificate being expired (or not yet valid). - -Returns 1 on match, 0 on mismatch, any other value indicates an invalid state. -*/ -PALEXPORT int32_t -AppleCryptoNative_SslIsHostnameMatch(SSLContextRef sslContext, CFStringRef cfHostname, CFDateRef notBefore, int32_t* pOSStatus); - /* Generate a TLS Close alert to terminate the session. diff --git a/src/runtime/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt b/src/runtime/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt index ec0ad0fc7db..c875413edd3 100644 --- a/src/runtime/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt +++ b/src/runtime/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt @@ -68,18 +68,6 @@ if (LOCAL_BUILD) ${CMAKE_CURRENT_BINARY_DIR}/pal_config.h) endif() - -# Always build portable on macOS because OpenSSL is not a system component -# and our prebuilts should not assume a specific ABI version for the types -# that use OpenSSL at runtime. -if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST) - set(FEATURE_DISTRO_AGNOSTIC_SSL True) - - # by default uninitialized variables like the shim _ptr functions, will turn into common symbols - # and on OSX those have linking problems in libraries (ELF vs. Mach-O difference) - add_compile_options(-fno-common) -endif() - if (FEATURE_DISTRO_AGNOSTIC_SSL) list(APPEND NATIVECRYPTO_SOURCES opensslshim.c @@ -125,16 +113,14 @@ if (GEN_SHARED_LIB) endif() endif() - if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID) - add_custom_command(TARGET System.Security.Cryptography.Native.OpenSsl POST_BUILD - COMMENT "Verifying System.Security.Cryptography.Native.OpenSsl entry points against entrypoints.c " - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-entrypoints.sh - $ - ${CMAKE_CURRENT_SOURCE_DIR}/entrypoints.c - ${CMAKE_NM} - VERBATIM - ) - endif() + add_custom_command(TARGET System.Security.Cryptography.Native.OpenSsl POST_BUILD + COMMENT "Verifying System.Security.Cryptography.Native.OpenSsl entry points against entrypoints.c " + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-entrypoints.sh + $ + ${CMAKE_CURRENT_SOURCE_DIR}/entrypoints.c + ${CMAKE_NM} + VERBATIM + ) target_link_libraries(System.Security.Cryptography.Native.OpenSsl PRIVATE diff --git a/src/runtime/src/native/libs/build-native.sh b/src/runtime/src/native/libs/build-native.sh index 5169732c2d6..5055b05839d 100755 --- a/src/runtime/src/native/libs/build-native.sh +++ b/src/runtime/src/native/libs/build-native.sh @@ -83,6 +83,9 @@ elif [[ "$__TargetOS" == ios || "$__TargetOS" == iossimulator ]]; then elif [[ "$__TargetOS" == tvos || "$__TargetOS" == tvossimulator ]]; then # nothing to do here true +elif [[ "$__TargetOS" == osx || "$__TargetOS" == maccatalyst ]]; then + # nothing to do here + true elif [[ "$__TargetOS" == android && -z "$ROOTFS_DIR" ]]; then # nothing to do here true diff --git a/src/runtime/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs b/src/runtime/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs index 006b746ef0d..bf3d76bcb24 100644 --- a/src/runtime/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs +++ b/src/runtime/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs @@ -108,6 +108,11 @@ public class AndroidAppBuilderTask : Task public bool ForceInterpreter { get; set; } + /// + /// Indicates whether we want to use invariant globalization mode. + /// + public bool InvariantGlobalization { get; set; } + [Output] public string ApkBundlePath { get; set; } = ""!; @@ -141,6 +146,7 @@ public override bool Execute() apkBuilder.NativeDependencies = NativeDependencies; apkBuilder.ExtraLinkerArguments = ExtraLinkerArguments; apkBuilder.RuntimeFlavor = RuntimeFlavor; + apkBuilder.InvariantGlobalization = InvariantGlobalization; (ApkBundlePath, ApkPackageId) = apkBuilder.BuildApk(RuntimeIdentifier, MainLibraryFileName, RuntimeHeaders); return true; diff --git a/src/runtime/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/runtime/src/tasks/AndroidAppBuilder/ApkBuilder.cs index 21fd800c896..df0772393e7 100644 --- a/src/runtime/src/tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/src/runtime/src/tasks/AndroidAppBuilder/ApkBuilder.cs @@ -424,6 +424,11 @@ public ApkBuilder(TaskLoggingHelper logger) envVariables += $"\t\tsetEnv(\"{name}\", \"{value}\");\n"; } + if (InvariantGlobalization) + { + envVariables += $"\t\tsetEnv(\"DOTNET_SYSTEM_GLOBALIZATION_INVARIANT\", \"true\");\n"; + } + string jniLibraryName = (IsLibraryMode) ? ProjectName! : (StaticLinkedRuntime && IsCoreCLR) ? "monodroid" : "System.Security.Cryptography.Native.Android"; string monoRunner = Utils.GetEmbeddedResource("MonoRunner.java") diff --git a/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 00d9e45ae2a..38f6d51b32a 100644 --- a/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -4896,6 +4896,20 @@ ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWideningAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddPairwiseWidening(left, right, i)"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWideningAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddPairwiseWidening(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddSaturate(left[i], right[i])"}), @@ -4999,6 +5013,15 @@ ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), @@ -5016,6 +5039,108 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])",}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])"}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndSubtract_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndSubtract_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndSubtract_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndSubtract_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])"}), + + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])"}), + + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_PolynomialMultiply_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiply(left[i], right[i])", ["GetIterResult"] = "Helpers.PolynomialMultiply(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_PolynomialMultiply_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiply(left[i], right[i])", ["GetIterResult"] = "Helpers.PolynomialMultiply(leftOp[i], rightOp[i])"}), + + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_PolynomialMultiplyWideningEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.PolynomialMultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_PolynomialMultiplyWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.PolynomialMultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_PolynomialMultiplyWideningOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.PolynomialMultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_PolynomialMultiplyWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.PolynomialMultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRounded_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (sbyte)Helpers.SveShiftArithmeticRounded(left[i], right[i])", ["GetIterResult"] = "(sbyte)Helpers.SveShiftArithmeticRounded(leftOp[i], rightOp[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRounded_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (short)Helpers.SveShiftArithmeticRounded(left[i], right[i])", ["GetIterResult"] = "(short)Helpers.SveShiftArithmeticRounded(leftOp[i], rightOp[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRounded_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (int) Helpers.SveShiftArithmeticRounded(left[i], right[i])", ["GetIterResult"] = "(int) Helpers.SveShiftArithmeticRounded(leftOp[i], rightOp[i])"}), @@ -5183,6 +5308,11 @@ ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractBorrowWideningEven_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractBorrowWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractBorrowWideningEven(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractBorrowWideningEven(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractBorrowWideningEven_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractBorrowWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractBorrowWideningEven(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractBorrowWideningEven(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractBorrowWideningOdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractBorrowWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractBorrowWideningOdd(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractBorrowWideningOdd(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractBorrowWideningOdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractBorrowWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractBorrowWideningOdd(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractBorrowWideningOdd(first, second, third)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), @@ -5197,6 +5327,20 @@ ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i)"}), ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), @@ -5206,15 +5350,6 @@ ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_short_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2])"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_int_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2])"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_long_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2])"}), @@ -5251,11 +5386,6 @@ ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOddEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2])"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOddEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2])"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractWithBorrowWideningLower_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWithBorrowWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractWithBorrowWideningLower(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractWithBorrowWideningLower(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractWithBorrowWideningLower_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWithBorrowWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractWithBorrowWideningLower(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractWithBorrowWideningLower(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractWithBorrowWideningUpper_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWithBorrowWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractWithBorrowWideningUpper(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractWithBorrowWideningUpper(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractWithBorrowWideningUpper_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWithBorrowWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractWithBorrowWideningUpper(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractWithBorrowWideningUpper(first, second, third)"}), - ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(third[i] < (Byte) RetElementCount * 2) ? ((third[i] < (Byte) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(Byte) RetElementCount])) : (result[i] != 0)"}), ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(third[i] < (UInt16) RetElementCount * 2) ? ((third[i] < (UInt16) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt16) RetElementCount])) : (result[i] != 0)"}), ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(third[i] < (UInt32) RetElementCount * 2) ? ((third[i] < (UInt32) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt32) RetElementCount])) : (result[i] != 0)"}), diff --git a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index e1ddb8238d1..d8643e94617 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2142,9 +2142,9 @@ public static float CompareTest(float left, float right) public static short AbsoluteDifferenceWideningLowerAndAddOdd(short[] op1, sbyte[] op2, sbyte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static short AbsoluteDifferenceWideningEven(sbyte[] op1, sbyte[] op2, int i) => (short) AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static short AbsoluteDifferenceWideningEven(sbyte[] op1, sbyte[] op2, int i) => (short)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static short AbsoluteDifferenceWideningOdd(sbyte[] op1, sbyte[] op2, int i) => (short) AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static short AbsoluteDifferenceWideningOdd(sbyte[] op1, sbyte[] op2, int i) => (short)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static short AddAcrossWidening(sbyte[] op1) => Reduce(AddWidening, op1); @@ -2302,9 +2302,9 @@ private static long Reduce(Func reduceOp, sbyte[] op1) public static int AbsoluteDifferenceWideningLowerAndAddOdd(int[] op1, short[] op2, short[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static int AbsoluteDifferenceWideningEven(short[] op1, short[] op2, int i) => (int) AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static int AbsoluteDifferenceWideningEven(short[] op1, short[] op2, int i) => (int)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static int AbsoluteDifferenceWideningOdd(short[] op1, short[] op2, int i) => (int) AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static int AbsoluteDifferenceWideningOdd(short[] op1, short[] op2, int i) => (int)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static int AddAcrossWidening(short[] op1) => Reduce(AddWidening, op1); @@ -2519,9 +2519,9 @@ private static long Reduce(Func reduceOp, short[] op1) public static long AbsoluteDifferenceWideningLowerAndAddOdd(long[] op1, int[] op2, int[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static long AbsoluteDifferenceWideningEven(int[] op1, int[] op2, int i) => (long) AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static long AbsoluteDifferenceWideningEven(int[] op1, int[] op2, int i) => (long)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static long AbsoluteDifferenceWideningOdd(int[] op1, int[] op2, int i) => (long) AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static long AbsoluteDifferenceWideningOdd(int[] op1, int[] op2, int i) => (long)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static long AddAcrossWidening(int[] op1) => Reduce(AddWidening, op1); @@ -2774,7 +2774,7 @@ private static long Reduce(Func reduceOp, int[] op1) public static ushort AbsoluteDifferenceWideningLowerAndAddOdd(ushort[] op1, byte[] op2, byte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static ushort AbsoluteDifferenceWideningEven(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static ushort AbsoluteDifferenceWideningEven(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); public static ushort AbsoluteDifferenceWideningOdd(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); @@ -2918,9 +2918,9 @@ private static ulong Reduce(Func reduceOp, byte[] op1) public static uint AbsoluteDifferenceWideningLowerAndAddOdd(uint[] op1, ushort[] op2, ushort[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static uint AbsoluteDifferenceWideningEven(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static uint AbsoluteDifferenceWideningEven(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static uint AbsoluteDifferenceWideningOdd(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static uint AbsoluteDifferenceWideningOdd(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static uint AddAcrossWidening(ushort[] op1) => Reduce(AddWidening, op1); @@ -3062,9 +3062,9 @@ private static ulong Reduce(Func reduceOp, ushort[] op1) public static ulong AbsoluteDifferenceWideningLowerAndAddOdd(ulong[] op1, uint[] op2, uint[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static ulong AbsoluteDifferenceWideningEven(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static ulong AbsoluteDifferenceWideningEven(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static ulong AbsoluteDifferenceWideningOdd(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static ulong AbsoluteDifferenceWideningOdd(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static ulong AddAcrossWidening(uint[] op1) => Reduce(AddWidening, op1); @@ -7180,6 +7180,22 @@ private static short PolynomialMult(sbyte op1, sbyte op2) return result; } + private static ulong PolynomialMult(uint op1, uint op2) + { + ulong result = default(ulong); + ulong extendedOp2 = (ulong)op2; + + for (int i = 0; i < 8 * sizeof(uint); i++) + { + if ((op1 & ((uint)1 << i)) != 0) + { + result = (ulong)(result ^ (extendedOp2 << i)); + } + } + + return result; + } + private static poly128_t PolynomialMult(ulong op1, ulong op2) { poly128_t result = default(poly128_t); @@ -7264,6 +7280,8 @@ public static ulong MultiplyHigh(ulong op1, ulong op2) public static long PolynomialMultiplyWideningHi64(long op1, long op2) => (long)PolynomialMult(op1, op2).hi; + public static ulong PolynomialMultiplyWidening(uint op1, uint op2) => PolynomialMult(op1, op2); + public static sbyte Concat(sbyte[] op1, sbyte[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; public static sbyte ConcatScalar(sbyte[] op1, sbyte[] op2, int i) @@ -10946,16 +10964,50 @@ public static T[] InterleavingXorOddEven(T[] even, T[] left, T[] right) where { for (int i = 0; i < even.Length; i += 2) { - even[i+1] = left[i+1] ^ right[i]; + even[i + 1] = left[i + 1] ^ right[i]; } return even; } + public static T[] SubtractBorrowWideningEven(T[] op1, T[] op2, T[] op3) + where T : unmanaged, IBinaryInteger + { + T[] result = new T[op1.Length]; + for (int i = 0; i < op1.Length; i += 2) + { + T a = op1[i]; + T b = ~op2[i]; + T carryIn = op3[i + 1] & T.One; + (T sum, T carryOut) = AddWithCarry(a, b, carryIn); + result[i] = sum; + result[i + 1] = carryOut; + } + + return result; + } + + public static T[] SubtractBorrowWideningOdd(T[] op1, T[] op2, T[] op3) + where T : unmanaged, IBinaryInteger + { + T[] result = new T[op1.Length]; + for (int i = 0; i < op1.Length; i += 2) + { + T a = op1[i]; + T b = ~op2[i+1]; + T carryIn = op3[i + 1] & T.One; + (T sum, T carryOut) = AddWithCarry(a, b, carryIn); + result[i] = sum; + result[i + 1] = carryOut; + } + + return result; + } + public static sbyte SubtractHighNarrowingEven(short[] left, short[] right, int i) { if (i % 2 == 0) { - return (sbyte) ((left[i / 2] - right[i / 2]) >> 8); + return (sbyte)((left[i / 2] - right[i / 2]) >> 8); } return 0; @@ -11081,40 +11133,6 @@ public static (T sum, T carryOut) AddWithCarry(T a, T b, T carryIn) return (sum, carryOut); } - public static T[] SubtractWithBorrowWideningLower(T[] op1, T[] op2, T[] op3) - where T : unmanaged, IBinaryInteger - { - T[] result = new T[op1.Length]; - for (int i = 0; i < op1.Length; i += 2) - { - T a = op1[i]; - T b = ~op2[i]; - T carryIn = op3[i + 1] & T.One; - (T sum, T carryOut) = AddWithCarry(a, b, carryIn); - result[i] = sum; - result[i + 1] = carryOut; - } - - return result; - } - - public static T[] SubtractWithBorrowWideningUpper(T[] op1, T[] op2, T[] op3) - where T : unmanaged, IBinaryInteger - { - T[] result = new T[op1.Length]; - for (int i = 0; i < op1.Length; i += 2) - { - T a = op1[i]; - T b = ~op2[i+1]; - T carryIn = op3[i + 1] & T.One; - (T sum, T carryOut) = AddWithCarry(a, b, carryIn); - result[i] = sum; - result[i + 1] = carryOut; - } - - return result; - } - public static T Xor(params T[] ops) where T : IBitwiseOperators { T result = ops[0]; @@ -11388,5 +11406,107 @@ public static U ShiftRightLogicalRoundedNarrowingSaturateOdd(U even, T val { return Odd(even, LogicalShift(val, shift, rounding: true, saturate: true), i); } + + public static W MultiplyAddWidening(W op1, N op2, N op3) + where W : IBinaryInteger + where N : IBinaryInteger + { + dynamic a = op2; + dynamic b = op3; + W product = (W)((W)a * (W)b); + W r = (W)(op1 + product); + return r; + } + + public static W MultiplySubtractWidening(W op1, N op2, N op3) + where W : IBinaryInteger + where N : IBinaryInteger + { + dynamic a = op2; + dynamic b = op3; + W product = (W)((W)a * (W)b); + W r = (W)(op1 - product); + return r; + } + + public static N AddRoundedHighNarrowing(W op1, W op2) + where W : IBinaryInteger + where N : IBinaryInteger + { + int halfsize = default(N).GetByteCount() * 8; + dynamic a = op1; + dynamic b = op2; + ulong sum = (ulong)a + (ulong)b; + ulong bias = 1UL << (halfsize - 1); + dynamic result = sum + bias; + return (N)(result >> halfsize); + } + + public static N AddRoundedHighNarrowingEven(W op1, W op2, int i) + where W : IBinaryInteger + where N : IBinaryInteger, new() + { + return Even(AddRoundedHighNarrowing(op1, op2), i); + } + + public static N AddRoundedHighNarrowingOdd(N even, W op1, W op2, int i) + where W : IBinaryInteger + where N : IBinaryInteger + { + return Odd(even, AddRoundedHighNarrowing(op1, op2), i); + } + + public static N SubtractRoundedHighNarrowing(W op1, W op2) + where W : IBinaryInteger + where N : IBinaryInteger + { + int halfsize = default(N).GetByteCount() * 8; + dynamic a = op1; + dynamic b = op2; + ulong sum = (ulong)a - (ulong)b; + ulong bias = 1UL << (halfsize - 1); + dynamic result = sum + bias; + return (N)(result >> halfsize); + } + + public static N SubtractRoundedHighNarrowingEven(W op1, W op2, int i) + where W : IBinaryInteger + where N : IBinaryInteger, new() + { + return Even(SubtractRoundedHighNarrowing(op1, op2), i); + } + + public static N SubtractRoundedHighNarrowingOdd(N even, W op1, W op2, int i) + where W : IBinaryInteger + where N : IBinaryInteger + { + return Odd(even, SubtractRoundedHighNarrowing(op1, op2), i); + } + + public static long FusedAddRoundedHalving(long op1, long op2) => (long)((ulong)(op1 + op2 + 1) >> 1); + + public static ulong FusedAddRoundedHalving(ulong op1, ulong op2) + { + bool overflow = false; + ulong sum = 0; + try + { + sum = checked(op1 + op2 + 1); + } + catch (OverflowException) + { + overflow = true; + sum = op1 + op2 + 1; + } + + sum >>>= 1; + + if (overflow) + { + sum |= (ulong)(1UL << 63); + } + + return sum; + } } } diff --git a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template index 2d2df308eb2..ad9531b94c7 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template @@ -538,7 +538,7 @@ namespace JIT.HardwareIntrinsics.Arm if (!succeeded) { TestLibrary.TestFramework.LogInformation(string.Empty); - TestLibrary.TestFramework.LogInformation($"{nameof(Sve2)}.{nameof({Isa}.{Method})}(Vector, Vector): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(Sve2)}.{nameof({Isa}.{Method})}<{RetBaseType}>(Vector<{Op1BaseType}>, Vector<{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/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template index 4708815e3ba..45907adb29e 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template @@ -185,8 +185,8 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueMask} % 2); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueMask} % 2); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } diff --git a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template index 9ce3a334f7d..4117cecd4dd 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template @@ -99,11 +99,11 @@ namespace JIT.HardwareIntrinsics.Arm private ulong alignment; - public DataTable({Op1BaseType}[] inArray1, {Op1BaseType}[] inArray2, {Op1BaseType}[] inArray3, {RetBaseType}[] outArray, int alignment) + public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {Op3BaseType}[] inArray3, {RetBaseType}[] outArray, int alignment) { int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>(); int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray) { @@ -123,8 +123,8 @@ namespace JIT.HardwareIntrinsics.Arm this.alignment = (ulong)alignment; Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); } public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); @@ -149,8 +149,8 @@ namespace JIT.HardwareIntrinsics.Arm private struct TestStruct { public {Op1VectorType}<{Op1BaseType}> _fld1; - public {Op1VectorType}<{Op1BaseType}> _fld2; - public {Op1VectorType}<{Op1BaseType}> _fld3; + public {Op1VectorType}<{Op2BaseType}> _fld2; + public {Op1VectorType}<{Op3BaseType}> _fld3; public static TestStruct Create() { @@ -158,10 +158,10 @@ namespace JIT.HardwareIntrinsics.Arm for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp3}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op3BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); return testStruct; } @@ -178,19 +178,23 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int LargestVectorSize = {LargestVectorSize}; private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>() / sizeof({Op3BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); private static readonly byte Imm = {Imm}; - private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; + private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; - private static {Op1BaseType}[] _data2 = new {Op1BaseType}[Op1ElementCount]; - private static {Op1BaseType}[] _data3 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; + private static {Op3BaseType}[] _data3 = new {Op3BaseType}[Op3ElementCount]; - private {Op1VectorType}<{Op1BaseType}> _mask; + private {Op1VectorType}<{RetBaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; - private {Op1VectorType}<{Op1BaseType}> _fld2; - private {Op1VectorType}<{Op1BaseType}> _fld3; - private {Op1VectorType}<{Op1BaseType}> _falseFld; + private {Op1VectorType}<{Op2BaseType}> _fld2; + private {Op1VectorType}<{Op3BaseType}> _fld3; + private {Op1VectorType}<{RetBaseType}> _falseFld; + private {Op1VectorType}<{RetBaseType}> _falseFld2; + private {Op1VectorType}<{RetBaseType}> _falseFld3; private DataTable _dataTable; @@ -198,19 +202,22 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueMask} % 2); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueMask} % 2); } for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp3}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } - for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp3}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } _dataTable = new DataTable(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize); } @@ -224,8 +231,8 @@ namespace JIT.HardwareIntrinsics.Arm var result = {Isa}.{Method}( Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr), + Unsafe.Read<{Op1VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op1VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), {Imm} ); @@ -242,8 +249,8 @@ namespace JIT.HardwareIntrinsics.Arm { var result = {Isa}.{Method}( Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr), + Unsafe.Read<{Op1VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op1VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), {InvalidImm} ); Console.WriteLine(result); @@ -263,12 +270,14 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + {Op1VectorType}<{Op2BaseType}> loadMask2 = Sve.CreateTrueMask{Op2BaseType}(SveMaskPattern.All); + {Op1VectorType}<{Op3BaseType}> loadMask3 = Sve.CreateTrueMask{Op3BaseType}(SveMaskPattern.All); var result = {Isa}.{Method}( {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), - {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray2Ptr)), - {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray3Ptr)), + {LoadIsa}.Load{Op1VectorType}(loadMask2, ({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {LoadIsa}.Load{Op1VectorType}(loadMask3, ({Op3BaseType}*)(_dataTable.inArray3Ptr)), {Imm} ); @@ -280,11 +289,11 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) }) + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op1VectorType}<{Op2BaseType}>), typeof({Op1VectorType}<{Op3BaseType}>), typeof(byte) }) .Invoke(null, new object[] { Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr), + Unsafe.Read<{Op1VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op1VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), (byte){Imm} }); @@ -297,8 +306,8 @@ namespace JIT.HardwareIntrinsics.Arm TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); - var op2 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr); - var op3 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr); + var op2 = Unsafe.Read<{Op1VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var op3 = Unsafe.Read<{Op1VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr); var result = {Isa}.{Method}(op1, op2, op3, {Imm}); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -337,64 +346,64 @@ namespace JIT.HardwareIntrinsics.Arm public void ConditionalSelect_Op1() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); } public void ConditionalSelect_Op2() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld2); } public void ConditionalSelect_Op3() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld3); } public void ConditionalSelect_FalseOp() @@ -403,44 +412,44 @@ namespace JIT.HardwareIntrinsics.Arm ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in FalseValue"); ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); } public void ConditionalSelect_ZeroOp() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp) + private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> falseOp) { var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, Imm), falseOp); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -448,7 +457,7 @@ namespace JIT.HardwareIntrinsics.Arm } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> op3, {Op1VectorType}<{Op1BaseType}> trueOp) + private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> trueOp) { var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2, op3, Imm)); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -476,25 +485,25 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op1BaseType}> secondOp, {Op1VectorType}<{Op1BaseType}> thirdOp, {Op1VectorType}<{Op1BaseType}> falseOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; {Op1BaseType}[] first = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] second = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] third = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] falseVal = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] second = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] third = new {Op3BaseType}[Op3ElementCount]; + {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref first[0]), firstOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref second[0]), secondOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref third[0]), thirdOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref falseVal[0]), falseOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref second[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref third[0]), thirdOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseVal[0]), falseOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); bool succeeded = true; {TemplateValidationLogicForCndSel} if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op2BaseType}>, {Op1VectorType}<{Op3BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); TestLibrary.TestFramework.LogInformation($" first: ({string.Join(", ", first)})"); TestLibrary.TestFramework.LogInformation($" second: ({string.Join(", ", second)})"); @@ -506,19 +515,19 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op1BaseType}> secondOp, {Op1VectorType}<{Op1BaseType}> thirdOp, {Op1VectorType}<{Op1BaseType}> trueOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {Op1BaseType}[RetElementCount]; {Op1BaseType}[] first = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] second = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] third = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] trueVal = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] second = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] third = new {Op3BaseType}[Op3ElementCount]; + {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref first[0]), firstOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref second[0]), secondOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref third[0]), thirdOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref trueVal[0]), trueOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref second[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref third[0]), thirdOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref trueVal[0]), trueOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); bool succeeded = true; @@ -526,7 +535,7 @@ namespace JIT.HardwareIntrinsics.Arm if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op2BaseType}>, {Op1VectorType}<{Op3BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); TestLibrary.TestFramework.LogInformation($" first: ({string.Join(", ", first)})"); TestLibrary.TestFramework.LogInformation($" second: ({string.Join(", ", second)})"); @@ -538,16 +547,16 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> op3, void* result, [CallerMemberName] string method = "") + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] inArray3 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), op2); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), op3); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), op3); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); ValidateResult(inArray1, inArray2, inArray3, outArray, method); @@ -556,19 +565,19 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] inArray3 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); ValidateResult(inArray1, inArray2, inArray3, outArray, method); } - private void ValidateResult({Op1BaseType}[] firstOp, {Op1BaseType}[] secondOp, {Op1BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { bool succeeded = true; @@ -576,7 +585,7 @@ namespace JIT.HardwareIntrinsics.Arm if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op2BaseType}>, {Op1VectorType}<{Op3BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template index 13343926763..bdce7267163 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template @@ -43,15 +43,9 @@ namespace JIT.HardwareIntrinsics.Arm // Validates passing a local works, using Unsafe.Read test.RunLclVarScenario_UnsafeRead(); - // Validates using the same local multiple times works, using Unsafe.Read - test.RunSameLclVarScenario_UnsafeRead(); - // Validates passing an instance member of a class works test.RunClassFldScenario(); - // Validates using the same instance member of a class multiple times works - test.RunSameClassFldScenario(); - // Validates passing the field of a local struct works test.RunStructLclFldScenario(); @@ -161,9 +155,9 @@ namespace JIT.HardwareIntrinsics.Arm for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp3}; } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op3BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); return testStruct; @@ -185,16 +179,20 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>() / sizeof({Op3BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); - private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; + private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; private static {Op3BaseType}[] _data3 = new {Op3BaseType}[Op3ElementCount]; - private {Op1VectorType}<{Op1BaseType}> _mask; + private {Op1VectorType}<{RetBaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; private {Op1VectorType}<{Op2BaseType}> _fld2; private {Op1VectorType}<{Op3BaseType}> _fld3; - private {Op1VectorType}<{Op1BaseType}> _falseFld; + private {Op1VectorType}<{RetBaseType}> _falseFld; + + private {Op1VectorType}<{RetBaseType}> _resultFld1; + private {Op1VectorType}<{RetBaseType}> _resultFld2; + private {Op1VectorType}<{RetBaseType}> _resultFld3; private DataTable _dataTable; @@ -202,16 +200,21 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1} % 2); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueOp1} % 2); } for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _resultFld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _resultFld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _resultFld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } @@ -283,20 +286,6 @@ namespace JIT.HardwareIntrinsics.Arm ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); } - public void RunSameLclVarScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunSameLclVarScenario_UnsafeRead)); - - var op = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); - var op1 = op; - var op2 = op; - var op3 = op; - var result = {Isa}.{Method}(op1, op2, op3); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); - } - public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); @@ -307,16 +296,6 @@ namespace JIT.HardwareIntrinsics.Arm ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); } - public void RunSameClassFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunSameClassFldScenario)); - - var result = {Isa}.{Method}(_fld1, _fld1, _fld1); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_fld1, _fld1, _fld1, _dataTable.outArrayPtr); - } - public void RunStructLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); @@ -339,64 +318,64 @@ namespace JIT.HardwareIntrinsics.Arm public void ConditionalSelect_Op1() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld1); } public void ConditionalSelect_Op2() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld2); } public void ConditionalSelect_Op3() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld3); } public void ConditionalSelect_FalseOp() @@ -405,44 +384,44 @@ namespace JIT.HardwareIntrinsics.Arm ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in FalseValue"); ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); } public void ConditionalSelect_ZeroOp() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp) + private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> falseOp) { var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp); @@ -451,7 +430,7 @@ namespace JIT.HardwareIntrinsics.Arm } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> trueOp) + private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> trueOp) { var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2, op3)); @@ -480,20 +459,20 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{Op1BaseType}> falseOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; {Op1BaseType}[] first = new {Op1BaseType}[Op1ElementCount]; {Op2BaseType}[] second = new {Op2BaseType}[Op2ElementCount]; {Op3BaseType}[] third = new {Op3BaseType}[Op3ElementCount]; - {Op1BaseType}[] falseVal = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref first[0]), firstOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref second[0]), secondOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref third[0]), thirdOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref falseVal[0]), falseOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref second[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref third[0]), thirdOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseVal[0]), falseOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); bool succeeded = true; @@ -515,20 +494,20 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{Op1BaseType}> trueOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; {Op1BaseType}[] first = new {Op1BaseType}[Op1ElementCount]; {Op2BaseType}[] second = new {Op2BaseType}[Op2ElementCount]; {Op3BaseType}[] third = new {Op3BaseType}[Op3ElementCount]; - {Op1BaseType}[] trueVal = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref first[0]), firstOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref second[0]), secondOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref third[0]), thirdOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref trueVal[0]), trueOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref second[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref third[0]), thirdOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref trueVal[0]), trueOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); bool succeeded = true; @@ -553,8 +532,8 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op1ElementCount]; - {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); @@ -568,8 +547,8 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op1ElementCount]; - {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.cs b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.cs new file mode 100644 index 00000000000..7ca27eb30a3 --- /dev/null +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// Failure calling a synchronized method in an assembly loaded in a collectible AssemblyLoadContext: +// +// Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. +// ---> System.NullReferenceException: Object reference not set to an instance of an object. +// at System.RuntimeTypeHandle.GetRuntimeTypeFromHandle(IntPtr handle) +// at Runtime_117566.Synchronized() +// at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(System.Object, IntPtr*) +// at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(System.Object, System.Reflection.BindingFlags) +// at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo) +// at System.Reflection.MethodBase.Invoke(System.Object, System.Object[]) +// at Runtime_117566.TestEntryPoint() + +using System.Reflection; +using System.Runtime.Loader; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_117566 +{ + [Fact] + public static void TestEntryPoint() + { + var context = new AssemblyLoadContext("CollectibleALC", isCollectible: true); + Assembly assembly = context.LoadFromAssemblyPath(Assembly.GetExecutingAssembly().Location); + + var method = assembly.GetType(nameof(Runtime_117566)).GetMethod(nameof(Synchronized), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + method?.Invoke(null, []); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + internal static void Synchronized() + { } +} diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj new file mode 100644 index 00000000000..1c287f51f44 --- /dev/null +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj @@ -0,0 +1,10 @@ + + + True + + true + + + + + diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.cs b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.cs new file mode 100644 index 00000000000..9a91aaf7a75 --- /dev/null +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Generated by Fuzzlyn v3.3 on 2025-07-14 11:26:52 +// Run on X64 Windows +// Seed: 5654087083843205658-vectort,vector128,vector256,x86aes,x86avx,x86avx2,x86avx512bw,x86avx512bwvl,x86avx512cd,x86avx512cdvl,x86avx512dq,x86avx512dqvl,x86avx512f,x86avx512fvl,x86avx512fx64,x86bmi1,x86bmi1x64,x86bmi2,x86bmi2x64,x86fma,x86lzcnt,x86lzcntx64,x86pclmulqdq,x86popcnt,x86popcntx64,x86sse,x86ssex64,x86sse2,x86sse2x64,x86sse3,x86sse41,x86sse41x64,x86sse42,x86sse42x64,x86ssse3,x86x86base +// Reduced from 33.4 KiB to 0.9 KiB in 00:01:30 +// Hits JIT assert for Release: +// Assertion failed '(maskBaseSize == 4) || (maskBaseSize == 8)' in 'Program:M0()' during 'Rationalize IR' (IL size 87; hash 0xaf50ff37; FullOpts) +// +// File: D:\a\_work\1\s\src\coreclr\jit\gentree.cpp Line: 20819 +// + +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +public class Runtime_117605 +{ + static Vector[] s_2; + + [Fact] + public static void TestEntryPoint() + { + if (Avx2.IsSupported) + { + M0(); + } + } + + private static void M0() + { + var vr3 = Vector256.Create(0, 7424648407429701945UL, 0, 0); + var vr6 = Vector256.Create(0); + var vr7 = Vector128.CreateScalar(9831122154695836571UL); + var vr4 = Avx2.InsertVector128(vr6, vr7, 0); + var vr8 = Vector256.CreateScalar(1497050855019840058UL); + var vr2 = Avx2.BlendVariable(vr3, vr4, vr8); + C0 vr9 = new C0(); + var vr1 = vr9.M3(ref s_2, vr2); + } + + class C0 + { + public short M3(ref Vector[] arg0, Vector256 arg1) + { + var vr5 = Vector128.Create(0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0); + return (short)Sse2.MoveMask(vr5); + } + } +} diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj new file mode 100644 index 00000000000..de6d5e08882 --- /dev/null +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/runtime/src/tests/JIT/interpreter/Interpreter.cs b/src/runtime/src/tests/JIT/interpreter/Interpreter.cs index 61c02d4bb61..90516f0466a 100644 --- a/src/runtime/src/tests/JIT/interpreter/Interpreter.cs +++ b/src/runtime/src/tests/JIT/interpreter/Interpreter.cs @@ -2075,6 +2075,11 @@ public static T TestUnboxInst(object o) struct GenericStruct { public T Value; + + public override string ToString() + { + return "GenericStruct: " + (Value?.ToString() ?? ""); + } } public static int preciseInitCctorsRun = 0; diff --git a/src/runtime/src/tests/build.proj b/src/runtime/src/tests/build.proj index 8499575b01c..b1fd5ba3b72 100644 --- a/src/runtime/src/tests/build.proj +++ b/src/runtime/src/tests/build.proj @@ -264,6 +264,7 @@ AppDir="$(BuildDir)" DiagnosticPorts="$(DiagnosticPorts)" ForceInterpreter="$(MonoInterp)" + InvariantGlobalization="$(InvariantGlobalization)" RuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackDir)/native/include/mono-2.0" OutputDir="$(AppDir)" ProjectName="$(Category)" diff --git a/src/source-manifest.json b/src/source-manifest.json index fa2e4b53119..0c1dce241c8 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -85,10 +85,10 @@ "commitSha": "714a51c57430dab50b67e5b468016288f5f7b0bd" }, { - "barId": 275332, + "barId": 275521, "path": "runtime", "remoteUri": "https://github.com/dotnet/runtime", - "commitSha": "6d7ba3656fa078fb17e68b4e31dc9fd9ff9868da" + "commitSha": "af05ae4672443e875e5b7768cb71bbbfaa351674" }, { "barId": 273704, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy