1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-09 17:44:48 +09:00

Revert "JIT: Added SVE GetFfr, SetFfr, LoadVectorFirstFaulting, `Gather…" (#105591)

This reverts commit 991ae97a1d.
This commit is contained in:
Jan Kotas 2024-07-27 10:20:34 -07:00 committed by GitHub
parent 991ae97a1d
commit dc7d7bc2c8
Signed by: github
GPG key ID: B5690EEEBB952194
22 changed files with 165 additions and 3218 deletions

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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:

View file

@ -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<T> mask, T* address, Vector<T2> 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 sign or zero extended to 64bits, then multiplied.
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;
// Index is multiplied.
sopt = (ins == INS_sve_ld1b || ins == INS_sve_ld1sb) ? INS_SCALABLE_OPTS_NONE
: INS_SCALABLE_OPTS_LSL_N;
}
else
{
// Index is multiplied.
assert(baseSize == EA_8BYTE);
sopt = isLoadingBytes ? INS_SCALABLE_OPTS_NONE : INS_SCALABLE_OPTS_LSL_N;
// 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 = (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<T> mask, Vector<T2> addresses)
assert(intrin.numOperands == 2);
GetEmitter()->emitIns_R_R_R_I(ins, emitSize, targetReg, op1Reg, op2Reg, 0, opt);
}

View file

@ -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)

View file

@ -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");

View file

@ -9,7 +9,10 @@ namespace System.Buffers
{
private static UnixImplementation<T> AllocateWithoutDataPopulationUnix<T>(int elementCount, PoisonPagePlacement placement) where T : unmanaged
{
return new UnixImplementation<T>(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<T>(elementCount);
}
private sealed class UnixImplementation<T> : BoundedMemory<T> where T : unmanaged
@ -18,9 +21,9 @@ namespace System.Buffers
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 @@ namespace System.Buffers
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 <sys/mman.h>
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);
}
}
}

View file

@ -33,7 +33,7 @@ namespace System.Buffers
// 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 @@ namespace System.Buffers
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 @@ namespace System.Buffers
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 @@ namespace System.Buffers
{
}
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);
}
}
}

View file

@ -3624,118 +3624,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe Vector<ulong> GatherVectorByteZeroExtend(Vector<ulong> mask, byte* address, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<double> GatherVectorFirstFaulting(Vector<double> mask, double* address, Vector<long> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svfloat64_t svldff1_gather[_u64base]_f64(svbool_t pg, svuint64_t bases)
/// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0]
/// </summary>
public static unsafe Vector<double> GatherVectorFirstFaulting(Vector<double> mask, Vector<ulong> addresses) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<double> GatherVectorFirstFaulting(Vector<double> mask, double* address, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }
// <summary>
// svint32_t svldff1_gather[_u32base]_s32(svbool_t pg, svuint32_t bases)
// LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0]
// </summary>
// Removed as per #103297
// public static unsafe Vector<int> GatherVectorFirstFaulting(Vector<int> mask, Vector<uint> addresses) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<int> GatherVectorFirstFaulting(Vector<int> mask, int* address, Vector<int> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<int> GatherVectorFirstFaulting(Vector<int> mask, int* address, Vector<uint> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svint64_t svldff1_gather[_u64base]_s64(svbool_t pg, svuint64_t bases)
/// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0]
/// </summary>
public static unsafe Vector<long> GatherVectorFirstFaulting(Vector<long> mask, Vector<ulong> addresses) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<long> GatherVectorFirstFaulting(Vector<long> mask, long* address, Vector<long> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<long> GatherVectorFirstFaulting(Vector<long> mask, long* address, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<float> GatherVectorFirstFaulting(Vector<float> mask, float* address, Vector<int> indices) { throw new PlatformNotSupportedException(); }
// <summary>
// svfloat32_t svldff1_gather[_u32base]_f32(svbool_t pg, svuint32_t bases)
// LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0]
// </summary>
// Removed as per #103297
// public static unsafe Vector<float> GatherVectorFirstFaulting(Vector<float> mask, Vector<uint> addresses) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<float> GatherVectorFirstFaulting(Vector<float> mask, float* address, Vector<uint> indices) { throw new PlatformNotSupportedException(); }
// <summary>
// svuint32_t svldff1_gather[_u32base]_u32(svbool_t pg, svuint32_t bases)
// LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0]
// </summary>
// Removed as per #103297
// public static unsafe Vector<uint> GatherVectorFirstFaulting(Vector<uint> mask, Vector<uint> addresses) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<uint> GatherVectorFirstFaulting(Vector<uint> mask, uint* address, Vector<int> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<uint> GatherVectorFirstFaulting(Vector<uint> mask, uint* address, Vector<uint> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svuint64_t svldff1_gather[_u64base]_u64(svbool_t pg, svuint64_t bases)
/// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0]
/// </summary>
public static unsafe Vector<ulong> GatherVectorFirstFaulting(Vector<ulong> mask, Vector<ulong> addresses) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<ulong> GatherVectorFirstFaulting(Vector<ulong> mask, ulong* address, Vector<long> indices) { throw new PlatformNotSupportedException(); }
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<ulong> GatherVectorFirstFaulting(Vector<ulong> mask, ulong* address, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }
/// Load 16-bit data and sign-extend
/// <summary>
@ -4401,55 +4289,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe ulong GetActiveElementCount(Vector<ulong> mask, Vector<ulong> from) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<byte> GetFfrByte() { throw new PlatformNotSupportedException(); }
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<short> GetFfrInt16() { throw new PlatformNotSupportedException(); }
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<int> GetFfrInt32() { throw new PlatformNotSupportedException(); }
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<long> GetFfrInt64() { throw new PlatformNotSupportedException(); }
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<sbyte> GetFfrSByte() { throw new PlatformNotSupportedException(); }
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<ushort> GetFfrUInt16() { throw new PlatformNotSupportedException(); }
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<uint> GetFfrUInt32() { throw new PlatformNotSupportedException(); }
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<ulong> GetFfrUInt64() { throw new PlatformNotSupportedException(); }
/// Insert scalar into shifted vector
/// <summary>
@ -4935,67 +4774,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe Vector<ulong> LoadVectorByteZeroExtendToUInt64(Vector<ulong> mask, byte* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svuint8_t svldff1[_u8](svbool_t pg, const uint8_t *base)
/// LDFF1B Zresult.B, Pg/Z, [Xbase, XZR]
/// </summary>
public static unsafe Vector<byte> LoadVectorFirstFaulting(Vector<byte> mask, byte* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svfloat64_t svldff1[_f64](svbool_t pg, const float64_t *base)
/// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3]
/// </summary>
public static unsafe Vector<double> LoadVectorFirstFaulting(Vector<double> mask, double* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svint16_t svldff1[_s16](svbool_t pg, const int16_t *base)
/// LDFF1H Zresult.H, Pg/Z, [Xbase, XZR, LSL #1]
/// </summary>
public static unsafe Vector<short> LoadVectorFirstFaulting(Vector<short> mask, short* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svint32_t svldff1[_s32](svbool_t pg, const int32_t *base)
/// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2]
/// </summary>
public static unsafe Vector<int> LoadVectorFirstFaulting(Vector<int> mask, int* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svint64_t svldff1[_s64](svbool_t pg, const int64_t *base)
/// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3]
/// </summary>
public static unsafe Vector<long> LoadVectorFirstFaulting(Vector<long> mask, long* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svint8_t svldff1[_s8](svbool_t pg, const int8_t *base)
/// LDFF1B Zresult.B, Pg/Z, [Xbase, XZR]
/// </summary>
public static unsafe Vector<sbyte> LoadVectorFirstFaulting(Vector<sbyte> mask, sbyte* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svfloat32_t svldff1[_f32](svbool_t pg, const float32_t *base)
/// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2]
/// </summary>
public static unsafe Vector<float> LoadVectorFirstFaulting(Vector<float> mask, float* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svuint16_t svldff1[_u16](svbool_t pg, const uint16_t *base)
/// LDFF1H Zresult.H, Pg/Z, [Xbase, XZR, LSL #1]
/// </summary>
public static unsafe Vector<ushort> LoadVectorFirstFaulting(Vector<ushort> mask, ushort* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svuint32_t svldff1[_u32](svbool_t pg, const uint32_t *base)
/// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2]
/// </summary>
public static unsafe Vector<uint> LoadVectorFirstFaulting(Vector<uint> mask, uint* address) { throw new PlatformNotSupportedException(); }
/// <summary>
/// svuint64_t svldff1[_u64](svbool_t pg, const uint64_t *base)
/// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3]
/// </summary>
public static unsafe Vector<ulong> LoadVectorFirstFaulting(Vector<ulong> mask, ulong* address) { throw new PlatformNotSupportedException(); }
/// LoadVectorInt16SignExtendToInt32 : Load 16-bit data and sign-extend
/// <summary>
@ -7905,55 +7683,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector<ulong> mask, byte* address, Vector<ulong> offsets, Vector<ulong> data) { throw new PlatformNotSupportedException(); }
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<byte> value) { throw new PlatformNotSupportedException(); }
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<short> value) { throw new PlatformNotSupportedException(); }
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<int> value) { throw new PlatformNotSupportedException(); }
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<long> value) { throw new PlatformNotSupportedException(); }
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<sbyte> value) { throw new PlatformNotSupportedException(); }
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<ushort> value) { throw new PlatformNotSupportedException(); }
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<uint> value) { throw new PlatformNotSupportedException(); }
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<ulong> value) { throw new PlatformNotSupportedException(); }
/// Logical shift left
/// <summary>

View file

@ -3681,119 +3681,6 @@ namespace System.Runtime.Intrinsics.Arm
/// </summary>
public static unsafe Vector<ulong> GatherVectorByteZeroExtend(Vector<ulong> mask, byte* address, Vector<ulong> indices) => GatherVectorByteZeroExtend(mask, address, indices);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<double> GatherVectorFirstFaulting(Vector<double> mask, double* address, Vector<long> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// <summary>
/// svfloat64_t svldff1_gather[_u64base]_f64(svbool_t pg, svuint64_t bases)
/// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0]
/// </summary>
public static unsafe Vector<double> GatherVectorFirstFaulting(Vector<double> mask, Vector<ulong> addresses) => GatherVectorFirstFaulting(mask, addresses);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<double> GatherVectorFirstFaulting(Vector<double> mask, double* address, Vector<ulong> indices) => GatherVectorFirstFaulting(mask, address, indices);
// <summary>
// svint32_t svldff1_gather[_u32base]_s32(svbool_t pg, svuint32_t bases)
// LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0]
// </summary>
// Removed as per #103297
// public static unsafe Vector<int> GatherVectorFirstFaulting(Vector<int> mask, Vector<uint> addresses) => GatherVectorFirstFaulting(mask, addresses);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<int> GatherVectorFirstFaulting(Vector<int> mask, int* address, Vector<int> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<int> GatherVectorFirstFaulting(Vector<int> mask, int* address, Vector<uint> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// <summary>
/// svint64_t svldff1_gather[_u64base]_s64(svbool_t pg, svuint64_t bases)
/// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0]
/// </summary>
public static unsafe Vector<long> GatherVectorFirstFaulting(Vector<long> mask, Vector<ulong> addresses) => GatherVectorFirstFaulting(mask, addresses);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<long> GatherVectorFirstFaulting(Vector<long> mask, long* address, Vector<long> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<long> GatherVectorFirstFaulting(Vector<long> mask, long* address, Vector<ulong> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<float> GatherVectorFirstFaulting(Vector<float> mask, float* address, Vector<int> indices) => GatherVectorFirstFaulting(mask, address, indices);
// <summary>
// svfloat32_t svldff1_gather[_u32base]_f32(svbool_t pg, svuint32_t bases)
// LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0]
// </summary>
// Removed as per #103297
// public static unsafe Vector<float> GatherVectorFirstFaulting(Vector<float> mask, Vector<uint> addresses) => GatherVectorFirstFaulting(mask, addresses);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<float> GatherVectorFirstFaulting(Vector<float> mask, float* address, Vector<uint> indices) => GatherVectorFirstFaulting(mask, address, indices);
// <summary>
// svuint32_t svldff1_gather[_u32base]_u32(svbool_t pg, svuint32_t bases)
// LDFF1W Zresult.S, Pg/Z, [Zbases.S, #0]
// </summary>
// Removed as per #103297
// public static unsafe Vector<uint> GatherVectorFirstFaulting(Vector<uint> mask, Vector<uint> addresses) => GatherVectorFirstFaulting(mask, addresses);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<uint> GatherVectorFirstFaulting(Vector<uint> mask, uint* address, Vector<int> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<uint> GatherVectorFirstFaulting(Vector<uint> mask, uint* address, Vector<uint> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// <summary>
/// svuint64_t svldff1_gather[_u64base]_u64(svbool_t pg, svuint64_t bases)
/// LDFF1D Zresult.D, Pg/Z, [Zbases.D, #0]
/// </summary>
public static unsafe Vector<ulong> GatherVectorFirstFaulting(Vector<ulong> mask, Vector<ulong> addresses) => GatherVectorFirstFaulting(mask, addresses);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<ulong> GatherVectorFirstFaulting(Vector<ulong> mask, ulong* address, Vector<long> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// <summary>
/// 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]
/// </summary>
public static unsafe Vector<ulong> GatherVectorFirstFaulting(Vector<ulong> mask, ulong* address, Vector<ulong> indices) => GatherVectorFirstFaulting(mask, address, indices);
/// Load 16-bit data and sign-extend
/// <summary>
@ -4459,55 +4346,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe ulong GetActiveElementCount(Vector<ulong> mask, Vector<ulong> from) => GetActiveElementCount(mask, from);
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<byte> GetFfrByte() => GetFfrByte();
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<short> GetFfrInt16() => GetFfrInt16();
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<int> GetFfrInt32() => GetFfrInt32();
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<long> GetFfrInt64() => GetFfrInt64();
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<sbyte> GetFfrSByte() => GetFfrSByte();
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<ushort> GetFfrUInt16() => GetFfrUInt16();
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<uint> GetFfrUInt32() => GetFfrUInt32();
/// <summary>
/// svbool_t svrdffr()
/// RDFFR Presult.B
/// </summary>
public static Vector<ulong> GetFfrUInt64() => GetFfrUInt64();
/// Insert scalar into shifted vector
/// <summary>
@ -4992,67 +4830,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe Vector<ulong> LoadVectorByteZeroExtendToUInt64(Vector<ulong> mask, byte* address) => LoadVectorByteZeroExtendToUInt64(mask, address);
/// <summary>
/// svuint8_t svldff1[_u8](svbool_t pg, const uint8_t *base)
/// LDFF1B Zresult.B, Pg/Z, [Xbase, XZR]
/// </summary>
public static unsafe Vector<byte> LoadVectorFirstFaulting(Vector<byte> mask, byte* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svfloat64_t svldff1[_f64](svbool_t pg, const float64_t *base)
/// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3]
/// </summary>
public static unsafe Vector<double> LoadVectorFirstFaulting(Vector<double> mask, double* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svint16_t svldff1[_s16](svbool_t pg, const int16_t *base)
/// LDFF1H Zresult.H, Pg/Z, [Xbase, XZR, LSL #1]
/// </summary>
public static unsafe Vector<short> LoadVectorFirstFaulting(Vector<short> mask, short* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svint32_t svldff1[_s32](svbool_t pg, const int32_t *base)
/// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2]
/// </summary>
public static unsafe Vector<int> LoadVectorFirstFaulting(Vector<int> mask, int* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svint64_t svldff1[_s64](svbool_t pg, const int64_t *base)
/// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3]
/// </summary>
public static unsafe Vector<long> LoadVectorFirstFaulting(Vector<long> mask, long* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svint8_t svldff1[_s8](svbool_t pg, const int8_t *base)
/// LDFF1B Zresult.B, Pg/Z, [Xbase, XZR]
/// </summary>
public static unsafe Vector<sbyte> LoadVectorFirstFaulting(Vector<sbyte> mask, sbyte* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svfloat32_t svldff1[_f32](svbool_t pg, const float32_t *base)
/// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2]
/// </summary>
public static unsafe Vector<float> LoadVectorFirstFaulting(Vector<float> mask, float* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svuint16_t svldff1[_u16](svbool_t pg, const uint16_t *base)
/// LDFF1H Zresult.H, Pg/Z, [Xbase, XZR, LSL #1]
/// </summary>
public static unsafe Vector<ushort> LoadVectorFirstFaulting(Vector<ushort> mask, ushort* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svuint32_t svldff1[_u32](svbool_t pg, const uint32_t *base)
/// LDFF1W Zresult.S, Pg/Z, [Xbase, XZR, LSL #2]
/// </summary>
public static unsafe Vector<uint> LoadVectorFirstFaulting(Vector<uint> mask, uint* address) => LoadVectorFirstFaulting(mask, address);
/// <summary>
/// svuint64_t svldff1[_u64](svbool_t pg, const uint64_t *base)
/// LDFF1D Zresult.D, Pg/Z, [Xbase, XZR, LSL #3]
/// </summary>
public static unsafe Vector<ulong> LoadVectorFirstFaulting(Vector<ulong> mask, ulong* address) => LoadVectorFirstFaulting(mask, address);
/// LoadVectorInt16SignExtendToInt32 : Load 16-bit data and sign-extend
/// <summary>
@ -7950,55 +7727,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector<ulong> mask, byte* address, Vector<ulong> offsets, Vector<ulong> data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data);
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<byte> value) => SetFfr(value);
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<short> value) => SetFfr(value);
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<int> value) => SetFfr(value);
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<long> value) => SetFfr(value);
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<sbyte> value) => SetFfr(value);
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<ushort> value) => SetFfr(value);
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<uint> value) => SetFfr(value);
/// <summary>
/// void svwrffr(svbool_t op)
/// WRFFR Pop.B
/// </summary>
public static unsafe void SetFfr(Vector<ulong> value) => SetFfr(value);
/// Logical shift left
/// <summary>

View file

@ -4882,26 +4882,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe System.Numerics.Vector<ulong> GatherVectorByteZeroExtend(System.Numerics.Vector<ulong> mask, byte* address, System.Numerics.Vector<long> indices) { throw null; }
public static System.Numerics.Vector<ulong> GatherVectorByteZeroExtend(System.Numerics.Vector<ulong> mask, System.Numerics.Vector<ulong> addresses) { throw null; }
public static unsafe System.Numerics.Vector<ulong> GatherVectorByteZeroExtend(System.Numerics.Vector<ulong> mask, byte* address, System.Numerics.Vector<ulong> indices) { throw null; }
public static unsafe System.Numerics.Vector<double> GatherVectorFirstFaulting(System.Numerics.Vector<double> mask, double* address, System.Numerics.Vector<long> indices) { throw null; }
public static unsafe System.Numerics.Vector<double> GatherVectorFirstFaulting(System.Numerics.Vector<double> mask, System.Numerics.Vector<ulong> addresses) { throw null; }
public static unsafe System.Numerics.Vector<double> GatherVectorFirstFaulting(System.Numerics.Vector<double> mask, double* address, System.Numerics.Vector<ulong> indices) { throw null; }
// public static unsafe System.Numerics.Vector<int> GatherVectorFirstFaulting(System.Numerics.Vector<int> mask, System.Numerics.Vector<uint> addresses) { throw null; }
public static unsafe System.Numerics.Vector<int> GatherVectorFirstFaulting(System.Numerics.Vector<int> mask, int* address, System.Numerics.Vector<int> indices) { throw null; }
public static unsafe System.Numerics.Vector<int> GatherVectorFirstFaulting(System.Numerics.Vector<int> mask, int* address, System.Numerics.Vector<uint> indices) { throw null; }
public static unsafe System.Numerics.Vector<long> GatherVectorFirstFaulting(System.Numerics.Vector<long> mask, System.Numerics.Vector<ulong> addresses) { throw null; }
public static unsafe System.Numerics.Vector<long> GatherVectorFirstFaulting(System.Numerics.Vector<long> mask, long* address, System.Numerics.Vector<long> indices) { throw null; }
public static unsafe System.Numerics.Vector<long> GatherVectorFirstFaulting(System.Numerics.Vector<long> mask, long* address, System.Numerics.Vector<ulong> indices) { throw null; }
public static unsafe System.Numerics.Vector<float> GatherVectorFirstFaulting(System.Numerics.Vector<float> mask, float* address, System.Numerics.Vector<int> indices) { throw null; }
// public static unsafe System.Numerics.Vector<float> GatherVectorFirstFaulting(System.Numerics.Vector<float> mask, System.Numerics.Vector<uint> addresses) { throw null; }
public static unsafe System.Numerics.Vector<float> GatherVectorFirstFaulting(System.Numerics.Vector<float> mask, float* address, System.Numerics.Vector<uint> indices) { throw null; }
// public static unsafe System.Numerics.Vector<uint> GatherVectorFirstFaulting(System.Numerics.Vector<uint> mask, System.Numerics.Vector<uint> addresses) { throw null; }
public static unsafe System.Numerics.Vector<uint> GatherVectorFirstFaulting(System.Numerics.Vector<uint> mask, uint* address, System.Numerics.Vector<int> indices) { throw null; }
public static unsafe System.Numerics.Vector<uint> GatherVectorFirstFaulting(System.Numerics.Vector<uint> mask, uint* address, System.Numerics.Vector<uint> indices) { throw null; }
public static unsafe System.Numerics.Vector<ulong> GatherVectorFirstFaulting(System.Numerics.Vector<ulong> mask, System.Numerics.Vector<ulong> addresses) { throw null; }
public static unsafe System.Numerics.Vector<ulong> GatherVectorFirstFaulting(System.Numerics.Vector<ulong> mask, ulong* address, System.Numerics.Vector<long> indices) { throw null; }
public static unsafe System.Numerics.Vector<ulong> GatherVectorFirstFaulting(System.Numerics.Vector<ulong> mask, ulong* address, System.Numerics.Vector<ulong> indices) { throw null; }
public static unsafe System.Numerics.Vector<int> GatherVectorInt16SignExtend(System.Numerics.Vector<int> mask, short* address, System.Numerics.Vector<int> indices) { throw null; }
// public static System.Numerics.Vector<int> GatherVectorInt16SignExtend(System.Numerics.Vector<int> mask, System.Numerics.Vector<uint> addresses) { throw null; }
public static unsafe System.Numerics.Vector<int> GatherVectorInt16SignExtend(System.Numerics.Vector<int> mask, short* address, System.Numerics.Vector<uint> indices) { throw null; }
@ -5009,15 +4989,6 @@ namespace System.Runtime.Intrinsics.Arm
public static ulong GetActiveElementCount(System.Numerics.Vector<uint> mask, System.Numerics.Vector<uint> from) { throw null; }
public static ulong GetActiveElementCount(System.Numerics.Vector<ulong> mask, System.Numerics.Vector<ulong> from) { throw null; }
public static System.Numerics.Vector<byte> GetFfrByte() { throw null; }
public static System.Numerics.Vector<short> GetFfrInt16() { throw null; }
public static System.Numerics.Vector<int> GetFfrInt32() { throw null; }
public static System.Numerics.Vector<long> GetFfrInt64() { throw null; }
public static System.Numerics.Vector<sbyte> GetFfrSByte() { throw null; }
public static System.Numerics.Vector<ushort> GetFfrUInt16() { throw null; }
public static System.Numerics.Vector<uint> GetFfrUInt32() { throw null; }
public static System.Numerics.Vector<ulong> GetFfrUInt64() { throw null; }
public static System.Numerics.Vector<byte> LeadingSignCount(System.Numerics.Vector<sbyte> value) { throw null; }
public static System.Numerics.Vector<ushort> LeadingSignCount(System.Numerics.Vector<short> value) { throw null; }
public static System.Numerics.Vector<uint> LeadingSignCount(System.Numerics.Vector<int> value) { throw null; }
@ -5092,18 +5063,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe System.Numerics.Vector<ushort> LoadVectorByteZeroExtendToUInt16(System.Numerics.Vector<ushort> mask, byte* address) { throw null; }
public static unsafe System.Numerics.Vector<uint> LoadVectorByteZeroExtendToUInt32(System.Numerics.Vector<uint> mask, byte* address) { throw null; }
public static unsafe System.Numerics.Vector<ulong> LoadVectorByteZeroExtendToUInt64(System.Numerics.Vector<ulong> mask, byte* address) { throw null; }
public static unsafe System.Numerics.Vector<byte> LoadVectorFirstFaulting(System.Numerics.Vector<byte> mask, byte* address) { throw null; }
public static unsafe System.Numerics.Vector<double> LoadVectorFirstFaulting(System.Numerics.Vector<double> mask, double* address) { throw null; }
public static unsafe System.Numerics.Vector<short> LoadVectorFirstFaulting(System.Numerics.Vector<short> mask, short* address) { throw null; }
public static unsafe System.Numerics.Vector<int> LoadVectorFirstFaulting(System.Numerics.Vector<int> mask, int* address) { throw null; }
public static unsafe System.Numerics.Vector<long> LoadVectorFirstFaulting(System.Numerics.Vector<long> mask, long* address) { throw null; }
public static unsafe System.Numerics.Vector<sbyte> LoadVectorFirstFaulting(System.Numerics.Vector<sbyte> mask, sbyte* address) { throw null; }
public static unsafe System.Numerics.Vector<float> LoadVectorFirstFaulting(System.Numerics.Vector<float> mask, float* address) { throw null; }
public static unsafe System.Numerics.Vector<ushort> LoadVectorFirstFaulting(System.Numerics.Vector<ushort> mask, ushort* address) { throw null; }
public static unsafe System.Numerics.Vector<uint> LoadVectorFirstFaulting(System.Numerics.Vector<uint> mask, uint* address) { throw null; }
public static unsafe System.Numerics.Vector<ulong> LoadVectorFirstFaulting(System.Numerics.Vector<ulong> mask, ulong* address) { throw null; }
public static unsafe System.Numerics.Vector<int> LoadVectorInt16SignExtendToInt32(System.Numerics.Vector<int> mask, short* address) { throw null; }
public static unsafe System.Numerics.Vector<long> LoadVectorInt16SignExtendToInt64(System.Numerics.Vector<long> mask, short* address) { throw null; }
public static unsafe System.Numerics.Vector<uint> LoadVectorInt16SignExtendToUInt32(System.Numerics.Vector<uint> mask, short* address) { throw null; }
@ -5524,15 +5483,6 @@ namespace System.Runtime.Intrinsics.Arm
public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector<ulong> mask, byte* address, System.Numerics.Vector<long> offsets, System.Numerics.Vector<ulong> data) { throw null; }
public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector<ulong> mask, byte* address, System.Numerics.Vector<ulong> offsets, System.Numerics.Vector<ulong> data) { throw null; }
public static unsafe void SetFfr(System.Numerics.Vector<byte> value) { throw null; }
public static unsafe void SetFfr(System.Numerics.Vector<short> value) { throw null; }
public static unsafe void SetFfr(System.Numerics.Vector<int> value) { throw null; }
public static unsafe void SetFfr(System.Numerics.Vector<long> value) { throw null; }
public static unsafe void SetFfr(System.Numerics.Vector<sbyte> value) { throw null; }
public static unsafe void SetFfr(System.Numerics.Vector<ushort> value) { throw null; }
public static unsafe void SetFfr(System.Numerics.Vector<uint> value) { throw null; }
public static unsafe void SetFfr(System.Numerics.Vector<ulong> value) { throw null; }
public static System.Numerics.Vector<byte> ShiftLeftLogical(System.Numerics.Vector<byte> left, System.Numerics.Vector<byte> right) { throw null; }
public static System.Numerics.Vector<byte> ShiftLeftLogical(System.Numerics.Vector<byte> left, System.Numerics.Vector<ulong> right) { throw null; }
public static System.Numerics.Vector<short> ShiftLeftLogical(System.Numerics.Vector<short> left, System.Numerics.Vector<ushort> right) { throw null; }

View file

@ -3516,15 +3516,6 @@ const string SecureHashOpTest_ValidationLogic = @"{RetBaseType}[] expectedResult
("SveExtractVectorTest.template", new Dictionary<string, string> { ["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<string, string> { ["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<string, string> { ["TestName"] = "Sve_Ffr_byte", ["VectorBaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()"}),
("SveFfrTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_Ffr_short", ["VectorBaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()"}),
("SveFfrTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_Ffr_int", ["VectorBaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()"}),
("SveFfrTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_Ffr_long", ["VectorBaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()"}),
("SveFfrTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_Ffr_sbyte", ["VectorBaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()"}),
("SveFfrTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_Ffr_ushort", ["VectorBaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()"}),
("SveFfrTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_Ffr_uint", ["VectorBaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()"}),
("SveFfrTest.template", new Dictionary<string, string> { ["TestName"] = "Sve_Ffr_ulong", ["VectorBaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()"}),
// ("SveGatherVectorVectorBases.template", new Dictionary<string, string> { ["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<string, string> { ["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<string, string> { ["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 @@ const string SecureHashOpTest_ValidationLogic = @"{RetBaseType}[] expectedResult
("SveGatherVectorIndices.template", new Dictionary<string, string> {["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<string, string> {["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<string, string> {["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<string, string> {["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<string, string> {["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> {["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<string, string> {["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<string, string> {["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 @@ const string SecureHashOpTest_ValidationLogic = @"{RetBaseType}[] expectedResult
("SveLoadNonFaultingUnOpTest.template", new Dictionary<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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]"}),

View file

@ -8507,308 +8507,6 @@ namespace JIT.HardwareIntrinsics.Arm
return result;
}
private static T ConditionalSelectResult<T>(T maskResult, T result, T falseResult) where T : INumberBase<T>
{
return (maskResult != T.Zero) ? result : falseResult;
}
private static T ConditionalSelectTrueResult<T>(T maskResult, T result, T trueResult) where T : INumberBase<T>
{
return (maskResult != T.Zero) ? trueResult : result;
}
private static bool CheckLoadVectorBehaviorCore<T>(T[] firstOp, T[] result, Func<int, T, T> map) where T : INumberBase<T>
{
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>(T[] firstOp, T[] result) where T : INumberBase<T>
{
return CheckLoadVectorBehaviorCore(firstOp, result, (_, loadResult) => loadResult);
}
public static bool CheckLoadVectorBehavior<T>(T[] maskOp, T[] firstOp, T[] result, T[] falseOp) where T : INumberBase<T>
{
return CheckLoadVectorBehaviorCore(firstOp, result, (i, loadResult) => ConditionalSelectResult(maskOp[i], loadResult, falseOp[i]));
}
private static T GetGatherVectorResultByIndex<T, ExtendedElementT, Index>(int index, T[] mask, ExtendedElementT[] data, Index[] indices)
where T : INumberBase<T>
where ExtendedElementT : INumberBase<ExtendedElementT>
where Index : IBinaryInteger<Index>
{
return (mask[index] == T.Zero) ? T.Zero : T.CreateTruncating(data[int.CreateChecked(indices[index])]);
}
private static unsafe T GetGatherVectorBasesResultByIndex<T, AddressT, ExtendedElementT>(int index, T[] mask, AddressT[] data)
where T : INumberBase<T>
where AddressT : unmanaged, INumberBase<AddressT>
where ExtendedElementT : unmanaged, INumberBase<ExtendedElementT>
{
return (mask[index] == T.Zero) ? T.Zero : T.CreateTruncating(*(ExtendedElementT*)Unsafe.BitCast<AddressT, nint>(data[index]));
}
private static bool CheckGatherVectorBehaviorCore<T, ExtendedElementT, Index>(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result, Func<int, T, T> map)
where T : INumberBase<T>
where ExtendedElementT : INumberBase<ExtendedElementT>
where Index : IBinaryInteger<Index>
{
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, AddressT, ExtendedElementT>(T[] mask, AddressT[] data, T[] result, Func<int, T, T> map)
where T : INumberBase<T>
where AddressT : unmanaged, INumberBase<AddressT>
where ExtendedElementT : unmanaged, INumberBase<ExtendedElementT>
{
for (var i = 0; i < mask.Length; i++)
{
T gatherResult = GetGatherVectorBasesResultByIndex<T, AddressT, ExtendedElementT>(i, mask, data);
gatherResult = map(i, gatherResult);
if (result[i] != gatherResult)
{
return false;
}
}
return true;
}
public static bool CheckGatherVectorBehavior<T, ExtendedElementT, Index>(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result)
where T : INumberBase<T>
where ExtendedElementT : INumberBase<ExtendedElementT>
where Index : IBinaryInteger<Index>
{
return CheckGatherVectorBehaviorCore(mask, data, indices, result, (_, gatherResult) => gatherResult);
}
public static bool CheckGatherVectorConditionalSelectBehavior<T, ExtendedElementT, Index>(T[] cndSelMask, T[] mask, ExtendedElementT[] data, Index[] indices, T[] cndSelFalse, T[] result)
where T : INumberBase<T>
where ExtendedElementT : INumberBase<ExtendedElementT>
where Index : IBinaryInteger<Index>
{
return CheckGatherVectorBehaviorCore(mask, data, indices, result, (i, gatherResult) => ConditionalSelectResult(cndSelMask[i], gatherResult, cndSelFalse[i]));
}
public static bool CheckGatherVectorConditionalSelectTrueBehavior<T, ExtendedElementT, Index>(T[] cndSelMask, T[] mask, ExtendedElementT[] data, Index[] indices, T[] cndSelTrue, T[] result)
where T : INumberBase<T>
where ExtendedElementT : INumberBase<ExtendedElementT>
where Index : IBinaryInteger<Index>
{
return CheckGatherVectorBehaviorCore(mask, data, indices, result, (i, gatherResult) => ConditionalSelectTrueResult(cndSelMask[i], gatherResult, cndSelTrue[i]));
}
public static bool CheckGatherVectorBasesBehavior<T, AddressT, ExtendedElementT>(T[] mask, AddressT[] data, T[] result)
where T : INumberBase<T>
where AddressT : unmanaged, INumberBase<AddressT>
where ExtendedElementT : unmanaged, INumberBase<ExtendedElementT>
{
return CheckGatherVectorBasesBehaviorCore<T, AddressT, ExtendedElementT>(mask, data, result, (_, gatherResult) => gatherResult);
}
public static bool CheckGatherVectorBasesConditionalSelectBehavior<T, AddressT, ExtendedElementT>(T[] cndSelMask, T[] mask, AddressT[] data, T[] cndSelFalse, T[] result)
where T : INumberBase<T>
where AddressT : unmanaged, INumberBase<AddressT>
where ExtendedElementT : unmanaged, INumberBase<ExtendedElementT>
{
return CheckGatherVectorBasesBehaviorCore<T, AddressT, ExtendedElementT>(mask, data, result, (i, gatherResult) => ConditionalSelectResult(cndSelMask[i], gatherResult, cndSelFalse[i]));
}
public static bool CheckGatherVectorBasesConditionalSelectTrueBehavior<T, AddressT, ExtendedElementT>(T[] cndSelMask, T[] mask, AddressT[] data, T[] cndSelTrue, T[] result)
where T : INumberBase<T>
where AddressT : unmanaged, INumberBase<AddressT>
where ExtendedElementT : unmanaged, INumberBase<ExtendedElementT>
{
return CheckGatherVectorBasesBehaviorCore<T, AddressT, ExtendedElementT>(mask, data, result, (i, gatherResult) => ConditionalSelectTrueResult(cndSelMask[i], gatherResult, cndSelTrue[i]));
}
private static bool CheckFirstFaultingBehaviorCore<T, TFault>(T[] result, Vector<TFault> faultResult, Func<int, bool> checkIter)
where T : INumberBase<T>
where TFault : INumberBase<TFault>
{
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<T>(Vector<T> faultResult) where T : INumberBase<T>
{
for (var i = 0; i < Vector<T>.Count; i++)
{
if (faultResult[i] == T.Zero)
{
return true;
}
}
return false;
}
public static bool CheckLoadVectorFirstFaultingBehavior<T, TFault>(T[] firstOp, T[] result, Vector<TFault> faultResult)
where T : INumberBase<T>
where TFault : INumberBase<TFault>
{
// 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<TFault>(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, ExtendedElementT, Index, TFault>(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result, Vector<TFault> faultResult)
where T : INumberBase<T>
where ExtendedElementT : INumberBase<ExtendedElementT>
where Index : IBinaryInteger<Index>
where TFault : INumberBase<TFault>
{
// 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<TFault>(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, AddressT, ExtendedElementT, TFault>(T[] mask, AddressT[] data, T[] result, Vector<TFault> faultResult)
where T : INumberBase<T>
where AddressT : unmanaged, INumberBase<AddressT>
where ExtendedElementT : unmanaged, INumberBase<ExtendedElementT>
where TFault : INumberBase<TFault>
{
// 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<TFault>(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<T, AddressT, ExtendedElementT>(i, mask, data) == result[i]);
}
public static T[] CreateBreakPropagateMask<T>(T[] op1, T[] op2) where T : IBinaryInteger<T>
{
var count = op1.Length;

View file

@ -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<byte>(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<Vector<{VectorBaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{VectorBaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector<{VectorBaseType}>>());
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<Vector<{VectorBaseType}>>() / sizeof({VectorBaseType});
private static readonly int RetElementCount = Unsafe.SizeOf<Vector<{VectorBaseType}>>() / 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<Vector<{VectorBaseType}>, byte>(ref _mask), ref Unsafe.As<{VectorBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<Vector<{VectorBaseType}>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector<{VectorBaseType}>, byte>(ref _fld1), ref Unsafe.As<{VectorBaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector<{VectorBaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector<{VectorBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{VectorBaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector<{VectorBaseType}>>());
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<Vector<{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 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<Vector<{VectorBaseType}>>(_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<Vector<{VectorBaseType}>>(_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<byte>(result), (uint)Unsafe.SizeOf<Vector<{VectorBaseType}>>());
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<byte>(op1), (uint)Unsafe.SizeOf<Vector<{VectorBaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{VectorBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector<{VectorBaseType}>>());
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;
}
}
}
}

View file

@ -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<byte>(sizeOfinBounded, PoisonPagePlacement.After);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(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<byte> 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<T>.
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<byte>(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<byte>(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<byte>(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)(Unsafe.SizeOf<{Op2BaseType}>() * Op2ElementCount));
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(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<byte>(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<byte>(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<byte>(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)(Unsafe.SizeOf<{Op2BaseType}>() * Op2ElementCount));
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(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<byte>(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<byte>(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<byte>(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<byte>(op3), (uint)(inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>()));
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(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;
}
}
}
}

View file

@ -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<byte>(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(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<byte>(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<byte>(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<byte>(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<byte>(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)(Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()));
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(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<byte>(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<byte>(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)(Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()));
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(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<byte>(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<byte>(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<byte>(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(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;
}
}
}
}

View file

@ -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)
{

View file

@ -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)
{

View file

@ -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<byte>(sizeOfinBounded, PoisonPagePlacement.After);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(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<byte> 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<byte>(firstOp), (uint)Unsafe.SizeOf<{RetVectorType}<{Op2BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(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<byte>(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<byte>(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;
}
}
}
}

View file

@ -10,10 +10,5 @@
<Compile Include="Program.Sve.cs" />
<Compile Include="..\Shared\Helpers.cs" />
<Compile Include="..\Shared\Program.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Creation.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Unix.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Windows.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/PoisonPagePlacement.cs" />
</ItemGroup>
</Project>

View file

@ -10,10 +10,5 @@
<Compile Include="Program.Sve.cs" />
<Compile Include="..\Shared\Helpers.cs" />
<Compile Include="..\Shared\Program.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Creation.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Unix.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/BoundedMemory.Windows.cs" />
<Compile Include="$(RepoRoot)src/libraries/Common/tests/TestUtilities/System/Buffers/PoisonPagePlacement.cs" />
</ItemGroup>
</Project>