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:
parent
991ae97a1d
commit
dc7d7bc2c8
22 changed files with 165 additions and 3218 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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]"}),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue