From dc7d7bc2c8f6a122f29ffaaecc27dc94a438308d Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sat, 27 Jul 2024 10:20:34 -0700 Subject: [PATCH] =?UTF-8?q?Revert=20"JIT:=20Added=20SVE=20`GetFfr`,=20`Set?= =?UTF-8?q?Ffr`,=20`LoadVectorFirstFaulting`,=20`Gather=E2=80=A6"=20(#1055?= =?UTF-8?q?91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 991ae97a1d063e94739d0b0fe009f90506ca4883. --- src/coreclr/jit/compiler.hpp | 4 - src/coreclr/jit/fgdiagnostic.cpp | 9 +- src/coreclr/jit/gentree.cpp | 48 +- src/coreclr/jit/hwintrinsic.cpp | 1 - src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 54 +- src/coreclr/jit/hwintrinsiclistarm64sve.h | 1 - src/coreclr/jit/lowerarmarch.cpp | 51 +- .../System/Buffers/BoundedMemory.Unix.cs | 75 +- .../System/Buffers/BoundedMemory.Windows.cs | 53 +- .../Arm/Sve.PlatformNotSupported.cs | 271 ------- .../src/System/Runtime/Intrinsics/Arm/Sve.cs | 272 ------- .../ref/System.Runtime.Intrinsics.cs | 50 -- .../GenerateHWIntrinsicTests_Arm.cs | 37 - .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 302 -------- .../Arm/Shared/SveFfrTest.template | 333 --------- ...eGatherVectorFirstFaultingIndices.template | 662 ----------------- ...herVectorFirstFaultingVectorBases.template | 682 ------------------ .../Shared/SveGatherVectorIndices.template | 41 +- .../SveGatherVectorVectorBases.template | 41 +- .../SveLoadVectorFirstFaultingTest.template | 384 ---------- .../HardwareIntrinsics/Arm/Sve/Sve_r.csproj | 5 - .../HardwareIntrinsics/Arm/Sve/Sve_ro.csproj | 5 - 22 files changed, 164 insertions(+), 3217 deletions(-) delete mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveFfrTest.template delete mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorFirstFaultingIndices.template delete mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorFirstFaultingVectorBases.template delete mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadVectorFirstFaultingTest.template diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 4f70a01a8a79e..e4ab163452a16 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -4245,10 +4245,6 @@ bool Compiler::fgVarIsNeverZeroInitializedInProlog(unsigned varNum) bool result = varDsc->lvIsParam || lvaIsOSRLocal(varNum) || (varNum == lvaGSSecurityCookie) || (varNum == lvaInlinedPInvokeFrameVar) || (varNum == lvaStubArgumentVar) || (varNum == lvaRetAddrVar); -#ifdef TARGET_ARM64 - result = result || (varNum == lvaFfrRegister); -#endif - #if FEATURE_FIXED_OUT_ARGS result = result || (varNum == lvaOutgoingArgSpaceVar); #endif diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index e014838915c03..9f1a72afce63e 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -3428,15 +3428,14 @@ void Compiler::fgDebugCheckFlags(GenTree* tree, BasicBlock* block) #if defined(TARGET_ARM64) case NI_ArmBase_Yield: - case NI_Sve_GatherPrefetch16Bit: - case NI_Sve_GatherPrefetch32Bit: - case NI_Sve_GatherPrefetch64Bit: - case NI_Sve_GatherPrefetch8Bit: case NI_Sve_PrefetchBytes: case NI_Sve_PrefetchInt16: case NI_Sve_PrefetchInt32: case NI_Sve_PrefetchInt64: - case NI_Sve_SetFfr: + case NI_Sve_GatherPrefetch16Bit: + case NI_Sve_GatherPrefetch32Bit: + case NI_Sve_GatherPrefetch64Bit: + case NI_Sve_GatherPrefetch8Bit: { assert(tree->OperRequiresCallFlag(this)); expectedFlags |= GTF_GLOB_REF; diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 4beb64f119a91..f24c4cae31ef2 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -26732,18 +26732,6 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const addr = Op(3); break; - case NI_Sve_GatherVector: - case NI_Sve_GatherVectorByteZeroExtend: - case NI_Sve_GatherVectorFirstFaulting: - case NI_Sve_GatherVectorInt16SignExtend: - case NI_Sve_GatherVectorInt16WithByteOffsetsSignExtend: - case NI_Sve_GatherVectorInt32SignExtend: - case NI_Sve_GatherVectorInt32WithByteOffsetsSignExtend: - case NI_Sve_GatherVectorSByteSignExtend: - case NI_Sve_GatherVectorUInt16WithByteOffsetsZeroExtend: - case NI_Sve_GatherVectorUInt16ZeroExtend: - case NI_Sve_GatherVectorUInt32WithByteOffsetsZeroExtend: - case NI_Sve_GatherVectorUInt32ZeroExtend: case NI_Sve_GatherVectorWithByteOffsets: case NI_Sve_LoadVector: case NI_Sve_LoadVectorNonTemporal: @@ -26754,7 +26742,6 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const case NI_Sve_LoadVectorByteZeroExtendToUInt16: case NI_Sve_LoadVectorByteZeroExtendToUInt32: case NI_Sve_LoadVectorByteZeroExtendToUInt64: - case NI_Sve_LoadVectorFirstFaulting: case NI_Sve_LoadVectorInt16SignExtendToInt32: case NI_Sve_LoadVectorInt16SignExtendToInt64: case NI_Sve_LoadVectorInt16SignExtendToUInt32: @@ -26779,6 +26766,20 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const addr = Op(2); break; + case NI_Sve_GatherVector: + case NI_Sve_GatherVectorByteZeroExtend: + case NI_Sve_GatherVectorInt16SignExtend: + case NI_Sve_GatherVectorInt16WithByteOffsetsSignExtend: + case NI_Sve_GatherVectorInt32SignExtend: + case NI_Sve_GatherVectorInt32WithByteOffsetsSignExtend: + case NI_Sve_GatherVectorSByteSignExtend: + case NI_Sve_GatherVectorUInt16WithByteOffsetsZeroExtend: + case NI_Sve_GatherVectorUInt16ZeroExtend: + case NI_Sve_GatherVectorUInt32WithByteOffsetsZeroExtend: + case NI_Sve_GatherVectorUInt32ZeroExtend: + addr = Op(2); + break; + #endif // TARGET_ARM64 default: @@ -26858,12 +26859,11 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const { #ifdef TARGET_ARM64 static_assert_no_msg( - AreContiguous(NI_Sve_GatherVector, NI_Sve_GatherVectorByteZeroExtend, NI_Sve_GatherVectorFirstFaulting, - NI_Sve_GatherVectorInt16SignExtend, NI_Sve_GatherVectorInt16WithByteOffsetsSignExtend, - NI_Sve_GatherVectorInt32SignExtend, NI_Sve_GatherVectorInt32WithByteOffsetsSignExtend, - NI_Sve_GatherVectorSByteSignExtend, NI_Sve_GatherVectorUInt16WithByteOffsetsZeroExtend, - NI_Sve_GatherVectorUInt16ZeroExtend, NI_Sve_GatherVectorUInt32WithByteOffsetsZeroExtend, - NI_Sve_GatherVectorUInt32ZeroExtend)); + AreContiguous(NI_Sve_GatherVector, NI_Sve_GatherVectorByteZeroExtend, NI_Sve_GatherVectorInt16SignExtend, + NI_Sve_GatherVectorInt16WithByteOffsetsSignExtend, NI_Sve_GatherVectorInt32SignExtend, + NI_Sve_GatherVectorInt32WithByteOffsetsSignExtend, NI_Sve_GatherVectorSByteSignExtend, + NI_Sve_GatherVectorUInt16WithByteOffsetsZeroExtend, NI_Sve_GatherVectorUInt16ZeroExtend, + NI_Sve_GatherVectorUInt32WithByteOffsetsZeroExtend, NI_Sve_GatherVectorUInt32ZeroExtend)); assert(varTypeIsI(addr) || (varTypeIsSIMD(addr) && ((intrinsicId >= NI_Sve_GatherVector) && (intrinsicId <= NI_Sve_GatherVectorUInt32ZeroExtend)))); #else @@ -27281,7 +27281,6 @@ bool GenTreeHWIntrinsic::OperRequiresCallFlag() const case NI_Sve_GatherPrefetch32Bit: case NI_Sve_GatherPrefetch64Bit: case NI_Sve_GatherPrefetch8Bit: - case NI_Sve_SetFfr: { return true; } @@ -27464,15 +27463,14 @@ void GenTreeHWIntrinsic::Initialize(NamedIntrinsic intrinsicId) #if defined(TARGET_ARM64) case NI_ArmBase_Yield: - case NI_Sve_GatherPrefetch16Bit: - case NI_Sve_GatherPrefetch32Bit: - case NI_Sve_GatherPrefetch64Bit: - case NI_Sve_GatherPrefetch8Bit: case NI_Sve_PrefetchBytes: case NI_Sve_PrefetchInt16: case NI_Sve_PrefetchInt32: case NI_Sve_PrefetchInt64: - case NI_Sve_SetFfr: + case NI_Sve_GatherPrefetch16Bit: + case NI_Sve_GatherPrefetch32Bit: + case NI_Sve_GatherPrefetch64Bit: + case NI_Sve_GatherPrefetch8Bit: { // Mark as a call and global reference, much as is done for GT_KEEPALIVE gtFlags |= (GTF_CALL | GTF_GLOB_REF); diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index efa1c4a2793a5..e977b649dc5a2 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -2217,7 +2217,6 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, #elif defined(TARGET_ARM64) case NI_Sve_GatherVector: case NI_Sve_GatherVectorByteZeroExtend: - case NI_Sve_GatherVectorFirstFaulting: case NI_Sve_GatherVectorInt16SignExtend: case NI_Sve_GatherVectorInt16WithByteOffsetsSignExtend: case NI_Sve_GatherVectorInt32SignExtend: diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index f6a490c3517d0..934ed32b81d75 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -2049,34 +2049,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; } - case NI_Sve_GatherVectorFirstFaulting: - { - if (node->GetAuxiliaryType() == TYP_UNKNOWN) - { - if (intrin.numOperands == 3) - { - // We have extra argument which means there is a "use" of FFR here. Restore it back in FFR - // register. - assert(op3Reg != REG_NA); - GetEmitter()->emitIns_R(INS_sve_wrffr, emitSize, op3Reg, opt); - } - } - else - { - // AuxilaryType is added only for numOperands == 3. If there is an extra argument, we need to - // "use" FFR here. Restore it back in FFR register. - - if (intrin.numOperands == 4) - { - // We have extra argument which means there is a "use" of FFR here. Restore it back in FFR - // register. - assert(op4Reg != REG_NA); - GetEmitter()->emitIns_R(INS_sve_wrffr, emitSize, op4Reg, opt); - } - } - - FALLTHROUGH; - } case NI_Sve_GatherVector: case NI_Sve_GatherVectorByteZeroExtend: case NI_Sve_GatherVectorInt16SignExtend: @@ -2093,24 +2065,25 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { // GatherVector...(Vector mask, T* address, Vector indices) - emitAttr baseSize = emitActualTypeSize(intrin.baseType); - bool isLoadingBytes = ((ins == INS_sve_ld1b) || (ins == INS_sve_ld1sb) || (ins == INS_sve_ldff1b) || - (ins == INS_sve_ldff1sb)); - insScalableOpts sopt = INS_SCALABLE_OPTS_NONE; + assert(intrin.numOperands == 3); + emitAttr baseSize = emitActualTypeSize(intrin.baseType); + insScalableOpts sopt = INS_SCALABLE_OPTS_NONE; - if (baseSize == EA_4BYTE) + if (baseSize == EA_8BYTE) + { + // Index is multiplied. + sopt = (ins == INS_sve_ld1b || ins == INS_sve_ld1sb) ? INS_SCALABLE_OPTS_NONE + : INS_SCALABLE_OPTS_LSL_N; + } + else { // Index is sign or zero extended to 64bits, then multiplied. + assert(baseSize == EA_4BYTE); opt = varTypeIsUnsigned(node->GetAuxiliaryType()) ? INS_OPTS_SCALABLE_S_UXTW : INS_OPTS_SCALABLE_S_SXTW; - sopt = isLoadingBytes ? INS_SCALABLE_OPTS_NONE : INS_SCALABLE_OPTS_MOD_N; - } - else - { - // Index is multiplied. - assert(baseSize == EA_8BYTE); - sopt = isLoadingBytes ? INS_SCALABLE_OPTS_NONE : INS_SCALABLE_OPTS_LSL_N; + sopt = (ins == INS_sve_ld1b || ins == INS_sve_ld1sb) ? INS_SCALABLE_OPTS_NONE + : INS_SCALABLE_OPTS_MOD_N; } GetEmitter()->emitIns_R_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, op3Reg, opt, sopt); @@ -2119,6 +2092,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { // GatherVector...(Vector mask, Vector addresses) + assert(intrin.numOperands == 2); GetEmitter()->emitIns_R_R_R_I(ins, emitSize, targetReg, op1Reg, op2Reg, 0, opt); } diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 78f6a31e32b0e..8a531918261a3 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -111,7 +111,6 @@ HARDWARE_INTRINSIC(Sve, GatherPrefetch64Bit, HARDWARE_INTRINSIC(Sve, GatherPrefetch8Bit, -1, -1, false, {INS_sve_prfb, INS_sve_prfb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Special, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialSideEffect_Other) HARDWARE_INTRINSIC(Sve, GatherVector, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1d, INS_sve_ld1d, INS_sve_ld1w, INS_sve_ld1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, GatherVectorByteZeroExtend, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_sve_ld1b, INS_sve_ld1b, INS_sve_ld1b, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, GatherVectorFirstFaulting, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldff1w, INS_sve_ldff1w, INS_sve_ldff1d, INS_sve_ldff1d, INS_sve_ldff1w, INS_sve_ldff1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, GatherVectorInt16SignExtend, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_sve_ld1sh, INS_sve_ld1sh, INS_sve_ld1sh, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, GatherVectorInt16WithByteOffsetsSignExtend, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_sve_ld1sh, INS_sve_ld1sh, INS_sve_ld1sh, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, GatherVectorInt32SignExtend, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sw, INS_sve_ld1sw, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index be09ce70fcf4e..a227d8ac14148 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -1775,50 +1775,6 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) break; } - case NI_Sve_GatherVectorFirstFaulting: - { - LIR::Use use; - bool foundUse = BlockRange().TryGetUse(node, &use); - - if (m_ffrTrashed) - { - // Consume the FFR register value from local variable to simulate "use" of FFR, - // only if it was trashed. If it was not trashed, we do not have to reload the - // contents of the FFR register. - - unsigned lclNum = comp->getFFRegisterVarNum(); - GenTree* lclVar = comp->gtNewLclvNode(lclNum, TYP_MASK); - BlockRange().InsertBefore(node, lclVar); - LowerNode(lclVar); - - if (node->GetOperandCount() == 3) - { - assert(node->GetAuxiliaryType() != TYP_UNKNOWN); - node->ResetHWIntrinsicId(intrinsicId, comp, node->Op(1), node->Op(2), node->Op(3), lclVar); - } - else - { - assert(node->GetOperandCount() == 2); - node->ResetHWIntrinsicId(intrinsicId, comp, node->Op(1), node->Op(2), lclVar); - } - } - - if (foundUse) - { - unsigned tmpNum = comp->lvaGrabTemp(true DEBUGARG("Return value result/FFR")); - LclVarDsc* tmpVarDsc = comp->lvaGetDesc(tmpNum); - tmpVarDsc->lvType = node->TypeGet(); - GenTree* storeLclVar; - use.ReplaceWithLclVar(comp, tmpNum, &storeLclVar); - } - else - { - node->SetUnusedValue(); - } - - StoreFFRValue(node); - break; - } case NI_Sve_LoadVectorFirstFaulting: { LIR::Use use; @@ -1830,8 +1786,7 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) // only if it was trashed. If it was not trashed, we do not have to reload the // contents of the FFR register. - unsigned lclNum = comp->getFFRegisterVarNum(); - GenTree* lclVar = comp->gtNewLclvNode(lclNum, TYP_MASK); + GenTree* lclVar = comp->gtNewLclvNode(comp->lvaFfrRegister, TYP_MASK); BlockRange().InsertBefore(node, lclVar); LowerNode(lclVar); @@ -4127,10 +4082,8 @@ void Lowering::StoreFFRValue(GenTreeHWIntrinsic* node) #ifdef DEBUG switch (node->GetHWIntrinsicId()) { - case NI_Sve_GatherVectorFirstFaulting: - case NI_Sve_LoadVectorFirstFaulting: case NI_Sve_SetFfr: - + case NI_Sve_LoadVectorFirstFaulting: break; default: assert(!"Unexpected HWIntrinsicId"); diff --git a/src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Unix.cs b/src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Unix.cs index 26626b50cbe9f..c8197b0055092 100644 --- a/src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Unix.cs +++ b/src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Unix.cs @@ -9,7 +9,10 @@ public static unsafe partial class BoundedMemory { private static UnixImplementation AllocateWithoutDataPopulationUnix(int elementCount, PoisonPagePlacement placement) where T : unmanaged { - return new UnixImplementation(elementCount, placement); + // On non-Windows platforms, we don't yet have support for changing the permissions of individual pages. + // We'll instead use AllocHGlobal / FreeHGlobal to carve out a r+w section of unmanaged memory. + + return new UnixImplementation(elementCount); } private sealed class UnixImplementation : BoundedMemory where T : unmanaged @@ -18,9 +21,9 @@ private sealed class UnixImplementation : BoundedMemory where T : unmanage private readonly int _elementCount; private readonly BoundedMemoryManager _memoryManager; - public UnixImplementation(int elementCount, PoisonPagePlacement placement) + public UnixImplementation(int elementCount) { - _handle = AllocHGlobalHandle.Allocate(checked(elementCount * (nint)sizeof(T)), placement); + _handle = AllocHGlobalHandle.Allocate(checked(elementCount * (nint)sizeof(T))); _elementCount = elementCount; _memoryManager = new BoundedMemoryManager(this); } @@ -115,77 +118,29 @@ public override void Unpin() private sealed class AllocHGlobalHandle : SafeHandle { - private IntPtr buffer; - private ulong allocationSize; - // Called by P/Invoke when returning SafeHandles - private AllocHGlobalHandle(IntPtr buffer, ulong allocationSize) + private AllocHGlobalHandle() : base(IntPtr.Zero, ownsHandle: true) { - this.buffer = buffer; - this.allocationSize = allocationSize; } - internal static AllocHGlobalHandle Allocate(nint byteLength, PoisonPagePlacement placement) + internal static AllocHGlobalHandle Allocate(nint byteLength) { - - // Allocate number of pages to incorporate required (byteLength bytes of) memory and an additional page to create a poison page. - int pageSize = Environment.SystemPageSize; - int allocationSize = (int)(((byteLength / pageSize) + ((byteLength % pageSize) == 0 ? 0 : 1) + 1) * pageSize); - IntPtr buffer = mmap(IntPtr.Zero, (ulong)allocationSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - if (buffer == IntPtr.Zero) - { - throw new InvalidOperationException($"Memory allocation failed with error {Marshal.GetLastPInvokeError()}."); - } - - // Depending on the PoisonPagePlacement requirement (before/after) initialise the baseAddress and poisonPageAddress to point to the location - // in the buffer. Here the baseAddress points to the first valid allocation and poisonPageAddress points to the first invalid location. - // For `PoisonPagePlacement.Before` the first page is made inaccessible using mprotect and baseAddress points to the start of the second page. - // The allocation and protection is at the granularity of a page. Thus, `PoisonPagePlacement.Before` configuration has an additional accessible - // memory at the end of the page (bytes equivalent to `pageSize - (byteLength % pageSize)`). - // For `PoisonPagePlacement.After`, we adjust the baseAddress so that inaccessible memory is at the `byteLength` offset from the baseAddress. - IntPtr baseAddress = buffer + pageSize; - IntPtr poisonPageAddress = buffer; - if (placement == PoisonPagePlacement.After) - { - baseAddress = buffer + (allocationSize - pageSize - byteLength); - poisonPageAddress = buffer + (allocationSize - pageSize); - } - - // Protect the page before/after based on the poison page placement. - if (mprotect(poisonPageAddress, (ulong) pageSize, PROT_NONE) == -1) - { - throw new InvalidOperationException($"Failed to mark page as a poison page using mprotect with error :{Marshal.GetLastPInvokeError()}."); - } - - AllocHGlobalHandle retVal = new AllocHGlobalHandle(buffer, (ulong)allocationSize); - retVal.SetHandle(baseAddress); // this base address would be used as the start of Span that is used during unit testing. + AllocHGlobalHandle retVal = new AllocHGlobalHandle(); + retVal.SetHandle(Marshal.AllocHGlobal(byteLength)); // this is for unit testing; don't bother setting up a CER on Full Framework return retVal; } + // Do not provide a finalizer - SafeHandle's critical finalizer will + // call ReleaseHandle for you. + public override bool IsInvalid => (handle == IntPtr.Zero); protected override bool ReleaseHandle() { - return munmap(buffer, allocationSize) == 0; + Marshal.FreeHGlobal(handle); + return true; } - - // Defined in - const int MAP_PRIVATE = 0x2; - const int MAP_ANONYMOUS = 0x20; - const int PROT_NONE = 0x0; - const int PROT_READ = 0x1; - const int PROT_WRITE = 0x2; - - [DllImport("libc", SetLastError = true)] - static extern IntPtr mmap(IntPtr address, ulong length, int prot, int flags, int fd, int offset); - - [DllImport("libc", SetLastError = true)] - static extern IntPtr munmap(IntPtr address, ulong length); - - [DllImport("libc", SetLastError = true)] - static extern int mprotect(IntPtr address, ulong length, int prot); } } } diff --git a/src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Windows.cs b/src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Windows.cs index d6dc353ed2daa..96f40d61492e5 100644 --- a/src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Windows.cs +++ b/src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Windows.cs @@ -33,7 +33,7 @@ private static WindowsImplementation AllocateWithoutDataPopulationWindows( // Reserve and commit the entire range as NOACCESS. - VirtualAllocHandle handle = VirtualAllocHandle.Allocate( + VirtualAllocHandle handle = UnsafeNativeMethods.VirtualAlloc( lpAddress: IntPtr.Zero, dwSize: (IntPtr)totalBytesToAllocate /* cast throws OverflowException if out of range */, flAllocationType: VirtualAllocAllocationType.MEM_RESERVE | VirtualAllocAllocationType.MEM_COMMIT, @@ -91,10 +91,9 @@ internal VirtualAllocProtection Protection try { _handle.DangerousAddRef(ref refAdded); - MEMORY_BASIC_INFORMATION memoryInfo; if (UnsafeNativeMethods.VirtualQuery( lpAddress: _handle.DangerousGetHandle() + _byteOffsetIntoHandle, - lpBuffer: &memoryInfo, + lpBuffer: out MEMORY_BASIC_INFORMATION memoryInfo, dwLength: (IntPtr)sizeof(MEMORY_BASIC_INFORMATION)) == IntPtr.Zero) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); @@ -118,12 +117,11 @@ internal VirtualAllocProtection Protection try { _handle.DangerousAddRef(ref refAdded); - VirtualAllocProtection flOldProtect; - if (UnsafeNativeMethods.VirtualProtect( + if (!UnsafeNativeMethods.VirtualProtect( lpAddress: _handle.DangerousGetHandle() + _byteOffsetIntoHandle, dwSize: (IntPtr)(&((T*)null)[_elementCount]), flNewProtect: value, - lpflOldProtect: &flOldProtect) == 0) + lpflOldProtect: out _)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); throw new InvalidOperationException("VirtualProtect failed unexpectedly."); @@ -281,41 +279,50 @@ public VirtualAllocHandle() { } - internal static VirtualAllocHandle Allocate(IntPtr lpAddress, IntPtr dwSize, VirtualAllocAllocationType flAllocationType, VirtualAllocProtection flProtect) - { - VirtualAllocHandle retVal = new VirtualAllocHandle(); - retVal.SetHandle(UnsafeNativeMethods.VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)); - return retVal; - } - // Do not provide a finalizer - SafeHandle's critical finalizer will // call ReleaseHandle for you. public override bool IsInvalid => (handle == IntPtr.Zero); protected override bool ReleaseHandle() => - UnsafeNativeMethods.VirtualFree(handle, IntPtr.Zero, VirtualAllocAllocationType.MEM_RELEASE) != 0; + UnsafeNativeMethods.VirtualFree(handle, IntPtr.Zero, VirtualAllocAllocationType.MEM_RELEASE); } - private static class UnsafeNativeMethods + private static partial class UnsafeNativeMethods { private const string KERNEL32_LIB = "kernel32.dll"; // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx - [DllImport(KERNEL32_LIB, SetLastError = true)] - public static extern IntPtr VirtualAlloc(IntPtr lpAddress, IntPtr dwSize, VirtualAllocAllocationType flAllocationType, VirtualAllocProtection flProtect); + [LibraryImport(KERNEL32_LIB, SetLastError = true)] + public static partial VirtualAllocHandle VirtualAlloc( + IntPtr lpAddress, + IntPtr dwSize, + VirtualAllocAllocationType flAllocationType, + VirtualAllocProtection flProtect); // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366892(v=vs.85).aspx - [DllImport(KERNEL32_LIB, SetLastError = true)] - public static extern int VirtualFree(IntPtr lpAddress, IntPtr dwSize, VirtualAllocAllocationType dwFreeType); + [LibraryImport(KERNEL32_LIB, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool VirtualFree( + IntPtr lpAddress, + IntPtr dwSize, + VirtualAllocAllocationType dwFreeType); // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspx - [DllImport(KERNEL32_LIB, SetLastError = true)] - public static extern int VirtualProtect(IntPtr lpAddress, IntPtr dwSize, VirtualAllocProtection flNewProtect, VirtualAllocProtection* lpflOldProtect); + [LibraryImport(KERNEL32_LIB, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool VirtualProtect( + IntPtr lpAddress, + IntPtr dwSize, + VirtualAllocProtection flNewProtect, + out VirtualAllocProtection lpflOldProtect); // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366902(v=vs.85).aspx - [DllImport(KERNEL32_LIB, SetLastError = true)] - public static extern IntPtr VirtualQuery(IntPtr lpAddress, MEMORY_BASIC_INFORMATION* lpBuffer, IntPtr dwLength); + [LibraryImport(KERNEL32_LIB, SetLastError = true)] + public static partial IntPtr VirtualQuery( + IntPtr lpAddress, + out MEMORY_BASIC_INFORMATION lpBuffer, + IntPtr dwLength); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index b815c360381e8..439b40a02dcf5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -3624,118 +3624,6 @@ internal Arm64() { } public static unsafe Vector GatherVectorByteZeroExtend(Vector mask, byte* address, Vector indices) { throw new PlatformNotSupportedException(); } - /// - /// svfloat64_t svldff1_gather_[s64]index[_f64](svbool_t pg, const float64_t *base, svint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, double* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// - /// svfloat64_t svldff1_gather[_u64base]_f64(svbool_t pg, svuint64_t bases) - /// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } - - /// - /// svfloat64_t svldff1_gather_[u64]index[_f64](svbool_t pg, const float64_t *base, svuint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, double* address, Vector indices) { throw new PlatformNotSupportedException(); } - - // - // svint32_t svldff1_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) - // LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0] - // - // Removed as per #103297 - // public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } - - /// - /// svint32_t svldff1_gather_[s32]index[_s32](svbool_t pg, const int32_t *base, svint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, SXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, int* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// - /// svint32_t svldff1_gather_[u32]index[_s32](svbool_t pg, const int32_t *base, svuint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, UXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, int* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// - /// svint64_t svldff1_gather[_u64base]_s64(svbool_t pg, svuint64_t bases) - /// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } - - /// - /// svint64_t svldff1_gather_[s64]index[_s64](svbool_t pg, const int64_t *base, svint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, long* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// - /// svint64_t svldff1_gather_[u64]index[_s64](svbool_t pg, const int64_t *base, svuint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, long* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// - /// svfloat32_t svldff1_gather_[s32]index[_f32](svbool_t pg, const float32_t *base, svint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, SXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, float* address, Vector indices) { throw new PlatformNotSupportedException(); } - - // - // svfloat32_t svldff1_gather[_u32base]_f32(svbool_t pg, svuint32_t bases) - // LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0] - // - // Removed as per #103297 - // public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } - - /// - /// svfloat32_t svldff1_gather_[u32]index[_f32](svbool_t pg, const float32_t *base, svuint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, UXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, float* address, Vector indices) { throw new PlatformNotSupportedException(); } - - // - // svuint32_t svldff1_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) - // LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0] - // - // Removed as per #103297 - // public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } - - /// - /// svuint32_t svldff1_gather_[s32]index[_u32](svbool_t pg, const uint32_t *base, svint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, SXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, uint* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// - /// svuint32_t svldff1_gather_[u32]index[_u32](svbool_t pg, const uint32_t *base, svuint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, UXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, uint* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svldff1_gather[_u64base]_u64(svbool_t pg, svuint64_t bases) - /// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svldff1_gather_[s64]index[_u64](svbool_t pg, const uint64_t *base, svint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, ulong* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svldff1_gather_[u64]index[_u64](svbool_t pg, const uint64_t *base, svuint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, ulong* address, Vector indices) { throw new PlatformNotSupportedException(); } - - /// Load 16-bit data and sign-extend /// @@ -4401,55 +4289,6 @@ internal Arm64() { } public static unsafe ulong GetActiveElementCount(Vector mask, Vector from) { throw new PlatformNotSupportedException(); } - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrByte() { throw new PlatformNotSupportedException(); } - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrInt16() { throw new PlatformNotSupportedException(); } - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrInt32() { throw new PlatformNotSupportedException(); } - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrInt64() { throw new PlatformNotSupportedException(); } - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrSByte() { throw new PlatformNotSupportedException(); } - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrUInt16() { throw new PlatformNotSupportedException(); } - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrUInt32() { throw new PlatformNotSupportedException(); } - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrUInt64() { throw new PlatformNotSupportedException(); } - - /// Insert scalar into shifted vector /// @@ -4935,67 +4774,6 @@ internal Arm64() { } public static unsafe Vector LoadVectorByteZeroExtendToUInt64(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } - /// - /// svuint8_t svldff1[_u8](svbool_t pg, const uint8_t *base) - /// LDFF1B Zresult.B, Pg/Z, [Xbase, XZR] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } - - /// - /// svfloat64_t svldff1[_f64](svbool_t pg, const float64_t *base) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, double* address) { throw new PlatformNotSupportedException(); } - - /// - /// svint16_t svldff1[_s16](svbool_t pg, const int16_t *base) - /// LDFF1H Zresult.H, Pg/Z, [Xbase, XZR, LSL #1] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, short* address) { throw new PlatformNotSupportedException(); } - - /// - /// svint32_t svldff1[_s32](svbool_t pg, const int32_t *base) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, int* address) { throw new PlatformNotSupportedException(); } - - /// - /// svint64_t svldff1[_s64](svbool_t pg, const int64_t *base) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, long* address) { throw new PlatformNotSupportedException(); } - - /// - /// svint8_t svldff1[_s8](svbool_t pg, const int8_t *base) - /// LDFF1B Zresult.B, Pg/Z, [Xbase, XZR] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } - - /// - /// svfloat32_t svldff1[_f32](svbool_t pg, const float32_t *base) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, float* address) { throw new PlatformNotSupportedException(); } - - /// - /// svuint16_t svldff1[_u16](svbool_t pg, const uint16_t *base) - /// LDFF1H Zresult.H, Pg/Z, [Xbase, XZR, LSL #1] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } - - /// - /// svuint32_t svldff1[_u32](svbool_t pg, const uint32_t *base) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, uint* address) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svldff1[_u64](svbool_t pg, const uint64_t *base) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, ulong* address) { throw new PlatformNotSupportedException(); } - - /// LoadVectorInt16SignExtendToInt32 : Load 16-bit data and sign-extend /// @@ -7905,55 +7683,6 @@ internal Arm64() { } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) { throw new PlatformNotSupportedException(); } - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) { throw new PlatformNotSupportedException(); } - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) { throw new PlatformNotSupportedException(); } - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) { throw new PlatformNotSupportedException(); } - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) { throw new PlatformNotSupportedException(); } - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) { throw new PlatformNotSupportedException(); } - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) { throw new PlatformNotSupportedException(); } - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) { throw new PlatformNotSupportedException(); } - - /// Logical shift left /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index b9e7001b954c7..a79e2b4bf4e5a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -3681,119 +3681,6 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorByteZeroExtend(Vector mask, byte* address, Vector indices) => GatherVectorByteZeroExtend(mask, address, indices); - - /// - /// svfloat64_t svldff1_gather_[s64]index[_f64](svbool_t pg, const float64_t *base, svint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, double* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// - /// svfloat64_t svldff1_gather[_u64base]_f64(svbool_t pg, svuint64_t bases) - /// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) => GatherVectorFirstFaulting(mask, addresses); - - /// - /// svfloat64_t svldff1_gather_[u64]index[_f64](svbool_t pg, const float64_t *base, svuint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, double* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - // - // svint32_t svldff1_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) - // LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0] - // - // Removed as per #103297 - // public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) => GatherVectorFirstFaulting(mask, addresses); - - /// - /// svint32_t svldff1_gather_[s32]index[_s32](svbool_t pg, const int32_t *base, svint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, SXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, int* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// - /// svint32_t svldff1_gather_[u32]index[_s32](svbool_t pg, const int32_t *base, svuint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, UXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, int* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// - /// svint64_t svldff1_gather[_u64base]_s64(svbool_t pg, svuint64_t bases) - /// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) => GatherVectorFirstFaulting(mask, addresses); - - /// - /// svint64_t svldff1_gather_[s64]index[_s64](svbool_t pg, const int64_t *base, svint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, long* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// - /// svint64_t svldff1_gather_[u64]index[_s64](svbool_t pg, const int64_t *base, svuint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, long* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// - /// svfloat32_t svldff1_gather_[s32]index[_f32](svbool_t pg, const float32_t *base, svint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, SXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, float* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - // - // svfloat32_t svldff1_gather[_u32base]_f32(svbool_t pg, svuint32_t bases) - // LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0] - // - // Removed as per #103297 - // public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) => GatherVectorFirstFaulting(mask, addresses); - - /// - /// svfloat32_t svldff1_gather_[u32]index[_f32](svbool_t pg, const float32_t *base, svuint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, UXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, float* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - // - // svuint32_t svldff1_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) - // LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0] - // - // Removed as per #103297 - // public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) => GatherVectorFirstFaulting(mask, addresses); - - /// - /// svuint32_t svldff1_gather_[s32]index[_u32](svbool_t pg, const uint32_t *base, svint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, SXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, uint* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// - /// svuint32_t svldff1_gather_[u32]index[_u32](svbool_t pg, const uint32_t *base, svuint32_t indices) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, Zindices.S, UXTW #2] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, uint* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// - /// svuint64_t svldff1_gather[_u64base]_u64(svbool_t pg, svuint64_t bases) - /// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, Vector addresses) => GatherVectorFirstFaulting(mask, addresses); - - /// - /// svuint64_t svldff1_gather_[s64]index[_u64](svbool_t pg, const uint64_t *base, svint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, ulong* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// - /// svuint64_t svldff1_gather_[u64]index[_u64](svbool_t pg, const uint64_t *base, svuint64_t indices) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, Zindices.D, LSL #3] - /// - public static unsafe Vector GatherVectorFirstFaulting(Vector mask, ulong* address, Vector indices) => GatherVectorFirstFaulting(mask, address, indices); - - /// Load 16-bit data and sign-extend /// @@ -4459,55 +4346,6 @@ internal Arm64() { } public static unsafe ulong GetActiveElementCount(Vector mask, Vector from) => GetActiveElementCount(mask, from); - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrByte() => GetFfrByte(); - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrInt16() => GetFfrInt16(); - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrInt32() => GetFfrInt32(); - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrInt64() => GetFfrInt64(); - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrSByte() => GetFfrSByte(); - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrUInt16() => GetFfrUInt16(); - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrUInt32() => GetFfrUInt32(); - - /// - /// svbool_t svrdffr() - /// RDFFR Presult.B - /// - public static Vector GetFfrUInt64() => GetFfrUInt64(); - - /// Insert scalar into shifted vector /// @@ -4992,67 +4830,6 @@ internal Arm64() { } public static unsafe Vector LoadVectorByteZeroExtendToUInt64(Vector mask, byte* address) => LoadVectorByteZeroExtendToUInt64(mask, address); - /// - /// svuint8_t svldff1[_u8](svbool_t pg, const uint8_t *base) - /// LDFF1B Zresult.B, Pg/Z, [Xbase, XZR] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, byte* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svfloat64_t svldff1[_f64](svbool_t pg, const float64_t *base) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, double* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svint16_t svldff1[_s16](svbool_t pg, const int16_t *base) - /// LDFF1H Zresult.H, Pg/Z, [Xbase, XZR, LSL #1] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, short* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svint32_t svldff1[_s32](svbool_t pg, const int32_t *base) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, int* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svint64_t svldff1[_s64](svbool_t pg, const int64_t *base) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, long* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svint8_t svldff1[_s8](svbool_t pg, const int8_t *base) - /// LDFF1B Zresult.B, Pg/Z, [Xbase, XZR] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, sbyte* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svfloat32_t svldff1[_f32](svbool_t pg, const float32_t *base) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, float* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svuint16_t svldff1[_u16](svbool_t pg, const uint16_t *base) - /// LDFF1H Zresult.H, Pg/Z, [Xbase, XZR, LSL #1] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, ushort* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svuint32_t svldff1[_u32](svbool_t pg, const uint32_t *base) - /// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, uint* address) => LoadVectorFirstFaulting(mask, address); - - /// - /// svuint64_t svldff1[_u64](svbool_t pg, const uint64_t *base) - /// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3] - /// - public static unsafe Vector LoadVectorFirstFaulting(Vector mask, ulong* address) => LoadVectorFirstFaulting(mask, address); - - /// LoadVectorInt16SignExtendToInt32 : Load 16-bit data and sign-extend /// @@ -7950,55 +7727,6 @@ internal Arm64() { } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) => SetFfr(value); - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) => SetFfr(value); - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) => SetFfr(value); - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) => SetFfr(value); - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) => SetFfr(value); - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) => SetFfr(value); - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) => SetFfr(value); - - /// - /// void svwrffr(svbool_t op) - /// WRFFR Pop.B - /// - public static unsafe void SetFfr(Vector value) => SetFfr(value); - - /// Logical shift left /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 235abf9affcf7..2dc63bb054ea8 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4882,26 +4882,6 @@ internal Arm64() { } public static unsafe System.Numerics.Vector GatherVectorByteZeroExtend(System.Numerics.Vector mask, byte* address, System.Numerics.Vector indices) { throw null; } public static System.Numerics.Vector GatherVectorByteZeroExtend(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorByteZeroExtend(System.Numerics.Vector mask, byte* address, System.Numerics.Vector indices) { throw null; } - - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, double* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, double* address, System.Numerics.Vector indices) { throw null; } - // public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, int* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, int* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, long* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, long* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, float* address, System.Numerics.Vector indices) { throw null; } - // public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, float* address, System.Numerics.Vector indices) { throw null; } - // public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, uint* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, uint* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, ulong* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorFirstFaulting(System.Numerics.Vector mask, ulong* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorInt16SignExtend(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } // public static System.Numerics.Vector GatherVectorInt16SignExtend(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtend(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } @@ -5009,15 +4989,6 @@ internal Arm64() { } public static ulong GetActiveElementCount(System.Numerics.Vector mask, System.Numerics.Vector from) { throw null; } public static ulong GetActiveElementCount(System.Numerics.Vector mask, System.Numerics.Vector from) { throw null; } - public static System.Numerics.Vector GetFfrByte() { throw null; } - public static System.Numerics.Vector GetFfrInt16() { throw null; } - public static System.Numerics.Vector GetFfrInt32() { throw null; } - public static System.Numerics.Vector GetFfrInt64() { throw null; } - public static System.Numerics.Vector GetFfrSByte() { throw null; } - public static System.Numerics.Vector GetFfrUInt16() { throw null; } - public static System.Numerics.Vector GetFfrUInt32() { throw null; } - public static System.Numerics.Vector GetFfrUInt64() { throw null; } - public static System.Numerics.Vector LeadingSignCount(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector LeadingSignCount(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector LeadingSignCount(System.Numerics.Vector value) { throw null; } @@ -5092,18 +5063,6 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt16(System.Numerics.Vector mask, byte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt32(System.Numerics.Vector mask, byte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt64(System.Numerics.Vector mask, byte* address) { throw null; } - - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, byte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, double* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, short* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, int* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, long* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, sbyte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, float* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, ushort* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, uint* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, ulong* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToInt32(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToInt64(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToUInt32(System.Numerics.Vector mask, short* address) { throw null; } @@ -5524,15 +5483,6 @@ internal Arm64() { } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } - public static unsafe void SetFfr(System.Numerics.Vector value) { throw null; } - public static unsafe void SetFfr(System.Numerics.Vector value) { throw null; } - public static unsafe void SetFfr(System.Numerics.Vector value) { throw null; } - public static unsafe void SetFfr(System.Numerics.Vector value) { throw null; } - public static unsafe void SetFfr(System.Numerics.Vector value) { throw null; } - public static unsafe void SetFfr(System.Numerics.Vector value) { throw null; } - public static unsafe void SetFfr(System.Numerics.Vector value) { throw null; } - public static unsafe void SetFfr(System.Numerics.Vector value) { throw null; } - public static System.Numerics.Vector ShiftLeftLogical(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ShiftLeftLogical(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ShiftLeftLogical(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index beb23342bc872..013db7b69edcb 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -3516,15 +3516,6 @@ ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "SveExtractVector_UInt32_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "SveExtractVector_UInt64_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_byte", ["VectorBaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_short", ["VectorBaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_int", ["VectorBaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_long", ["VectorBaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_sbyte", ["VectorBaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_ushort", ["VectorBaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_uint", ["VectorBaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_ulong", ["VectorBaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()"}), - // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetSingle()"}), // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), @@ -3648,23 +3639,6 @@ ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetDouble()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), @@ -3724,17 +3698,6 @@ ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_uint", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Cast"] = "(uint*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Cast"] = "(ulong*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_float", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_double", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index c7ca861fbcb0a..5dc35e1c674c8 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -8507,308 +8507,6 @@ public static T[] CreateBreakBeforePropagateMask(T[] mask, T[] op1, T[] op2) return result; } - private static T ConditionalSelectResult(T maskResult, T result, T falseResult) where T : INumberBase - { - return (maskResult != T.Zero) ? result : falseResult; - } - - private static T ConditionalSelectTrueResult(T maskResult, T result, T trueResult) where T : INumberBase - { - return (maskResult != T.Zero) ? trueResult : result; - } - - - private static bool CheckLoadVectorBehaviorCore(T[] firstOp, T[] result, Func map) where T : INumberBase - { - for (var i = 0; i < firstOp.Length; i++) - { - T loadResult = firstOp[i]; - loadResult = map(i, loadResult); - if (result[i] != loadResult) - { - return false; - } - } - return true; - } - - public static bool CheckLoadVectorBehavior(T[] firstOp, T[] result) where T : INumberBase - { - return CheckLoadVectorBehaviorCore(firstOp, result, (_, loadResult) => loadResult); - } - - public static bool CheckLoadVectorBehavior(T[] maskOp, T[] firstOp, T[] result, T[] falseOp) where T : INumberBase - { - return CheckLoadVectorBehaviorCore(firstOp, result, (i, loadResult) => ConditionalSelectResult(maskOp[i], loadResult, falseOp[i])); - } - - private static T GetGatherVectorResultByIndex(int index, T[] mask, ExtendedElementT[] data, Index[] indices) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - { - return (mask[index] == T.Zero) ? T.Zero : T.CreateTruncating(data[int.CreateChecked(indices[index])]); - } - - private static unsafe T GetGatherVectorBasesResultByIndex(int index, T[] mask, AddressT[] data) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - { - return (mask[index] == T.Zero) ? T.Zero : T.CreateTruncating(*(ExtendedElementT*)Unsafe.BitCast(data[index])); - } - - private static bool CheckGatherVectorBehaviorCore(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result, Func map) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - { - for (var i = 0; i < mask.Length; i++) - { - T gatherResult = GetGatherVectorResultByIndex(i, mask, data, indices); - gatherResult = map(i, gatherResult); - if (result[i] != gatherResult) - { - return false; - } - } - return true; - } - - private static bool CheckGatherVectorBasesBehaviorCore(T[] mask, AddressT[] data, T[] result, Func map) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - { - for (var i = 0; i < mask.Length; i++) - { - T gatherResult = GetGatherVectorBasesResultByIndex(i, mask, data); - gatherResult = map(i, gatherResult); - if (result[i] != gatherResult) - { - return false; - } - } - return true; - } - - public static bool CheckGatherVectorBehavior(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - { - return CheckGatherVectorBehaviorCore(mask, data, indices, result, (_, gatherResult) => gatherResult); - } - - public static bool CheckGatherVectorConditionalSelectBehavior(T[] cndSelMask, T[] mask, ExtendedElementT[] data, Index[] indices, T[] cndSelFalse, T[] result) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - { - return CheckGatherVectorBehaviorCore(mask, data, indices, result, (i, gatherResult) => ConditionalSelectResult(cndSelMask[i], gatherResult, cndSelFalse[i])); - } - - public static bool CheckGatherVectorConditionalSelectTrueBehavior(T[] cndSelMask, T[] mask, ExtendedElementT[] data, Index[] indices, T[] cndSelTrue, T[] result) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - { - return CheckGatherVectorBehaviorCore(mask, data, indices, result, (i, gatherResult) => ConditionalSelectTrueResult(cndSelMask[i], gatherResult, cndSelTrue[i])); - } - - - public static bool CheckGatherVectorBasesBehavior(T[] mask, AddressT[] data, T[] result) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - { - return CheckGatherVectorBasesBehaviorCore(mask, data, result, (_, gatherResult) => gatherResult); - } - - public static bool CheckGatherVectorBasesConditionalSelectBehavior(T[] cndSelMask, T[] mask, AddressT[] data, T[] cndSelFalse, T[] result) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - { - return CheckGatherVectorBasesBehaviorCore(mask, data, result, (i, gatherResult) => ConditionalSelectResult(cndSelMask[i], gatherResult, cndSelFalse[i])); - } - - public static bool CheckGatherVectorBasesConditionalSelectTrueBehavior(T[] cndSelMask, T[] mask, AddressT[] data, T[] cndSelTrue, T[] result) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - { - return CheckGatherVectorBasesBehaviorCore(mask, data, result, (i, gatherResult) => ConditionalSelectTrueResult(cndSelMask[i], gatherResult, cndSelTrue[i])); - } - - private static bool CheckFirstFaultingBehaviorCore(T[] result, Vector faultResult, Func checkIter) - where T : INumberBase - where TFault : INumberBase - { - bool hitFault = false; - - for (var i = 0; i < result.Length; i++) - { - if (hitFault) - { - if (faultResult[i] != TFault.Zero) - { - return false; - } - } - else - { - if (faultResult[i] == TFault.Zero) - { - // There has to be a valid value for the first element, so check it. - if (i == 0) - { - return false; - } - hitFault = true; - } - else - { - if (!checkIter(i)) - { - return false; - } - } - } - } - - return true; - } - - private static bool CheckFaultResultHasAtLeastOneZero(Vector faultResult) where T : INumberBase - { - for (var i = 0; i < Vector.Count; i++) - { - if (faultResult[i] == T.Zero) - { - return true; - } - } - return false; - } - - public static bool CheckLoadVectorFirstFaultingBehavior(T[] firstOp, T[] result, Vector faultResult) - where T : INumberBase - where TFault : INumberBase - { - // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. - if (!CheckFaultResultHasAtLeastOneZero(faultResult)) - { - TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); - return false; - } - - var validElementCount = firstOp.Length; - var expectedFaultResult = - InitVector(i => - { - if (i < validElementCount) - { - return TFault.One; - } - return TFault.Zero; - }); - if (expectedFaultResult != faultResult) - { - TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); - return false; - } - - return CheckFirstFaultingBehaviorCore(result, faultResult, i => firstOp[i] == result[i]); - } - - public static bool CheckGatherVectorFirstFaultingBehavior(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result, Vector faultResult) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - where TFault : INumberBase - { - // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. - if (!CheckFaultResultHasAtLeastOneZero(faultResult)) - { - TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); - return false; - } - - var hasFaulted = false; - var expectedFaultResult = - InitVector(i => - { - if (hasFaulted) - { - return TFault.Zero; - } - - if (mask[i] == T.Zero) - { - return TFault.One; - } - - var index = int.CreateChecked(indices[i]); - if (index < 0 || index >= data.Length) - { - hasFaulted = true; - return TFault.Zero; - } - return TFault.One; - }); - if (expectedFaultResult != faultResult) - { - TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); - return false; - } - - return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorResultByIndex(i, mask, data, indices) == result[i]); - } - - public static bool CheckGatherVectorBasesFirstFaultingBehavior(T[] mask, AddressT[] data, T[] result, Vector faultResult) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - where TFault : INumberBase - { - // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. - if (!CheckFaultResultHasAtLeastOneZero(faultResult)) - { - TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); - return false; - } - - var hasFaulted = false; - var expectedFaultResult = - InitVector(i => - { - if (hasFaulted) - { - return TFault.Zero; - } - - if (mask[i] == T.Zero) - { - return TFault.One; - } - - if (data[i] == AddressT.Zero) - { - hasFaulted = true; - return TFault.Zero; - } - return TFault.One; - }); - if (expectedFaultResult != faultResult) - { - TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); - return false; - } - - return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorBasesResultByIndex(i, mask, data) == result[i]); - } - public static T[] CreateBreakPropagateMask(T[] op1, T[] op2) where T : IBinaryInteger { var count = op1.Length; diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveFfrTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveFfrTest.template deleted file mode 100644 index b16742a718121..0000000000000 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveFfrTest.template +++ /dev/null @@ -1,333 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/****************************************************************************** - * This file is auto-generated from a template file by the GenerateTests.csx * - * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * - * changes, please update the corresponding template and run according to the * - * directions listed in the file. * - ******************************************************************************/ - -using System; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using Xunit; - -namespace JIT.HardwareIntrinsics.Arm -{ - public static partial class Program - { - [Fact] - public static void {TestName}() - { - var test = new SveFfrTest__{TestName}(); - - if (test.IsSupported) - { - // Validates basic functionality works, using Unsafe.Read - test.RunBasicScenario_UnsafeRead(); - - if (Sve.IsSupported) - { - // Validates basic functionality works, using Load - test.RunBasicScenario_Load(); - } - - // Validates calling via reflection works, using Unsafe.Read - test.RunReflectionScenario_UnsafeRead(); - - // Validates passing a local works, using Unsafe.Read - test.RunLclVarScenario_UnsafeRead(); - - // Validates passing an instance member of a class works - test.RunClassFldScenario(); - - // Validates passing the field of a local struct works - test.RunStructLclFldScenario(); - - // Validates passing an instance member of a struct works - test.RunStructFldScenario(); - } - else - { - // Validates we throw on unsupported hardware - test.RunUnsupportedScenario(); - } - - if (!test.Succeeded) - { - throw new Exception("One or more scenarios did not complete as expected."); - } - } - } - - public sealed unsafe class SveFfrTest__{TestName} - { - private struct DataTable - { - private byte[] inArray1; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle outHandle; - - private ulong alignment; - - public DataTable({VectorBaseType}[] inArray1, {VectorBaseType}[] outArray, int alignment) - { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{VectorBaseType}>(); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{VectorBaseType}>(); - if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); - } - - this.inArray1 = new byte[alignment * 2]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - this.alignment = (ulong)alignment; - - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{VectorBaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); - } - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - - private struct TestStruct - { - public Vector<{VectorBaseType}> _fld1; - - public static TestStruct Create() - { - var testStruct = new TestStruct(); - - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As<{VectorBaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf>()); - - return testStruct; - } - - public void RunStructFldScenario(SveFfrTest__{TestName} testClass) - { - Sve.SetFfr(_fld1); - var result = Sve.GetFfr{VectorBaseType}(); - - Unsafe.Write(testClass._dataTable.outArrayPtr, result); - testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); - } - } - - private static readonly int LargestVectorSize = {LargestVectorSize}; - - private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof({VectorBaseType}); - private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof({VectorBaseType}); - - private static {VectorBaseType}[] _maskData = new {VectorBaseType}[Op1ElementCount]; - private static {VectorBaseType}[] _data1 = new {VectorBaseType}[Op1ElementCount]; - - private Vector<{VectorBaseType}> _mask; - private Vector<{VectorBaseType}> _fld1; - private Vector<{VectorBaseType}> _falseFld; - - private DataTable _dataTable; - - public SveFfrTest__{TestName}() - { - Succeeded = true; - - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({VectorBaseType})({NextValueOp1} % 2); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _mask), ref Unsafe.As<{VectorBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf>()); - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As<{VectorBaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _falseFld), ref Unsafe.As<{VectorBaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf>()); - - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - _dataTable = new DataTable(_data1, new {VectorBaseType}[RetElementCount], LargestVectorSize); - } - - public bool IsSupported => Sve.IsSupported; - - public bool Succeeded { get; set; } - - public void RunBasicScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - - Sve.SetFfr( - Unsafe.Read>(_dataTable.inArray1Ptr) - ); - - // call to make sure FFR contents are preserved - Console.WriteLine(""); - - var result = Sve.GetFfr{VectorBaseType}(); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - - Vector<{VectorBaseType}> loadMask = Sve.CreateTrueMask{VectorBaseType}(SveMaskPattern.All); - - Sve.SetFfr( - Sve.LoadVector(loadMask, ({VectorBaseType}*)(_dataTable.inArray1Ptr)) - ); - - // call to make sure FFR contents are preserved - Console.WriteLine(""); - - var result = Sve.GetFfr{VectorBaseType}(); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunReflectionScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - - typeof(Sve).GetMethod(nameof(Sve.SetFfr), new Type[] { typeof(Vector<{VectorBaseType}>) }) - .Invoke(null, new object[] { - Unsafe.Read>(_dataTable.inArray1Ptr) - }); - - var result = typeof(Sve).GetMethod(nameof(Sve.GetFfr{VectorBaseType}), new Type[] { }) - .Invoke(null, new object[] { }); - - // We cannot validate the results because the FFR register is trashed. - // Unsafe.Write(_dataTable.outArrayPtr, (Vector<{VectorBaseType}>)(result)); - // ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunLclVarScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); - - var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); - Sve.SetFfr(op1); - var result = Sve.GetFfr{VectorBaseType}(); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(op1, _dataTable.outArrayPtr); - } - - public void RunClassFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - - Sve.SetFfr(_fld1); - var result = Sve.GetFfr{VectorBaseType}(); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_fld1, _dataTable.outArrayPtr); - } - - public void RunStructLclFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); - - var test = TestStruct.Create(); - Sve.SetFfr(test._fld1); - var result = Sve.GetFfr{VectorBaseType}(); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(test._fld1, _dataTable.outArrayPtr); - } - - public void RunStructFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); - - var test = TestStruct.Create(); - test.RunStructFldScenario(this); - } - - public void RunUnsupportedScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); - - bool succeeded = false; - - try - { - RunBasicScenario_UnsafeRead(); - } - catch (PlatformNotSupportedException) - { - succeeded = true; - } - - if (!succeeded) - { - Succeeded = false; - } - } - - private void ValidateResult(Vector<{VectorBaseType}> op1, void* result, [CallerMemberName] string method = "") - { - {VectorBaseType}[] inArray1 = new {VectorBaseType}[Op1ElementCount]; - {VectorBaseType}[] outArray = new {VectorBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{VectorBaseType}, byte>(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{VectorBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); - - ValidateResult(inArray1, outArray, method); - } - - private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") - { - {VectorBaseType}[] inArray1 = new {VectorBaseType}[Op1ElementCount]; - {VectorBaseType}[] outArray = new {VectorBaseType}[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{VectorBaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{VectorBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); - - ValidateResult(inArray1, outArray, method); - } - - private void ValidateResult({VectorBaseType}[] firstOp, {VectorBaseType}[] result, [CallerMemberName] string method = "") - { - bool succeeded = true; - - for (var i = 0; i < firstOp.Length; i++) - { - if (firstOp[i] != result[i]) - { - succeeded = false; - break; - } - } - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof(Sve)}.{nameof(Sve.SetFfr)}<{VectorBaseType}>(Vector<{VectorBaseType}>): SetFfr failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - } -} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorFirstFaultingIndices.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorFirstFaultingIndices.template deleted file mode 100644 index f06ff9f2e2e6d..0000000000000 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorFirstFaultingIndices.template +++ /dev/null @@ -1,662 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/****************************************************************************** - * This file is auto-generated from a template file by the GenerateTests.csx * - * script in tests\src\JIT\HardwareIntrinsics\Arm\Shared. In order to make * - * changes, please update the corresponding template and run according to the * - * directions listed in the file. * - ******************************************************************************/ - -using System; -using System.Buffers; -using System.Numerics; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using Xunit; - -namespace JIT.HardwareIntrinsics.Arm -{ - public static partial class Program - { - [Fact] - public static void {TestName}() - { - var test = new SveGatherVectorIndices__{TestName}(); - - if (test.IsSupported) - { - // Validates basic functionality works, using Unsafe.Read - test.RunBasicScenario_UnsafeRead(); - - // Validates basic functionality works - test.RunBasicScenario_Load(); - - // Validates basic functionality of first-faulting behavior - test.RunBasicScenario_LoadFirstFaulting(); - - // Validates fully masked out load works. - test.RunBasicScenario_FalseMask(); - - // Validates fully masked out load with invalid address works. - test.RunBasicScenario_NonFaulting(); - - // Validates calling via reflection works, using Unsafe.Read - test.RunReflectionScenario_UnsafeRead(); - - // Validates passing a local works, using Unsafe.Read - test.RunLclVarScenario_UnsafeRead(); - - // Validates passing an instance member of a class works - test.RunClassFldScenario(); - - // Validates passing the field of a local struct works - test.RunStructLclFldScenario(); - - // Validates passing an instance member of a struct works - test.RunStructFldScenario(); - - // Validates using inside ConditionalSelect with value falseValue - // Currently, using this operation in ConditionalSelect() gives incorrect result - // when falseReg == targetReg because this instruction uses Pg/Z to update the targetReg - // instead of Pg/M to merge it. As such, the value of falseReg is lost. Ideally, such - // instructions should be marked similar to RMW (a different flag name) to make sure that - // we do not assign falseReg/targetReg same. Then, we would do something like this: - // - // ldnf1sh target, pg/z, [x0] - // sel mask, target, target, falseReg - // - // This needs more careful thinking, so disabling it for now. - // test.ConditionalSelect_FalseOp(); - - // Validates using inside ConditionalSelect with zero falseValue - test.ConditionalSelect_ZeroOp(); - } - else - { - // Validates we throw on unsupported hardware - test.RunUnsupportedScenario(); - } - - if (!test.Succeeded) - { - throw new Exception("One or more scenarios did not complete as expected."); - } - } - } - - public sealed unsafe class SveGatherVectorIndices__{TestName} - { - private struct DataTable - { - private byte[] inArray1; - private byte[] inArray2; - private byte[] inArray3; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle inHandle2; - private GCHandle inHandle3; - private GCHandle outHandle; - - private ulong 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<{Op2BaseType}>(); - int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>(); - int sizeOfinBounded = new Random().Next(Unsafe.SizeOf<{Op2BaseType}>(), Vector<{Op2BaseType}>.Count * Unsafe.SizeOf<{Op2BaseType}>() - 1); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - - if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfinArray2: {sizeOfinArray2}, sizeOfinArray3: {sizeOfinArray3}, sizeOfoutArray: {sizeOfoutArray}"); - } - - this.inArray1 = new byte[alignment * 2]; - this.inArray2 = new byte[alignment + sizeOfinArray2]; - this.inArray3 = new byte[alignment * 2]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); - this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - this.alignment = (ulong)alignment; - - this.inBounded = BoundedMemory.Allocate(sizeOfinBounded, PoisonPagePlacement.After); - - 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<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); - Unsafe.CopyBlockUnaligned(ref inBounded.Span.GetPinnableReference(), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinBounded); - } - - public BoundedMemory inBounded; - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); - public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - inHandle3.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - - private struct TestStruct - { - public {Op1VectorType}<{Op1BaseType}> _fld1; - public {Op2BaseType}* _fld2; - public {Op3VectorType}<{Op3BaseType}> _fld3; - - public static TestStruct Create(DataTable _dataTable) - { - var testStruct = new TestStruct(); - - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } - - // Ensure all values of _data3 fit within the number of _data2 elements - for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3} % ({Op3BaseType})Op2ElementCount; } - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); - - testStruct._fld2 = ({Op2BaseType}*)_dataTable.inArray2Ptr; - - return testStruct; - } - - public void RunStructFldScenario(SveGatherVectorIndices__{TestName} testClass) - { - var result = {Isa}.{Method}(_fld1, _fld2, _fld3); - - Unsafe.Write(testClass._dataTable.outArrayPtr, result); - testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); - } - } - - private static readonly int LargestVectorSize = {LargestVectorSize}; - - // A large enough buffer to hold many values. Op3 will index into Op2. - private static readonly int Op2ElementCount = 1024; - - private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); - private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>() / sizeof({Op3BaseType}); - private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); - - private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; - private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; - private static {Op3BaseType}[] _data3 = new {Op3BaseType}[Op3ElementCount]; - - private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; - private static {RetBaseType}[] _falseData = new {RetBaseType}[RetElementCount]; - - private {Op1VectorType}<{Op1BaseType}> _fld1; - private {Op2BaseType}* _fld2; - private {Op3VectorType}<{Op3BaseType}> _fld3; - - private {Op1VectorType}<{Op1BaseType}> _mask; - private {Op1VectorType}<{Op1BaseType}> _falseFld; - - private DataTable _dataTable; - - public SveGatherVectorIndices__{TestName}() - { - Succeeded = true; - - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } - - // Ensure all values of _data3 fit within the number of _data2 elements - for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3} % ({Op3BaseType})Op2ElementCount; } - - 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<{Op3VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); - - for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueOp1}); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - for (var i = 0; i < RetElementCount; i++) { _falseData[i] = ({RetBaseType})({NextValueOp2}); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{RetBaseType}, byte>(ref _falseData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - _dataTable = new DataTable(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize); - - _fld2 = ({Op2BaseType}*)_dataTable.inArray2Ptr; - } - - public bool IsSupported => {Isa}.IsSupported; - - public bool Succeeded { get; set; } - - public void RunBasicScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - - var result = {Isa}.{Method}( - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - ({Op2BaseType}*)_dataTable.inArray2Ptr, - Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - - {Op1VectorType}<{Op1BaseType}> loadMask1 = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); - {Op3VectorType}<{Op3BaseType}> loadMask3 = Sve.CreateTrueMask{Op3BaseType}(SveMaskPattern.All); - - var result = {Isa}.{Method}( - {LoadIsa}.Load{Op1VectorType}(loadMask1, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), - ({Op2BaseType}*)_dataTable.inArray2Ptr, - {LoadIsa}.Load{Op3VectorType}(loadMask3, ({Op3BaseType}*)(_dataTable.inArray3Ptr)) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_LoadFirstFaulting() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadFirstFaulting)); - - {Op1VectorType}<{Op1BaseType}> loadMask1 = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); - {Op3VectorType}<{Op3BaseType}> loadMask3 = Sve.CreateTrueMask{Op3BaseType}(SveMaskPattern.All); - - var op1 = {LoadIsa}.Load{Op1VectorType}(loadMask1, ({Op1BaseType}*)(_dataTable.inArray1Ptr)); - ref var op2Ref = ref (_dataTable.inBounded.Span.GetPinnableReference()); - var op3 = {LoadIsa}.Load{Op3VectorType}(loadMask3, ({Op3BaseType}*)(_dataTable.inArray3Ptr)); - - // We know this is outside the bounds because 'inBounded' will never be the full size of a Vector. - var outsideBoundsIndex = ({Op3BaseType})(Vector<{Op2BaseType}>.Count - 1); - - // When testing first-faulting behavior, we need to make sure we can get the first element. - // So set the first active element of the index vector to 0. - var firstActiveElement = -1; - for (var i = 0; i < Vector<{Op3BaseType}>.Count; i++) - { - // op1 is the mask for GatherVector. - if (op1[i] != 0) - { - if (firstActiveElement == -1) - { - op3 = op3.WithElement<{Op3BaseType}>(i, 0); - firstActiveElement = i; - } - else if (op3[i] < 0 || op3[i] > outsideBoundsIndex) - { - op3 = op3.WithElement<{Op3BaseType}>(i, outsideBoundsIndex); - } - } - } - - // Force at least one element to cause a fault (required for testing). So set the last element to an index outside the bounds. - var lastIndex = Vector<{Op3BaseType}>.Count - 1; - - // Ensure we at least have one element that we can read. - if ((firstActiveElement == -1) || (firstActiveElement == lastIndex)) - { - op1 = op1.WithElement<{Op1BaseType}>(0, 1); - op3 = op3.WithElement<{Op3BaseType}>(0, 0); - } - - op1 = op1.WithElement<{Op1BaseType}>(lastIndex, 1); - - // Force an index outside the bounds. - op3 = op3.WithElement<{Op3BaseType}>(lastIndex, outsideBoundsIndex); - - Sve.SetFfr(Sve.CreateTrueMaskByte(SveMaskPattern.All)); - var result = {Isa}.{Method}( - op1, - ({Op2BaseType}*)(Unsafe.AsPointer(ref op2Ref)), - op3 - ); - var faultResult = Sve.GetFfr{GetFfrType}(); - - ref var op1Ref = ref op1; - ref var op3Ref = ref op3; - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateFirstFaultingResult(Unsafe.AsPointer(ref op1Ref), ref op2Ref, _dataTable.inBounded.Span.Length, Unsafe.AsPointer(ref op3Ref), _dataTable.outArrayPtr, faultResult); - } - - public void RunBasicScenario_FalseMask() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_FalseMask)); - - {Op1VectorType}<{Op1BaseType}> falseMask = Sve.CreateFalseMask{Op1BaseType}(); - - var result = {Isa}.{Method}( - falseMask, - ({Op2BaseType}*)_dataTable.inArray2Ptr, - Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateZeroResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_NonFaulting() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_NonFaulting)); - - {Op1VectorType}<{Op1BaseType}> falseMask = Sve.CreateFalseMask{Op1BaseType}(); - - try - { - var result = {Isa}.{Method}( - falseMask, - default, - Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateZeroResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); - } - catch - { - Succeeded = false; - } - } - - public void RunReflectionScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - - var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2BaseType}*), typeof({Op3VectorType}<{Op3BaseType}>) }) - .Invoke(null, new object[] { - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Pointer.Box(_dataTable.inArray2Ptr, typeof({Op2BaseType}*)), - Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr) - }); - - Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); - } - - public void RunLclVarScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); - - var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); - var op2 = ({Op2BaseType}*)_dataTable.inArray2Ptr; - var op3 = Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr); - 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)); - - var result = {Isa}.{Method}(_fld1, _fld2, _fld3); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); - } - - public void RunStructLclFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); - - var test = TestStruct.Create(_dataTable); - var result = {Isa}.{Method}(test._fld1, test._fld2, test._fld3); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); - } - - public void RunStructFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); - - var test = TestStruct.Create(_dataTable); - test.RunStructFldScenario(this); - } - - - public void ConditionalSelect_FalseOp() - { - TestLibrary.TestFramework.BeginScenario(nameof(ConditionalSelect_FalseOp)); - ConditionalSelectScenario(_mask, _fld1, _fld2, _fld3, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero"); - ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all"); - ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); - } - - public void ConditionalSelect_ZeroOp() - { - TestLibrary.TestFramework.BeginScenario(nameof(ConditionalSelect_ZeroOp)); - ConditionalSelectScenario(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero"); - ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all"); - ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); - } - - [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2BaseType}* op2, {Op3VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp) - { - var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateConditionalSelectResult(mask, op1, op2, op3, falseOp, _dataTable.outArrayPtr); - } - - public void RunUnsupportedScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); - - Succeeded = false; - - try - { - RunBasicScenario_Load(); - } - catch (PlatformNotSupportedException) - { - Succeeded = true; - } - } - - private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2BaseType}* op2, {Op3VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = 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.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)(Unsafe.SizeOf<{Op2BaseType}>() * Op2ElementCount)); - 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); - } - - private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = 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(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)(Unsafe.SizeOf<{Op2BaseType}>() * Op2ElementCount)); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(thirdOp), (uint)Unsafe.SizeOf<{Op3VectorType}<{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, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckGatherVectorBehavior<{RetBaseType}, {ExtendedElementType}, {Op3BaseType}>(firstOp, secondOp, thirdOp, result); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}, {Op3BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateZeroResult({Op1VectorType}<{Op1BaseType}> op1, {Op2BaseType}* op2, {Op3VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = 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.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)(Unsafe.SizeOf<{Op2BaseType}>() * Op2ElementCount)); - 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}>>()); - - ValidateZeroResult(inArray1, inArray2, inArray3, outArray, method); - } - - private void ValidateZeroResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = 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(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)(Unsafe.SizeOf<{Op2BaseType}>() * Op2ElementCount)); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(thirdOp), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateZeroResult(inArray1, inArray2, inArray3, outArray, method); - } - - private void ValidateZeroResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - bool succeeded = true; - - for (var i = 0; i < RetElementCount; i++) - { - if (result[i] != 0) - { - succeeded = false; - break; - } - } - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}, {Op3BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateConditionalSelectResult({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> op1, {Op2BaseType}* op2, {Op3VectorType}<{Op3BaseType}> op3, {RetVectorType}<{RetBaseType}> falseOp, void* result, [CallerMemberName] string method = "") - { - {RetBaseType}[] maskArray = new {RetBaseType}[RetElementCount]; - {Op1BaseType}[] op1Array = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] op2Array = new {Op2BaseType}[Op2ElementCount]; - {Op3BaseType}[] op3Array = new {Op3BaseType}[Op3ElementCount]; - {RetBaseType}[] falseValArray = new {RetBaseType}[RetElementCount]; - {RetBaseType}[] resultArray = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref maskArray[0]), maskOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref op1Array[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref op2Array[0]), ref Unsafe.AsRef(op2), (uint)(Unsafe.SizeOf<{Op2BaseType}>() * Op2ElementCount)); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref op3Array[0]), op3); - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseValArray[0]), falseOp); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref resultArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateConditionalSelectResult(maskArray, op1Array, op2Array, op3Array, falseValArray, resultArray, method); - } - - private void ValidateConditionalSelectResult({RetBaseType}[] maskOp, {Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] falseOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckGatherVectorConditionalSelectBehavior(maskOp, firstOp, secondOp, thirdOp, falseOp, result); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}, {Op3BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" maskOp: ({string.Join(", ", maskOp)})"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); - TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateFirstFaultingResult(void* op1, ref byte op2, int op2Size, void* op3, void* result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Vector<{Op1BaseType}>.Count]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[op2Size / Unsafe.SizeOf<{Op2BaseType}>()]; - {Op3BaseType}[] inArray3 = new {Op3BaseType}[Vector<{Op3BaseType}>.Count]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)(inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>())); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref op2, (uint)(inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>())); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)(inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>())); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateFirstFaultingResult(inArray1, inArray2, inArray3, outArray, faultResult, method); - } - - private void ValidateFirstFaultingResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckGatherVectorFirstFaultingBehavior(firstOp, secondOp, thirdOp, result, faultResult); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}, {Op3BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation($" faultResult: ({faultResult})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - } -} \ No newline at end of file diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorFirstFaultingVectorBases.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorFirstFaultingVectorBases.template deleted file mode 100644 index 5ba9b48264f1f..0000000000000 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorFirstFaultingVectorBases.template +++ /dev/null @@ -1,682 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/****************************************************************************** - * This file is auto-generated from a template file by the GenerateTests.csx * - * script in tests\src\JIT\HardwareIntrinsics\Arm\Shared. In order to make * - * changes, please update the corresponding template and run according to the * - * directions listed in the file. * - ******************************************************************************/ - -using System; -using System.Buffers; -using System.Numerics; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using Xunit; - -namespace JIT.HardwareIntrinsics.Arm -{ - public static partial class Program - { - [Fact] - public static void {TestName}() - { - var test = new SveGatherVectorVectorBasesTest__{TestName}(); - - if (test.IsSupported) - { - // Validates basic functionality works, using Unsafe.Read - test.RunBasicScenario_UnsafeRead(); - - // Validates basic functionality works - test.RunBasicScenario_Load(); - - // Validates basic functionality of first-faulting behavior - test.RunBasicScenario_LoadFirstFaulting(); - - // Validates fully masked out load works. - test.RunBasicScenario_FalseMask(); - - // Validates fully masked out load with invalid address works. - test.RunBasicScenario_NonFaulting(); - - // Validates calling via reflection works, using Unsafe.Read - test.RunReflectionScenario_UnsafeRead(); - - // Validates passing a local works, using Unsafe.Read - test.RunLclVarScenario_UnsafeRead(); - - // Validates passing an instance member of a class works - test.RunClassFldScenario(); - - // Validates passing the field of a local struct works - test.RunStructLclFldScenario(); - - // Validates passing an instance member of a struct works - test.RunStructFldScenario(); - - // Validates using inside ConditionalSelect with value falseValue - // Currently, using this operation in ConditionalSelect() gives incorrect result - // when falseReg == targetReg because this instruction uses Pg/Z to update the targetReg - // instead of Pg/M to merge it. As such, the value of falseReg is lost. Ideally, such - // instructions should be marked similar to RMW (a different flag name) to make sure that - // we do not assign falseReg/targetReg same. Then, we would do something like this: - // - // ldnf1sh target, pg/z, [x0] - // sel mask, target, target, falseReg - // - // This needs more careful thinking, so disabling it for now. - // test.ConditionalSelect_FalseOp(); - - // Validates using inside ConditionalSelect with zero falseValue - test.ConditionalSelect_ZeroOp(); - } - else - { - // Validates we throw on unsupported hardware - test.RunUnsupportedScenario(); - } - - if (!test.Succeeded) - { - throw new Exception("One or more scenarios did not complete as expected."); - } - } - } - - public sealed unsafe class SveGatherVectorVectorBasesTest__{TestName} - { - private struct DataTable - { - private byte[] inArray1; - private byte[] inArray2; - private byte[] inArray2Ffr; - private byte[] baseArray; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle inHandle2; - private GCHandle inHandle2Ffr; - private GCHandle baseHandle; - private GCHandle outHandle; - - private ulong alignment; - - public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {RetBaseType}[] baseArray, {RetBaseType}[] outArray, int alignment) - { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); - int sizeOfBaseArray = baseArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - - if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfinArray2: {sizeOfinArray2}, sizeOfoutArray: {sizeOfoutArray}"); - } - - this.inArray1 = new byte[alignment * 2]; - this.inArray2 = new byte[alignment * 2]; - this.inArray2Ffr = new byte[alignment * 2]; - this.baseArray = new byte[alignment + sizeOfBaseArray]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); - this.inHandle2Ffr = GCHandle.Alloc(this.inArray2Ffr, GCHandleType.Pinned); - this.baseHandle = GCHandle.Alloc(this.baseArray, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - 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(baseArrayPtr), ref Unsafe.As<{RetBaseType}, byte>(ref baseArray[0]), (uint)sizeOfBaseArray); - - var inArray2Ffr = new {Op2BaseType}[inArray2.Length]; - inArray2.CopyTo(inArray2Ffr, 0); - - // Add the base pointer to the offsets within inArray2 to create complete pointers. - for (var i = 0; i < inArray2.Length; i++) { inArray2[i] += ({Op2BaseType})baseArrayPtr; } - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); - - // Add the base pointer to the offsets within inArray2Ffr to create complete pointers. - var random = new Random(); - for (var i = 0; i < inArray2Ffr.Length; i++) - { - // In order to test the first-faulting behavior, we need to put in null pointers after the first active element (element 0). - // We will always cause a fault on the last element for testing. - if (((i != 0) && (random.Next() % 2) == 0) || (i == (inArray2Ffr.Length - 1))) - { - inArray2Ffr[i] = default; // nullptr - } - else - { - inArray2Ffr[i] += ({Op2BaseType})baseArrayPtr; - } - } - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2FfrPtr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2Ffr[0]), (uint)sizeOfinArray2); - } - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); - public void* inArray2FfrPtr => Align((byte*)(inHandle2Ffr.AddrOfPinnedObject().ToPointer()), alignment); - public void* baseArrayPtr => Align((byte*)(baseHandle.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - inHandle2Ffr.Free(); - baseHandle.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - - private struct TestStruct - { - public {Op1VectorType}<{Op1BaseType}> _fld1; - public {Op2VectorType}<{Op2BaseType}> _fld2; - - public static TestStruct Create(DataTable _dataTable) - { - var testStruct = new TestStruct(); - - for (var i = 0; i < BaseElementCount; i++) { _datab[i] = {NextValueBase}; } - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } - - // Fill full of offsets into the data buffer. - for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2} % ({Op2BaseType})BaseElementCount; } - - // Add the base pointer to the offsets within inArray2 to create complete pointers. - for (var i = 0; i < Op2ElementCount; i++) { _data2[i] += ({Op2BaseType})_dataTable.baseArrayPtr; } - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); - - return testStruct; - } - - public void RunStructFldScenario(SveGatherVectorVectorBasesTest__{TestName} testClass) - { - var result = {Isa}.{Method}(_fld1, _fld2); - - Unsafe.Write(testClass._dataTable.outArrayPtr, result); - testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); - } - } - - private static readonly int LargestVectorSize = {LargestVectorSize}; - - // A large enough buffer to hold many values. - // Values in Op2 will point to locations within this buffer. - private static readonly int BaseElementCount = 1024; - private static {RetBaseType}[] _datab = new {RetBaseType}[BaseElementCount]; - - private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); - private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); - private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); - - private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; - private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; - - private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; - private static {RetBaseType}[] _falseData = new {RetBaseType}[RetElementCount]; - - private {Op1VectorType}<{Op1BaseType}> _fld1; - private {Op2VectorType}<{Op2BaseType}> _fld2; - - private {Op1VectorType}<{Op1BaseType}> _mask; - private {Op1VectorType}<{Op1BaseType}> _falseFld; - - private DataTable _dataTable; - - public SveGatherVectorVectorBasesTest__{TestName}() - { - Succeeded = true; - - for (var i = 0; i < BaseElementCount; i++) { _datab[i] = {NextValueBase}; } - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - - // Fill full of offsets into the data buffer. They wil be expanded to full pointers inside the DataTable constructor. - for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2} % ({Op2BaseType})BaseElementCount; } - - for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueOp1}); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - for (var i = 0; i < RetElementCount; i++) { _falseData[i] = ({RetBaseType})({NextValueOp2}); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{RetBaseType}, byte>(ref _falseData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - _dataTable = new DataTable(_data1, _data2, _datab, new {RetBaseType}[RetElementCount], LargestVectorSize); - - 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<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); - } - - public bool IsSupported => {Isa}.IsSupported; - - public bool Succeeded { get; set; } - - public void RunBasicScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - - var result = {Isa}.{Method}( - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - - {Op1VectorType}<{Op1BaseType}> loadMask1 = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); - {Op2VectorType}<{Op2BaseType}> loadMask2 = Sve.CreateTrueMask{Op2BaseType}(SveMaskPattern.All); - - var result = {Isa}.{Method}( - {LoadIsa}.Load{Op1VectorType}(loadMask1, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), - {LoadIsa}.Load{Op2VectorType}(loadMask2, ({Op2BaseType}*)(_dataTable.inArray2Ptr)) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_LoadFirstFaulting() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadFirstFaulting)); - - {Op1VectorType}<{Op1BaseType}> loadMask1 = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); - {Op2VectorType}<{Op2BaseType}> loadMask2 = Sve.CreateTrueMask{Op2BaseType}(SveMaskPattern.All); - - var op1 = {LoadIsa}.Load{Op1VectorType}(loadMask1, ({Op1BaseType}*)(_dataTable.inArray1Ptr)); - var op2 = {LoadIsa}.Load{Op2VectorType}(loadMask2, ({Op2BaseType}*)(_dataTable.inArray2FfrPtr)); - - // Force op1 (mask) to have the first and last element to be active. - op1 = op1.WithElement<{Op1BaseType}>(0, 1).WithElement<{Op1BaseType}>(Vector<{Op1BaseType}>.Count - 1, 1); - - Sve.SetFfr(Sve.CreateTrueMaskByte(SveMaskPattern.All)); - var result = {Isa}.{Method}(op1, op2); - var faultResult = Sve.GetFfr{GetFfrType}(); - - ref var op1Ref = ref op1; - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateFirstFaultingResult(Unsafe.AsPointer(ref op1Ref), _dataTable.inArray2FfrPtr, _dataTable.outArrayPtr, faultResult); - } - - public void RunBasicScenario_FalseMask() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_FalseMask)); - - {Op1VectorType}<{Op1BaseType}> falseMask = Sve.CreateFalseMask{Op1BaseType}(); - - var result = {Isa}.{Method}( - falseMask, - Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateZeroResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_NonFaulting() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_NonFaulting)); - - {Op1VectorType}<{Op1BaseType}> falseMask = Sve.CreateFalseMask{Op1BaseType}(); - - try - { - var result = {Isa}.{Method}( - falseMask, - {Op2VectorType}<{Op2BaseType}>.Zero - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateZeroResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); - } - catch - { - Succeeded = false; - } - } - - public void RunReflectionScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - - var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op1VectorType}<{Op2BaseType}>) }) - .Invoke(null, new object[] { - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), - }); - - Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); - } - - public void RunLclVarScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); - - var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); - var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); - var result = {Isa}.{Method}(op1, op2); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(op1, op2, _dataTable.outArrayPtr); - } - - public void RunClassFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - - var result = {Isa}.{Method}(_fld1, _fld2); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); - } - - public void RunStructLclFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); - - var test = TestStruct.Create(_dataTable); - var result = {Isa}.{Method}(test._fld1, test._fld2); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); - } - - public void RunStructFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); - - var test = TestStruct.Create(_dataTable); - test.RunStructFldScenario(this); - } - - public void ConditionalSelect_FalseOp() - { - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _falseFld); - } - - public void ConditionalSelect_ZeroOp() - { - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, {Op1VectorType}<{Op1BaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, {Op1VectorType}<{Op1BaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, {Op1VectorType}<{Op1BaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, {Op1VectorType}<{Op1BaseType}>.Zero); - } - - [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op1BaseType}> falseOp) - { - var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr); - } - - [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op1BaseType}> trueOp) - { - var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2)); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateConditionalSelectResult_FalseValue(mask, op1, op2, trueOp, _dataTable.outArrayPtr); - } - - public void RunUnsupportedScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); - - Succeeded = false; - - try - { - RunBasicScenario_Load(); - } - catch (PlatformNotSupportedException) - { - Succeeded = true; - } - } - - private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateResult(inArray1, inArray2, outArray, method); - } - - private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)(Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>())); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateResult(inArray1, inArray2, outArray, method); - } - - private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckGatherVectorBasesBehavior<{Op1BaseType}, {Op2BaseType}, {ExtendedElementType}>(firstOp, secondOp, result); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}, {Op2BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateZeroResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateZeroResult(inArray1, inArray2, outArray, method); - } - - private void ValidateZeroResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)(Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>())); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateZeroResult(inArray1, inArray2, outArray, method); - } - - private void ValidateZeroResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - bool succeeded = true; - - for (var i = 0; i < RetElementCount; i++) - { - if (result[i] != 0) - { - succeeded = false; - break; - } - } - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}, {Op2BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateConditionalSelectResult_TrueValue({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {RetVectorType}<{RetBaseType}> falseOp, void* result, [CallerMemberName] string method = "") - { - {RetBaseType}[] maskArray = new {RetBaseType}[RetElementCount]; - {Op1BaseType}[] op1Array = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] op2Array = new {Op2BaseType}[Op2ElementCount]; - {RetBaseType}[] falseValArray = new {RetBaseType}[RetElementCount]; - {RetBaseType}[] resultArray = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref maskArray[0]), maskOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref op1Array[0]), op1); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref op2Array[0]), op2); - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseValArray[0]), falseOp); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref resultArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateConditionalSelectResult_TrueValue(maskArray, op1Array, op2Array, falseValArray, resultArray, method); - } - - private void ValidateConditionalSelectResult_TrueValue({RetBaseType}[] maskOp, {Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] falseOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckGatherVectorBasesConditionalSelectBehavior<{Op1BaseType}, {Op2BaseType}, {ExtendedElementType}>(maskOp, firstOp, secondOp, falseOp, result); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}, {Op2BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" maskOp: ({string.Join(", ", maskOp)})"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateConditionalSelectResult_FalseValue({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {RetVectorType}<{RetBaseType}> trueOp, void* result, [CallerMemberName] string method = "") - { - {RetBaseType}[] maskArray = new {RetBaseType}[RetElementCount]; - {Op1BaseType}[] op1Array = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] op2Array = new {Op2BaseType}[Op2ElementCount]; - {RetBaseType}[] trueValArray = new {RetBaseType}[RetElementCount]; - {RetBaseType}[] resultArray = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref maskArray[0]), maskOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref op1Array[0]), op1); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref op2Array[0]), op2); - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref trueValArray[0]), trueOp); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref resultArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateConditionalSelectResult_FalseValue(maskArray, op1Array, op2Array, trueValArray, resultArray, method); - } - - private void ValidateConditionalSelectResult_FalseValue({RetBaseType}[] maskOp, {Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] trueOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckGatherVectorBasesConditionalSelectTrueBehavior<{Op1BaseType}, {Op2BaseType}, {ExtendedElementType}>(maskOp, firstOp, secondOp, trueOp, result); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}, {Op2BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" maskOp: ({string.Join(", ", maskOp)})"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" trueOp: ({string.Join(", ", trueOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateFirstFaultingResult(void* op1, void* op2, void* result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; - {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<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateFirstFaultingResult(inArray1, inArray2, outArray, faultResult, method); - } - - private void ValidateFirstFaultingResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckGatherVectorBasesFirstFaultingBehavior<{Op1BaseType}, {Op2BaseType}, {ExtendedElementType}, {GetFfrType}>(firstOp, secondOp, result, faultResult); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}, {Op2BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation($" faultResult: ({faultResult})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - } -} \ No newline at end of file diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorIndices.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorIndices.template index 094cb1eec218f..ff430714f94df 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorIndices.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorIndices.template @@ -470,7 +470,17 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { - var succeeded = Helpers.CheckGatherVectorBehavior<{RetBaseType}, {ExtendedElementType}, {Op3BaseType}>(firstOp, secondOp, thirdOp, result); + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} gatherResult = ({RetBaseType})(firstOp[i] == 0 ? 0 : ({ExtendedElementType})secondOp[thirdOp[i]]); + if (result[i] != gatherResult) + { + succeeded = false; + break; + } + } if (!succeeded) { @@ -562,7 +572,18 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateConditionalSelectResult_TrueValue({RetBaseType}[] maskOp, {Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] falseOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { - var succeeded = Helpers.CheckGatherVectorConditionalSelectBehavior(maskOp, firstOp, secondOp, thirdOp, falseOp, result); + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} gatherResult = ({RetBaseType})(firstOp[i] == 0 ? 0 : ({ExtendedElementType})secondOp[thirdOp[i]]); + {RetBaseType} iterResult = (maskOp[i] != 0) ? gatherResult : falseOp[i]; + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } if (!succeeded) { @@ -600,7 +621,21 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateConditionalSelectResult_FalseValue({RetBaseType}[] maskOp, {Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] trueOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { - var succeeded = Helpers.CheckGatherVectorConditionalSelectTrueBehavior(maskOp, firstOp, secondOp, thirdOp, trueOp, result); + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} gatherResult = ({RetBaseType})(firstOp[i] == 0 ? 0 : ({ExtendedElementType})secondOp[thirdOp[i]]); + {RetBaseType} iterResult = (maskOp[i] != 0) ? trueOp[i] : gatherResult; + if (maskOp[i] != 0) + { + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } + } if (!succeeded) { diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorVectorBases.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorVectorBases.template index d4bc14542bef4..eb5a2b2b65e83 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorVectorBases.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveGatherVectorVectorBases.template @@ -462,7 +462,17 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { - var succeeded = Helpers.CheckGatherVectorBasesBehavior<{Op1BaseType}, {Op2BaseType}, {ExtendedElementType}>(firstOp, secondOp, result); + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} gatherResult = ({RetBaseType})(firstOp[i] == 0 ? 0 : *({ExtendedElementType}*)(secondOp[i])); + if (result[i] != gatherResult) + { + succeeded = false; + break; + } + } if (!succeeded) { @@ -546,7 +556,18 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateConditionalSelectResult_TrueValue({RetBaseType}[] maskOp, {Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] falseOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { - var succeeded = Helpers.CheckGatherVectorBasesConditionalSelectBehavior<{Op1BaseType}, {Op2BaseType}, {ExtendedElementType}>(maskOp, firstOp, secondOp, falseOp, result); + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} gatherResult = ({RetBaseType})(firstOp[i] == 0 ? 0 : *({ExtendedElementType}*)(secondOp[i])); + {RetBaseType} iterResult = (maskOp[i] != 0) ? gatherResult : falseOp[i]; + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } if (!succeeded) { @@ -581,7 +602,21 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateConditionalSelectResult_FalseValue({RetBaseType}[] maskOp, {Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] trueOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { - var succeeded = Helpers.CheckGatherVectorBasesConditionalSelectTrueBehavior<{Op1BaseType}, {Op2BaseType}, {ExtendedElementType}>(maskOp, firstOp, secondOp, trueOp, result); + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} gatherResult = ({RetBaseType})(firstOp[i] == 0 ? 0 : *({ExtendedElementType}*)(secondOp[i])); + {RetBaseType} iterResult = (maskOp[i] != 0) ? trueOp[i] : gatherResult; + if (maskOp[i] != 0) + { + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } + } if (!succeeded) { diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadVectorFirstFaultingTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadVectorFirstFaultingTest.template deleted file mode 100644 index c0e489d138950..0000000000000 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadVectorFirstFaultingTest.template +++ /dev/null @@ -1,384 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/****************************************************************************** - * This file is auto-generated from a template file by the GenerateTests.csx * - * script in tests\src\JIT\HardwareIntrinsics\Arm\Shared. In order to make * - * changes, please update the corresponding template and run according to the * - * directions listed in the file. * - ******************************************************************************/ - -using System; -using System.Buffers; -using System.Numerics; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using Xunit; - -namespace JIT.HardwareIntrinsics.Arm -{ - public static partial class Program - { - [Fact] - public static void {TestName}() - { - var test = new Sve__{TestName}(); - - if (test.IsSupported) - { - // Validates basic functionality works - test.RunBasicScenario_Load(); - - // Validates basic functionality of first-faulting behavior - test.RunBasicScenario_LoadFirstFaulting(); - - // Validates calling via reflection works - test.RunReflectionScenario_Load(); - - // Validates passing an instance member of a class works - test.RunClassFldScenario(); - - // Validates passing the field of a local struct works - test.RunStructLclFldScenario(); - - // Validates passing an instance member of a struct works - test.RunStructFldScenario(); - - // Validates using inside ConditionalSelect with zero falseValue - test.ConditionalSelect_ZeroOp(); - } - else - { - // Validates we throw on unsupported hardware - test.RunUnsupportedScenario(); - } - - if (!test.Succeeded) - { - throw new Exception("One or more scenarios did not complete as expected."); - } - } - } - - public sealed unsafe class Sve__{TestName} - { - private struct DataTable - { - private byte[] inArray1; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle outHandle; - - private ulong alignment; - - public DataTable({Op2BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) - { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op2BaseType}>(); - int sizeOfinBounded = new Random().Next(Unsafe.SizeOf<{Op2BaseType}>(), Vector<{Op2BaseType}>.Count * Unsafe.SizeOf<{Op2BaseType}>() - 1); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); - } - - this.inArray1 = new byte[alignment * 2]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - this.alignment = (ulong)alignment; - - this.inBounded = BoundedMemory.Allocate(sizeOfinBounded, PoisonPagePlacement.After); - - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); - Unsafe.CopyBlockUnaligned(ref inBounded.Span.GetPinnableReference(), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinBounded); - } - - public BoundedMemory inBounded; - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - - private struct TestStruct - { - public {Op1VectorType}<{RetBaseType}> _fld1; - - public static TestStruct Create() - { - var testStruct = new TestStruct(); - - for (var i = 0; i < Op2ElementCount; i++) { _data[i] = {NextValueOp2}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); - - return testStruct; - } - - public void RunStructFldScenario(Sve__{TestName} testClass) - { - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); - - var result = {Isa}.{Method}(loadMask, ({Op2BaseType}*)testClass._dataTable.inArray1Ptr); - - Unsafe.Write(testClass._dataTable.outArrayPtr, result); - testClass.ValidateResult(testClass._dataTable.inArray1Ptr, testClass._dataTable.outArrayPtr); - } - } - - private static readonly int LargestVectorSize = {LargestVectorSize}; - - private static readonly int Op2ElementCount = Unsafe.SizeOf<{RetVectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); - private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); - - private static {Op1BaseType}[] _data = new {Op1BaseType}[Op2ElementCount]; - - private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; - private static {RetBaseType}[] _falseData = new {RetBaseType}[RetElementCount]; - - private {Op1VectorType}<{RetBaseType}> _fld1; - - private {Op1VectorType}<{Op1BaseType}> _mask; - private {Op1VectorType}<{Op1BaseType}> _falseFld; - - private DataTable _dataTable; - - public Sve__{TestName}() - { - Succeeded = true; - - for (var i = 0; i < Op2ElementCount; i++) { _data[i] = {NextValueOp2}; } - _dataTable = new DataTable(_data, new {RetBaseType}[RetElementCount], LargestVectorSize); - - for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueOp1}); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - for (var i = 0; i < RetElementCount; i++) { _falseData[i] = ({RetBaseType})({NextValueOp2}); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{RetBaseType}, byte>(ref _falseData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - } - - public bool IsSupported => {Isa}.IsSupported; - - public bool Succeeded { get; set; } - - public void RunBasicScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); - - var result = {Isa}.{Method}( - loadMask, - ({Op2BaseType}*)(_dataTable.inArray1Ptr) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_LoadFirstFaulting() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadFirstFaulting)); - - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); - - ref var op2Ref = ref (_dataTable.inBounded.Span.GetPinnableReference()); - - Sve.SetFfr(Sve.CreateTrueMaskByte(SveMaskPattern.All)); - var result = {Isa}.{Method}( - loadMask, - ({Op2BaseType}*)(Unsafe.AsPointer(ref op2Ref)) - ); - var faultResult = Sve.GetFfr{GetFfrType}(); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateFirstFaultingResult(ref op2Ref, _dataTable.inBounded.Span.Length, _dataTable.outArrayPtr, faultResult); - } - - public void RunReflectionScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); - - var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof(Vector<{Op1BaseType}>), typeof({Op2BaseType}*) }) - .Invoke(null, new object[] { - loadMask, - Pointer.Box(_dataTable.inArray1Ptr, typeof({Op2BaseType}*)) - }); - - Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunClassFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); - - _fld1 = {Isa}.{Method}(loadMask, ({Op2BaseType}*)_dataTable.inArray1Ptr); - - Unsafe.Write(_dataTable.outArrayPtr, _fld1); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunStructLclFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); - - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); - - var test = TestStruct.Create(); - test._fld1 = {Isa}.{Method}(loadMask, ({Op2BaseType}*)_dataTable.inArray1Ptr); - - Unsafe.Write(_dataTable.outArrayPtr, test._fld1); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunStructFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); - - var test = TestStruct.Create(); - test.RunStructFldScenario(this); - } - - public void ConditionalSelect_ZeroOp() - { - TestLibrary.TestFramework.BeginScenario(nameof(ConditionalSelect_ZeroOp)); - ConditionalSelectScenario(_mask, ref _fld1, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero"); - ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, ref _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all"); - ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, ref _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); - } - - [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario({RetVectorType}<{RetBaseType}> mask, ref {RetVectorType}<{Op2BaseType}> op1, {Op1VectorType}<{Op1BaseType}> falseOp) - { - var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All), ({Op2BaseType}*)Unsafe.AsPointer(ref op1)), falseOp); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateConditionalSelectResult(mask, op1, falseOp, _dataTable.outArrayPtr); - } - - public void RunUnsupportedScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); - - Succeeded = false; - - try - { - RunBasicScenario_Load(); - } - catch (PlatformNotSupportedException) - { - Succeeded = true; - } - } - - private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") - { - {Op2BaseType}[] inArray = new {Op2BaseType}[Op2ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf<{RetVectorType}<{Op2BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateResult(inArray, outArray, method); - } - - private void ValidateResult({Op2BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckLoadVectorBehavior(firstOp, result); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateConditionalSelectResult({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> op1, {RetVectorType}<{RetBaseType}> falseOp, void* result, [CallerMemberName] string method = "") - { - {RetBaseType}[] maskArray = new {RetBaseType}[RetElementCount]; - {Op1BaseType}[] op1Array = new {Op1BaseType}[RetElementCount]; - {RetBaseType}[] falseValArray = new {RetBaseType}[RetElementCount]; - {RetBaseType}[] resultArray = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref maskArray[0]), maskOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref op1Array[0]), op1); - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseValArray[0]), falseOp); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref resultArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateConditionalSelectResult(maskArray, op1Array, falseValArray, resultArray, method); - } - - private void ValidateConditionalSelectResult({RetBaseType}[] maskOp, {Op1BaseType}[] firstOp, {RetBaseType}[] falseOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckLoadVectorBehavior(maskOp, firstOp, result, falseOp); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op2BaseType}>): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" maskOp: ({string.Join(", ", maskOp)})"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateFirstFaultingResult(ref byte firstOp, int size, void* result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "") - { - {Op2BaseType}[] inArray = new {Op2BaseType}[size / Unsafe.SizeOf<{Op2BaseType}>()]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray[0]), ref firstOp, (uint)(inArray.Length * Unsafe.SizeOf<{Op2BaseType}>())); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateFirstFaultingResult(inArray, outArray, faultResult, method); - } - - private void ValidateFirstFaultingResult({Op2BaseType}[] firstOp, {RetBaseType}[] result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "") - { - var succeeded = Helpers.CheckLoadVectorFirstFaultingBehavior(firstOp, result, faultResult); - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op2BaseType}>): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation($" faultResult: ({faultResult})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - } -} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Sve_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Sve_r.csproj index dd4135fc1c866..0918724cfff28 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Sve_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Sve_r.csproj @@ -10,10 +10,5 @@ - - - - - diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Sve_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Sve_ro.csproj index e23748ff74c8b..a9d4a43b42ae1 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Sve_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Sve_ro.csproj @@ -10,10 +10,5 @@ - - - - -