diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 3ac9792c8eb07..83eeb02409eee 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -260,6 +260,7 @@ void HWIntrinsicInfo::lookupImmBounds( case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: case NI_AdvSimd_StoreSelectedScalar: + case NI_AdvSimd_Arm64_StoreSelectedScalar: case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: case NI_AdvSimd_Arm64_InsertSelectedScalar: immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType) - 1; @@ -1796,6 +1797,65 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_AdvSimd_StoreSelectedScalar: + case NI_AdvSimd_Arm64_StoreSelectedScalar: + { + assert(sig->numArgs == 3); + assert(retType == TYP_VOID); + + CORINFO_ARG_LIST_HANDLE arg1 = sig->args; + CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1); + CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2); + var_types argType = TYP_UNKNOWN; + CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE; + argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass))); + op3 = impPopStack().val; + argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); + op2 = impPopStack().val; + unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(argClass); + int immLowerBound = 0; + int immUpperBound = 0; + + if (op2->TypeGet() == TYP_STRUCT) + { + info.compNeedsConsecutiveRegisters = true; + + if (!op2->OperIs(GT_LCL_VAR)) + { + unsigned tmp = lvaGrabTemp(true DEBUGARG("StoreSelectedScalarN")); + + impStoreTemp(tmp, op2, CHECK_SPILL_NONE); + op2 = gtNewLclvNode(tmp, argType); + } + op2 = gtConvertTableOpToFieldList(op2, fieldCount); + } + else + { + // While storing from a single vector, both Vector128 and Vector64 API calls are in AdvSimd class. + // Thus, we get simdSize as 8 for both of the calls. We re-calculate that simd size for such API calls. + getBaseJitTypeAndSizeOfSIMDType(argClass, &simdSize); + } + + assert(HWIntrinsicInfo::isImmOp(intrinsic, op3)); + HWIntrinsicInfo::lookupImmBounds(intrinsic, simdSize, simdBaseType, &immLowerBound, &immUpperBound); + op3 = addRangeCheckIfNeeded(intrinsic, op3, (!op3->IsCnsIntOrI()), immLowerBound, immUpperBound); + argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass))); + op1 = getArgForHWIntrinsic(argType, argClass); + + if (op1->OperIs(GT_CAST)) + { + // Although the API specifies a pointer, if what we have is a BYREF, that's what + // we really want, so throw away the cast. + if (op1->gtGetOp1()->TypeGet() == TYP_BYREF) + { + op1 = op1->gtGetOp1(); + } + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize); + break; + } + case NI_Vector64_Sum: case NI_Vector128_Sum: { diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 1bf08f24d0491..7b903a2deb0e4 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -493,6 +493,52 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) ins = varTypeIsUnsigned(intrin.baseType) ? INS_umsubl : INS_smsubl; break; + case NI_AdvSimd_StoreSelectedScalar: + case NI_AdvSimd_Arm64_StoreSelectedScalar: + { + unsigned regCount = 0; + if (intrin.op2->OperIsFieldList()) + { + GenTreeFieldList* fieldList = intrin.op2->AsFieldList(); + GenTree* firstField = fieldList->Uses().GetHead()->GetNode(); + op2Reg = firstField->GetRegNum(); + + INDEBUG(regNumber argReg = op2Reg); + for (GenTreeFieldList::Use& use : fieldList->Uses()) + { + regCount++; +#ifdef DEBUG + GenTree* argNode = use.GetNode(); + assert(argReg == argNode->GetRegNum()); + argReg = REG_NEXT(argReg); +#endif + } + } + else + { + regCount = 1; + } + + switch (regCount) + { + case 1: + ins = INS_st1; + break; + case 2: + ins = INS_st2; + break; + case 3: + ins = INS_st3; + break; + case 4: + ins = INS_st4; + break; + default: + unreached(); + } + break; + } + default: ins = HWIntrinsicInfo::lookupIns(intrin.id, intrin.baseType); break; @@ -773,7 +819,18 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) op1Reg); break; + case NI_AdvSimd_Arm64_StorePair: + case NI_AdvSimd_Arm64_StorePairNonTemporal: + GetEmitter()->emitIns_R_R_R(ins, emitSize, op2Reg, op3Reg, op1Reg); + break; + + case NI_AdvSimd_Arm64_StorePairScalar: + case NI_AdvSimd_Arm64_StorePairScalarNonTemporal: + GetEmitter()->emitIns_R_R_R(ins, emitTypeSize(intrin.baseType), op2Reg, op3Reg, op1Reg); + break; + case NI_AdvSimd_StoreSelectedScalar: + case NI_AdvSimd_Arm64_StoreSelectedScalar: { HWIntrinsicImmOpHelper helper(this, intrin.op3, node); @@ -783,18 +840,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitIns_R_R_I(ins, emitSize, op2Reg, op1Reg, elementIndex, opt); } - } - break; - - case NI_AdvSimd_Arm64_StorePair: - case NI_AdvSimd_Arm64_StorePairNonTemporal: - GetEmitter()->emitIns_R_R_R(ins, emitSize, op2Reg, op3Reg, op1Reg); - break; - - case NI_AdvSimd_Arm64_StorePairScalar: - case NI_AdvSimd_Arm64_StorePairScalarNonTemporal: - GetEmitter()->emitIns_R_R_R(ins, emitTypeSize(intrin.baseType), op2Reg, op3Reg, op1Reg); break; + } case NI_AdvSimd_StoreVector64x2AndZip: case NI_AdvSimd_StoreVector64x3AndZip: diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h index 699184d7a9973..1a6c8cd48081b 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/jit/hwintrinsiclistarm64.h @@ -478,7 +478,7 @@ HARDWARE_INTRINSIC(AdvSimd, SignExtendWideningLower, HARDWARE_INTRINSIC(AdvSimd, SignExtendWideningUpper, 16, 1, true, {INS_sxtl2, INS_invalid, INS_sxtl2, INS_invalid, INS_sxtl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AdvSimd, SqrtScalar, 8, 1, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsqrt, INS_fsqrt}, HW_Category_SIMD, HW_Flag_SIMDScalar) HARDWARE_INTRINSIC(AdvSimd, Store, -1, 2, true, {INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromSecondArg|HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(AdvSimd, StoreSelectedScalar, -1, 3, true, {INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromSecondArg|HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, StoreSelectedScalar, 8, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd, StoreVector64x2AndZip, 8, 2, true, {INS_st2, INS_st2, INS_st2, INS_st2, INS_st2, INS_st2, INS_invalid, INS_invalid, INS_st2, INS_invalid}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd, StoreVector64x3AndZip, 8, 2, true, {INS_st3, INS_st3, INS_st3, INS_st3, INS_st3, INS_st3, INS_invalid, INS_invalid, INS_st3, INS_invalid}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd, StoreVector64x4AndZip, 8, 2, true, {INS_st4, INS_st4, INS_st4, INS_st4, INS_st4, INS_st4, INS_invalid, INS_invalid, INS_st4, INS_invalid}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NeedsConsecutiveRegisters) @@ -676,6 +676,7 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64, StorePair, HARDWARE_INTRINSIC(AdvSimd_Arm64, StorePairScalar, 8, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_stp, INS_stp, INS_invalid, INS_invalid, INS_stp, INS_invalid}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd_Arm64, StorePairScalarNonTemporal, 8, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_stnp, INS_stnp, INS_invalid, INS_invalid, INS_stnp, INS_invalid}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd_Arm64, StorePairNonTemporal, -1, 3, true, {INS_stnp, INS_stnp, INS_stnp, INS_stnp, INS_stnp, INS_stnp, INS_stnp, INS_stnp, INS_stnp, INS_stp}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, StoreSelectedScalar, 16, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd_Arm64, StoreVector128x2AndZip, 16, 2, true, {INS_st2, INS_st2, INS_st2, INS_st2, INS_st2, INS_st2, INS_st2, INS_st2, INS_st2, INS_st2}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd_Arm64, StoreVector128x3AndZip, 16, 2, true, {INS_st3, INS_st3, INS_st3, INS_st3, INS_st3, INS_st3, INS_st3, INS_st3, INS_st3, INS_st3}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd_Arm64, StoreVector128x4AndZip, 16, 2, true, {INS_st4, INS_st4, INS_st4, INS_st4, INS_st4, INS_st4, INS_st4, INS_st4, INS_st4, INS_st4}, HW_Category_MemoryStore, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NeedsConsecutiveRegisters) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 0ef5399dff06d..9a314539fd9f9 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -3035,6 +3035,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_ExtractVector64: case NI_AdvSimd_ExtractVector128: case NI_AdvSimd_StoreSelectedScalar: + case NI_AdvSimd_Arm64_StoreSelectedScalar: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op3)); if (intrin.op3->IsCnsIntOrI()) diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 8d4eee488dd00..0b4b383c491b5 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1412,6 +1412,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou case NI_AdvSimd_ExtractVector64: case NI_AdvSimd_ExtractVector128: case NI_AdvSimd_StoreSelectedScalar: + case NI_AdvSimd_Arm64_StoreSelectedScalar: needBranchTargetReg = !intrin.op3->isContainedIntOrIImmed(); break; @@ -1577,6 +1578,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou { case NI_AdvSimd_VectorTableLookup: case NI_AdvSimd_Arm64_VectorTableLookup: + { assert(intrin.op2 != nullptr); srcCount += BuildOperandUses(intrin.op2); assert(dstCount == 1); @@ -1584,9 +1586,11 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou BuildDef(intrinsicTree); *pDstCount = 1; break; + } case NI_AdvSimd_VectorTableLookupExtension: case NI_AdvSimd_Arm64_VectorTableLookupExtension: + { assert(intrin.op2 != nullptr); assert(intrin.op3 != nullptr); assert(isRMW); @@ -1597,6 +1601,23 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou BuildDef(intrinsicTree); *pDstCount = 1; break; + } + + case NI_AdvSimd_StoreSelectedScalar: + case NI_AdvSimd_Arm64_StoreSelectedScalar: + { + assert(intrin.op1 != nullptr); + assert(intrin.op3 != nullptr); + srcCount += BuildConsecutiveRegistersForUse(intrin.op2); + if (!intrin.op3->isContainedIntOrIImmed()) + { + srcCount += BuildOperandUses(intrin.op3); + } + assert(dstCount == 0); + buildInternalRegisterUses(); + *pDstCount = 0; + break; + } case NI_AdvSimd_StoreVector64x2AndZip: case NI_AdvSimd_StoreVector64x3AndZip: @@ -1610,12 +1631,14 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou case NI_AdvSimd_Arm64_StoreVector128x2: case NI_AdvSimd_Arm64_StoreVector128x3: case NI_AdvSimd_Arm64_StoreVector128x4: + { assert(intrin.op1 != nullptr); srcCount += BuildConsecutiveRegistersForUse(intrin.op2); assert(dstCount == 0); buildInternalRegisterUses(); *pDstCount = 0; break; + } case NI_AdvSimd_LoadAndInsertScalarVector64x2: case NI_AdvSimd_LoadAndInsertScalarVector64x3: @@ -1623,6 +1646,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: + { assert(intrin.op2 != nullptr); assert(intrin.op3 != nullptr); assert(isRMW); @@ -1634,6 +1658,8 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou assert(intrinsicTree->OperIsMemoryLoadOrStore()); srcCount += BuildAddrUses(intrin.op3); FALLTHROUGH; + } + case NI_AdvSimd_LoadVector64x2AndUnzip: case NI_AdvSimd_LoadVector64x3AndUnzip: case NI_AdvSimd_LoadVector64x4AndUnzip: diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs index 26e4f2cbd2467..3202d6dc94a62 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs @@ -3776,6 +3776,177 @@ internal Arm64() { } /// public static unsafe void StorePairScalarNonTemporal(uint* address, Vector64 value1, Vector64 value2) { throw new PlatformNotSupportedException(); } + /// + /// void vst2_lane_s8 (int8_t * ptr, int8x16x2_t val, const int lane) + /// A64: ST2 { Vt.16B, Vt+1.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(15))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst2_lane_s8 (int8_t * ptr, int8x16x2_t val, const int lane) + /// A64: ST2 { Vt.16B, Vt+1.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(15))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst2_lane_s16 (int16_t * ptr, int16x8x2_t val, const int lane) + /// A64: ST2 { Vt.8H, Vt+1.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst2_lane_s16 (int16_t * ptr, int16x8x2_t val, const int lane) + /// A64: ST2 { Vt.8H, Vt+1.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst2_lane_s32 (int32_t * ptr, int32x4x2_t val, const int lane) + /// A64: ST2 { Vt.4S, Vt+1.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst2_lane_s32 (int32_t * ptr, int32x4x2_t val, const int lane) + /// A64: ST2 { Vt.4S, Vt+1.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.2D, Vt+1.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(long* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.2D, Vt+1.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ulong* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst2_lane_f32 (float32_t * ptr, float32x2x2_t val, const int lane) + /// A64: ST2 { Vt.4S, Vt+1.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.2D, Vt+1.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(double* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst3_lane_s8 (int8_t * ptr, int8x16x3_t val, const int lane) + /// A64: ST3 { Vt.16B, Vt+1.16B, Vt+2.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(15))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst3_lane_s8 (int8_t * ptr, int8x16x3_t val, const int lane) + /// A64: ST3 { Vt.16B, Vt+1.16B, Vt+2.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(15))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst3_lane_s16 (int16_t * ptr, int16x8x3_t val, const int lane) + /// A64: ST3 { Vt.8H, Vt+1.8H, Vt+2.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst3_lane_s16 (int16_t * ptr, int16x8x3_t val, const int lane) + /// A64: ST3 { Vt.8H, Vt+1.8H, Vt+2.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst3_lane_s32 (int32_t * ptr, int32x4x3_t val, const int lane) + /// A64: ST3 { Vt.4S, Vt+1.4S, Vt+2.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst3_lane_s32 (int32_t * ptr, int32x4x3_t val, const int lane) + /// A64: ST3 { Vt.4S, Vt+1.4S, Vt+2.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.2D, Vt+1.2D, Vt+2.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(long* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.2D, Vt+1.2D, Vt+2.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ulong* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst3_lane_f32 (float32_t * ptr, float32x2x3_t val, const int lane) + /// A64: ST3 { Vt.4S, Vt+1.4S, Vt+2.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.2D, Vt+1.2D, Vt+2.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(double* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst4_lane_s8 (int8_t * ptr, int8x16x4_t val, const int lane) + /// A64: ST4 { Vt.16B, Vt+1.16B, Vt+2.16B, Vt+3.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(15))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst4_lane_s8 (int8_t * ptr, int8x16x4_t val, const int lane) + /// A64: ST4 { Vt.16B, Vt+1.16B, Vt+2.16B, Vt+3.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(15))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst4_lane_s16 (int16_t * ptr, int16x8x4_t val, const int lane) + /// A64: ST4 { Vt.8H, Vt+1.8H, Vt+2.8H, Vt+3.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst4_lane_s16 (int16_t * ptr, int16x8x4_t val, const int lane) + /// A64: ST4 { Vt.8H, Vt+1.8H, Vt+2.8H, Vt+3.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst4_lane_s32 (int32_t * ptr, int32x4x4_t val, const int lane) + /// A64: ST4 { Vt.4S, Vt+1.4S, Vt+2.4S, Vt+3.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst4_lane_s32 (int32_t * ptr, int32x4x4_t val, const int lane) + /// A64: ST4 { Vt.4S, Vt+1.4S, Vt+2.4S, Vt+3.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.2D, Vt+1.2D, Vt+2.2D, Vt+3.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(long* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.2D, Vt+1.2D, Vt+2.2D, Vt+3.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ulong* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// void vst4_lane_f32 (float32_t * ptr, float32x2x4_t val, const int lane) + /// A64: ST4 { Vt.4S, Vt+1.4S, Vt+2.4S, Vt+3.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.2D, Vt+1.2D, Vt+2.2D, Vt+3.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(double* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + /// /// A64: ST2 { Vn.16B, Vn+1.16B }, [Xn] /// @@ -15757,6 +15928,111 @@ internal Arm64() { } /// public static unsafe void StoreSelectedScalar(ulong* address, Vector128 value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + /// + /// A64: ST2 { Vt.8B, Vt+1.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.8B, Vt+1.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.4H, Vt+1.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.4H, Vt+1.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.2S, Vt+1.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.2S, Vt+1.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST2 { Vt.2S, Vt+1.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.8B, Vt+1.8B, Vt+2.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.8B, Vt+1.8B, Vt+2.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.4H, Vt+1.4H, Vt+2.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.4H, Vt+1.4H, Vt+2.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.2S, Vt+1.2S, Vt+2.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.2S, Vt+1.2S, Vt+2.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST3 { Vt.2S, Vt+1.2S, Vt+2.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.8B, Vt+1.8B, Vt+2.8B, Vt+3.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.8B, Vt+1.8B, Vt+2.8B, Vt+3.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.4H, Vt+1.4H, Vt+2.4H, Vt+3.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.4H, Vt+1.4H, Vt+2.4H, Vt+3.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.2S, Vt+1.2S, Vt+2.2S, Vt+3.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.2S, Vt+1.2S, Vt+2.2S, Vt+3.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + + /// + /// A64: ST4 { Vt.2S, Vt+1.2S, Vt+2.2S, Vt+3.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + /// /// A64: ST2 { Vn.8B, Vn+1.8B }, [Xn] /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs index bbdfad39422d5..97bf19cde73e6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs @@ -3774,6 +3774,177 @@ internal Arm64() { } /// public static unsafe void StorePairScalarNonTemporal(uint* address, Vector64 value1, Vector64 value2) => StorePairScalarNonTemporal(address, value1, value2); + /// + /// void vst2_lane_s8 (int8_t * ptr, int8x16x2_t val, const int lane) + /// A64: ST2 { Vt.16B, Vt+1.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(15))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst2_lane_s8 (int8_t * ptr, int8x16x2_t val, const int lane) + /// A64: ST2 { Vt.16B, Vt+1.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(15))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst2_lane_s16 (int16_t * ptr, int16x8x2_t val, const int lane) + /// A64: ST2 { Vt.8H, Vt+1.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst2_lane_s16 (int16_t * ptr, int16x8x2_t val, const int lane) + /// A64: ST2 { Vt.8H, Vt+1.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst2_lane_s32 (int32_t * ptr, int32x4x2_t val, const int lane) + /// A64: ST2 { Vt.4S, Vt+1.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst2_lane_s32 (int32_t * ptr, int32x4x2_t val, const int lane) + /// A64: ST2 { Vt.4S, Vt+1.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.2D, Vt+1.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(long* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.2D, Vt+1.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ulong* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst2_lane_f32 (float32_t * ptr, float32x2x2_t val, const int lane) + /// A64: ST2 { Vt.4S, Vt+1.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.2D, Vt+1.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(double* address, (Vector128 value1, Vector128 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst3_lane_s8 (int8_t * ptr, int8x16x3_t val, const int lane) + /// A64: ST3 { Vt.16B, Vt+1.16B, Vt+2.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(15))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst3_lane_s8 (int8_t * ptr, int8x16x3_t val, const int lane) + /// A64: ST3 { Vt.16B, Vt+1.16B, Vt+2.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(15))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst3_lane_s16 (int16_t * ptr, int16x8x3_t val, const int lane) + /// A64: ST3 { Vt.8H, Vt+1.8H, Vt+2.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst3_lane_s16 (int16_t * ptr, int16x8x3_t val, const int lane) + /// A64: ST3 { Vt.8H, Vt+1.8H, Vt+2.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst3_lane_s32 (int32_t * ptr, int32x4x3_t val, const int lane) + /// A64: ST3 { Vt.4S, Vt+1.4S, Vt+2.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst3_lane_s32 (int32_t * ptr, int32x4x3_t val, const int lane) + /// A64: ST3 { Vt.4S, Vt+1.4S, Vt+2.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.2D, Vt+1.2D, Vt+2.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(long* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.2D, Vt+1.2D, Vt+2.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ulong* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst3_lane_f32 (float32_t * ptr, float32x2x3_t val, const int lane) + /// A64: ST3 { Vt.4S, Vt+1.4S, Vt+2.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.2D, Vt+1.2D, Vt+2.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(double* address, (Vector128 value1, Vector128 value2, Vector128 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst4_lane_s8 (int8_t * ptr, int8x16x4_t val, const int lane) + /// A64: ST4 { Vt.16B, Vt+1.16B, Vt+2.16B, Vt+3.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(15))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst4_lane_s8 (int8_t * ptr, int8x16x4_t val, const int lane) + /// A64: ST4 { Vt.16B, Vt+1.16B, Vt+2.16B, Vt+3.16B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(15))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst4_lane_s16 (int16_t * ptr, int16x8x4_t val, const int lane) + /// A64: ST4 { Vt.8H, Vt+1.8H, Vt+2.8H, Vt+3.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst4_lane_s16 (int16_t * ptr, int16x8x4_t val, const int lane) + /// A64: ST4 { Vt.8H, Vt+1.8H, Vt+2.8H, Vt+3.8H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst4_lane_s32 (int32_t * ptr, int32x4x4_t val, const int lane) + /// A64: ST4 { Vt.4S, Vt+1.4S, Vt+2.4S, Vt+3.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst4_lane_s32 (int32_t * ptr, int32x4x4_t val, const int lane) + /// A64: ST4 { Vt.4S, Vt+1.4S, Vt+2.4S, Vt+3.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.2D, Vt+1.2D, Vt+2.2D, Vt+3.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(long* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.2D, Vt+1.2D, Vt+2.2D, Vt+3.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ulong* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// void vst4_lane_f32 (float32_t * ptr, float32x2x4_t val, const int lane) + /// A64: ST4 { Vt.4S, Vt+1.4S, Vt+2.4S, Vt+3.4S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.2D, Vt+1.2D, Vt+2.2D, Vt+3.2D }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(double* address, (Vector128 value1, Vector128 value2, Vector128 value3, Vector128 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + /// /// A64: ST2 { Vn.16B, Vn+1.16B }, [Xn] /// @@ -15754,6 +15925,111 @@ internal Arm64() { } /// public static unsafe void StoreSelectedScalar(ulong* address, Vector128 value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + /// + /// A64: ST2 { Vt.8B, Vt+1.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.8B, Vt+1.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.4H, Vt+1.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.4H, Vt+1.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.2S, Vt+1.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.2S, Vt+1.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.2S, Vt+1.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector64 value1, Vector64 value2) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.8B, Vt+1.8B, Vt+2.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.8B, Vt+1.8B, Vt+2.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.4H, Vt+1.4H, Vt+2.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.4H, Vt+1.4H, Vt+2.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.2S, Vt+1.2S, Vt+2.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST3 { Vt.2S, Vt+1.2S, Vt+2.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST2 { Vt.2S, Vt+1.2S, Vt+2.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector64 value1, Vector64 value2, Vector64 value3) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.8B, Vt+1.8B, Vt+2.8B, Vt+3.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(byte* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.8B, Vt+1.8B, Vt+2.8B, Vt+3.8B }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(sbyte* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(7))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.4H, Vt+1.4H, Vt+2.4H, Vt+3.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(short* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.4H, Vt+1.4H, Vt+2.4H, Vt+3.4H }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(ushort* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(3))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.2S, Vt+1.2S, Vt+2.2S, Vt+3.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(int* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.2S, Vt+1.2S, Vt+2.2S, Vt+3.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(uint* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + + /// + /// A64: ST4 { Vt.2S, Vt+1.2S, Vt+2.2S, Vt+3.2S }[index], [Xn] + /// + public static unsafe void StoreSelectedScalar(float* address, (Vector64 value1, Vector64 value2, Vector64 value3, Vector64 value4) value, [ConstantExpected(Max = (byte)(1))] byte index) => StoreSelectedScalar(address, value, index); + /// /// A64: ST2 { Vn.8B, Vn+1.8B }, [Xn] /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index a4a86567f65ff..f58be580e073c 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -2872,6 +2872,27 @@ public static unsafe void StoreSelectedScalar(ushort* address, System.Runtime.In public static unsafe void StoreSelectedScalar(uint* address, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { } public static unsafe void StoreSelectedScalar(uint* address, System.Runtime.Intrinsics.Vector64 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { } public static unsafe void StoreSelectedScalar(ulong* address, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { } + public static unsafe void StoreSelectedScalar(byte* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(sbyte* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(short* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(ushort* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(int* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(uint* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(float* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(byte* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(sbyte* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(short* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(ushort* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(int* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(uint* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(float* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(byte* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3, System.Runtime.Intrinsics.Vector64 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + public static unsafe void StoreSelectedScalar(sbyte* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3, System.Runtime.Intrinsics.Vector64 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw new PlatformNotSupportedException(); } + public static unsafe void StoreSelectedScalar(short* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3, System.Runtime.Intrinsics.Vector64 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + public static unsafe void StoreSelectedScalar(ushort* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3, System.Runtime.Intrinsics.Vector64 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw new PlatformNotSupportedException(); } + public static unsafe void StoreSelectedScalar(int* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3, System.Runtime.Intrinsics.Vector64 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + public static unsafe void StoreSelectedScalar(uint* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3, System.Runtime.Intrinsics.Vector64 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } + public static unsafe void StoreSelectedScalar(float* address, (System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2, System.Runtime.Intrinsics.Vector64 value3, System.Runtime.Intrinsics.Vector64 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw new PlatformNotSupportedException(); } public unsafe static void StoreVector64x2AndZip(byte* address, (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) value) { throw null; } public unsafe static void StoreVector64x2AndZip(sbyte* address, (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) value) { throw null; } public unsafe static void StoreVector64x2AndZip(short* address, (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) value) { throw null; } @@ -3692,6 +3713,36 @@ public static unsafe void StorePairScalar(uint* address, System.Runtime.Intrinsi public static unsafe void StorePairScalarNonTemporal(int* address, System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) { } public static unsafe void StorePairScalarNonTemporal(float* address, System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) { } public static unsafe void StorePairScalarNonTemporal(uint* address, System.Runtime.Intrinsics.Vector64 value1, System.Runtime.Intrinsics.Vector64 value2) { } + public static unsafe void StoreSelectedScalar(byte* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(sbyte* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(short* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(ushort* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(int* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(uint* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(long* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(ulong* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(float* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(double* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(byte* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(sbyte* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(short* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(ushort* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(int* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(uint* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(long* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(ulong* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(float* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(double* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(byte* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(sbyte* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(short* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(ushort* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(int* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(uint* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(long* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(ulong* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(float* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index) { throw null; } + public static unsafe void StoreSelectedScalar(double* address, (System.Runtime.Intrinsics.Vector128 value1, System.Runtime.Intrinsics.Vector128 value2, System.Runtime.Intrinsics.Vector128 value3, System.Runtime.Intrinsics.Vector128 value4) value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index) { throw null; } public unsafe static void StoreVector128x2AndZip(byte* address, (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) value) { throw null; } public unsafe static void StoreVector128x2AndZip(sbyte* address, (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) value) { throw null; } public unsafe static void StoreVector128x2AndZip(short* address, (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) value) { throw null; } diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 8622d105f4f8b..eb1c1c687be5b 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -3825,7 +3825,7 @@ static SimdIntrinsic advsimd_methods [] = { {SN_StorePairNonTemporal, OP_ARM64_STNP}, {SN_StorePairScalar, OP_ARM64_STP_SCALAR}, {SN_StorePairScalarNonTemporal, OP_ARM64_STNP_SCALAR}, - {SN_StoreSelectedScalar, OP_ARM64_ST1_SCALAR}, + {SN_StoreSelectedScalar}, {SN_Subtract, OP_XBINOP, OP_ISUB, None, None, OP_XBINOP, OP_FSUB}, {SN_SubtractHighNarrowingLower, OP_ARM64_SUBHN}, {SN_SubtractHighNarrowingUpper, OP_ARM64_SUBHN2}, @@ -4060,6 +4060,11 @@ emit_arm64_intrinsics ( ret->inst_c1 = etype->type; return ret; } + case SN_StoreSelectedScalar: { + if (!is_intrinsics_vector_type (fsig->params [1])) + return NULL; + return emit_simd_ins_for_sig (cfg, klass, OP_ARM64_ST1_SCALAR, 0, arg0_type, fsig, args); + } case SN_MultiplyRoundedDoublingBySelectedScalarSaturateHigh: case SN_MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh: case SN_MultiplyDoublingScalarBySelectedScalarSaturateHigh: diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index b3faa0075c51d..c59da0d84da8d 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -1685,23 +1685,44 @@ ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Byte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "15", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.DoubleToInt64Bits(firstOp[ElementIndex]) != BitConverter.DoubleToInt64Bits(result)"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_SByte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "15", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "3", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Byte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "15", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.DoubleToInt64Bits(firstOp[ElementIndex]) != BitConverter.DoubleToInt64Bits(result)"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_SByte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "15", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "3", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVector64x2SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVector64x2", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVector64x2Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVector64x2", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVector64x2UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVector64x2", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), @@ -2521,6 +2542,36 @@ ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVector128x2SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVector128x2", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVector128x2Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVector128x2", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVector128x2UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVector128x2", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarTest.template index 918616f32b51d..9a5e3346fcf9b 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarTest.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarTest.template @@ -76,10 +76,10 @@ namespace JIT.HardwareIntrinsics.Arm private ulong alignment; - public DataTable({Op1BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) + public DataTable({Op2BaseType}[] inArray1, {Op1BaseType}[] outArray, int alignment) { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{Op1BaseType}>(); if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) { throw new ArgumentException("Invalid value of alignment"); @@ -93,7 +93,7 @@ namespace JIT.HardwareIntrinsics.Arm this.alignment = (ulong)alignment; - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); } public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); @@ -113,21 +113,21 @@ namespace JIT.HardwareIntrinsics.Arm private struct TestStruct { - public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld1; public static TestStruct Create() { var testStruct = new TestStruct(); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op2BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); return testStruct; } public void RunStructFldScenario(StoreSelectedScalarTest__{TestName} testClass) { - {Isa}.{Method}(({RetBaseType}*)testClass._dataTable.outArrayPtr, _fld1, {ElementIndex}); + {Isa}.{Method}(({Op1BaseType}*)testClass._dataTable.outArrayPtr, _fld1, {ElementIndex}); testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); } @@ -135,13 +135,13 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int LargestVectorSize = {LargestVectorSize}; - private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); private static readonly int RetElementCount = 1; private static readonly byte ElementIndex = {ElementIndex}; - private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data1 = new {Op2BaseType}[Op1ElementCount]; - private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld1; private DataTable _dataTable; @@ -150,10 +150,10 @@ namespace JIT.HardwareIntrinsics.Arm Succeeded = true; for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op2BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); + _dataTable = new DataTable(_data1, new {Op1BaseType}[RetElementCount], LargestVectorSize); } public bool IsSupported => {Isa}.IsSupported; @@ -164,7 +164,7 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - {Isa}.{Method}(({RetBaseType}*)_dataTable.outArrayPtr, Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), {ElementIndex}); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr), {ElementIndex}); ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); } @@ -173,7 +173,7 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - {Isa}.{Method}(({RetBaseType}*)_dataTable.outArrayPtr, {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), {ElementIndex}); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray1Ptr)), {ElementIndex}); ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); } @@ -182,10 +182,10 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({RetBaseType}*), typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) }) + typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}*), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) }) .Invoke(null, new object[] { - Pointer.Box(_dataTable.outArrayPtr, typeof({RetBaseType}*)), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Pointer.Box(_dataTable.outArrayPtr, typeof({Op1BaseType}*)), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr), ElementIndex }); ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); @@ -195,8 +195,8 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); - var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); - {Isa}.{Method}(({RetBaseType}*)_dataTable.outArrayPtr, op1, {ElementIndex}); + var op1 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, op1, {ElementIndex}); ValidateResult(op1, _dataTable.outArrayPtr); } @@ -205,7 +205,7 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - {Isa}.{Method}(({RetBaseType}*)_dataTable.outArrayPtr, _fld1, {ElementIndex}); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, _fld1, {ElementIndex}); ValidateResult(_fld1, _dataTable.outArrayPtr); } @@ -215,7 +215,7 @@ namespace JIT.HardwareIntrinsics.Arm TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - {Isa}.{Method}(({RetBaseType}*)_dataTable.outArrayPtr, test._fld1, {ElementIndex}); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, test._fld1, {ElementIndex}); ValidateResult(test._fld1, _dataTable.outArrayPtr); } @@ -249,29 +249,29 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") + private void ValidateResult({Op2VectorType}<{Op2BaseType}> op1, void* result, [CallerMemberName] string method = "") { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + {Op2BaseType}[] inArray1 = new {Op2BaseType}[Op1ElementCount]; + {Op1BaseType}[] outArray = new {Op1BaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf<{RetBaseType}>() * RetElementCount)); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result),(uint)(Unsafe.SizeOf<{Op1BaseType}>() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + {Op2BaseType}[] inArray1 = new {Op2BaseType}[Op1ElementCount]; + {Op1BaseType}[] outArray = new {Op1BaseType}[RetElementCount]; - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf<{RetBaseType}>() * RetElementCount)); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(Unsafe.SizeOf<{Op1BaseType}>() * RetElementCount)); ValidateResult(inArray1, outArray[0], method); } - private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType} result, [CallerMemberName] string method = "") + private void ValidateResult({Op2BaseType}[] firstOp, {Op1BaseType} result, [CallerMemberName] string method = "") { bool succeeded = true; @@ -282,7 +282,7 @@ namespace JIT.HardwareIntrinsics.Arm if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}*, {Op1VectorType}<{Op1BaseType}>, {ElementIndex}): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{Op1BaseType}>({Op2BaseType}*, {Op2VectorType}<{Op2BaseType}>, {ElementIndex}): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx2Test.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx2Test.template new file mode 100644 index 0000000000000..4aa717e4edcea --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx2Test.template @@ -0,0 +1,313 @@ +// 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 src\tests\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.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 StoreSelectedScalarx2Test__{Op1BaseType}(); + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.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 StoreSelectedScalarx2Test__{Op1BaseType} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op2BaseType}[] inArray1, {Op2BaseType}[] inArray2, {Op1BaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{Op1BaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = 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.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op2VectorType}<{Op2BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + public byte elemIndex; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op2BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + testStruct.elemIndex = (byte) (TestLibrary.Generator.GetByte() % OpElementCount); + + return testStruct; + } + + public void RunStructFldScenario(StoreSelectedScalarx2Test__{Op1BaseType} testClass) + { + {Isa}.{Method}(({Op1BaseType}*)testClass._dataTable.outArrayPtr, (_fld1, _fld2), elemIndex); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr, elemIndex); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int OpElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int DestElementCount = 2; + + private static {Op2BaseType}[] _data1 = new {Op2BaseType}[OpElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[OpElementCount]; + + private {Op2VectorType}<{Op2BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + + public byte elemIndex; + + private DataTable _dataTable; + + public StoreSelectedScalarx2Test__{Op1BaseType}() + { + Succeeded = true; + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op2BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; } + _dataTable = new DataTable(_data1, _data2, new {Op1BaseType}[DestElementCount], LargestVectorSize); + elemIndex = (byte) (TestLibrary.Generator.GetByte() % OpElementCount); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)), elemIndex); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, ({LoadIsa}.Load{Op2VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), {LoadIsa}.Load{Op2VectorType}(({Op1BaseType}*)(_dataTable.inArray2Ptr))), elemIndex); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}*), typeof(({Op2VectorType}<{Op2BaseType}>, {Op2VectorType}<{Op2BaseType}>)), typeof(byte)}). + Invoke(null, new object[] { + Pointer.Box(_dataTable.outArrayPtr, typeof({Op1BaseType}*)), + (Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)), elemIndex}); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (op1, op2), elemIndex); + + ValidateResult(op1, op2, _dataTable.outArrayPtr, elemIndex); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (_fld1, _fld2), elemIndex); + + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr, elemIndex); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (test._fld1, test._fld2), test.elemIndex); + + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr, test.elemIndex); + } + + 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(void* op1, void* op2, void* result, byte index, [CallerMemberName] string method = "") + { + {Op2BaseType}[] inArray1 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[OpElementCount]; + {Op1BaseType}[] outArray = new {Op1BaseType}[DestElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)sizeof({Op1BaseType}) * 2); + + ValidateResult(inArray1, inArray2, outArray, index, method); + } + + private void ValidateResult({Op2BaseType}[] input1, {Op2BaseType}[] input2, {Op1BaseType}[] result, byte index, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (input1[index] != result[0] || input2[index] != result[1]) + { + succeeded = false; + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{Op2BaseType}>({Op2VectorType}<{Op2BaseType}>): {Method} failed:"); + TestLibrary.TestFramework.LogInformation($" input1: ({string.Join(", ", input1)})"); + TestLibrary.TestFramework.LogInformation($" input2: ({string.Join(", ", input2)})"); + TestLibrary.TestFramework.LogInformation($" index: ({string.Join(", ", index)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateResult({Op2VectorType}<{Op2BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, void* result, byte index, [CallerMemberName] string method = "") + { + {Op2BaseType}[] inArray1 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[OpElementCount]; + {Op1BaseType}[] outArray = new {Op1BaseType}[DestElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)sizeof({Op1BaseType}) * 2); + + ValidateResult(inArray1, inArray2, outArray, index, method); + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx3Test.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx3Test.template new file mode 100644 index 0000000000000..25be2aa49af51 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx3Test.template @@ -0,0 +1,332 @@ +// 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 src\tests\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.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 {Method}x3Test__{Op1BaseType}(); + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.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 {Method}x3Test__{Op1BaseType} + { + 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({Op2BaseType}[] inArray1, {Op2BaseType}[] inArray2, {Op2BaseType}[] inArray3, {Op1BaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{Op1BaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + 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; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); + } + + 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 {Op2VectorType}<{Op2BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + public {Op2VectorType}<{Op2BaseType}> _fld3; + public byte elemIndex; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; _data3[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op2BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op2BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + testStruct.elemIndex = (byte) (TestLibrary.Generator.GetByte() % OpElementCount); + + return testStruct; + } + + public void RunStructFldScenario({Method}x3Test__{Op1BaseType} testClass) + { + {Isa}.{Method}(({Op1BaseType}*)testClass._dataTable.outArrayPtr, (_fld1, _fld2, _fld3), elemIndex); + testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr, elemIndex); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int OpElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int DestElementCount = 3; + + private static {Op2BaseType}[] _data1 = new {Op2BaseType}[OpElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[OpElementCount]; + private static {Op2BaseType}[] _data3 = new {Op2BaseType}[OpElementCount]; + + private {Op2VectorType}<{Op2BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + private {Op2VectorType}<{Op2BaseType}> _fld3; + + public byte elemIndex; + + private DataTable _dataTable; + + public {Method}x3Test__{Op1BaseType}() + { + Succeeded = true; + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; _data3[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op2BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op2BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; _data3[i] = {NextValueOp2}; } + _dataTable = new DataTable(_data1, _data2, _data3, new {Op1BaseType}[DestElementCount], LargestVectorSize); + elemIndex = (byte) (TestLibrary.Generator.GetByte() % OpElementCount); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray3Ptr)), elemIndex); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, ({LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray1Ptr)), {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray3Ptr))), elemIndex); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}*), typeof(({Op2VectorType}<{Op2BaseType}>, {Op2VectorType}<{Op2BaseType}>, {Op2VectorType}<{Op2BaseType}>)), typeof(byte)}). + Invoke(null, new object[] { + Pointer.Box(_dataTable.outArrayPtr, typeof({Op1BaseType}*)), + (Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray3Ptr)), elemIndex}); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var op3 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray3Ptr); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (op1, op2, op3), elemIndex); + + ValidateResult(op1, op2, op3, _dataTable.outArrayPtr, elemIndex); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (_fld1, _fld2, _fld3), elemIndex); + + ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr, elemIndex); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (test._fld1, test._fld2, test._fld3), test.elemIndex); + + ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr, test.elemIndex); + } + + 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(void* op1, void* op2, void* op3, void* result, byte index, [CallerMemberName] string method = "") + { + {Op2BaseType}[] inArray1 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray3 = new {Op2BaseType}[OpElementCount]; + {Op1BaseType}[] outArray = new {Op1BaseType}[DestElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)sizeof({Op1BaseType}) * 3); + + ValidateResult(inArray1, inArray2, inArray3, outArray, index, method); + } + + private void ValidateResult({Op2BaseType}[] input1, {Op2BaseType}[] input2, {Op2BaseType}[] input3, {Op1BaseType}[] result, byte index, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if ({ValidateResult}) + { + succeeded = false; + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{Op2BaseType}>({Op2VectorType}<{Op2BaseType}>): {Method} failed:"); + TestLibrary.TestFramework.LogInformation($" input1: ({string.Join(", ", input1)})"); + TestLibrary.TestFramework.LogInformation($" input2: ({string.Join(", ", input2)})"); + TestLibrary.TestFramework.LogInformation($" input3: ({string.Join(", ", input3)})"); + TestLibrary.TestFramework.LogInformation($" index: ({string.Join(", ", index)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateResult({Op2VectorType}<{Op2BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op2VectorType}<{Op2BaseType}> op3, void* result, byte index, [CallerMemberName] string method = "") + { + {Op2BaseType}[] inArray1 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray3 = new {Op2BaseType}[OpElementCount]; + {Op1BaseType}[] outArray = new {Op1BaseType}[DestElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray3[0]), op3); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)sizeof({Op1BaseType}) * 3); + + ValidateResult(inArray1, inArray2, inArray3, outArray, index, method); + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx4Test.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx4Test.template new file mode 100644 index 0000000000000..0580f1a8ec4a7 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/StoreSelectedScalarx4Test.template @@ -0,0 +1,351 @@ +// 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 src\tests\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.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 {Method}x4Test__{Op1BaseType}(); + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.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 {Method}x4Test__{Op1BaseType} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] inArray3; + private byte[] inArray4; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle inHandle3; + private GCHandle inHandle4; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op2BaseType}[] inArray1, {Op2BaseType}[] inArray2, {Op2BaseType}[] inArray3, {Op2BaseType}[] inArray4, {Op1BaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray4 = inArray4.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{Op1BaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.inArray3 = new byte[alignment * 2]; + this.inArray4 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 4]; + + 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.inHandle4 = GCHandle.Alloc(this.inArray4, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray4Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray4[0]), (uint)sizeOfinArray4); + } + + 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* inArray4Ptr => Align((byte*)(inHandle4.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + inHandle3.Free(); + inHandle4.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op2VectorType}<{Op2BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + public {Op2VectorType}<{Op2BaseType}> _fld3; + public {Op2VectorType}<{Op2BaseType}> _fld4; + public byte elemIndex; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; _data3[i] = {NextValueOp2}; _data4[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op2BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op2BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld4), ref Unsafe.As<{Op2BaseType}, byte>(ref _data4[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + testStruct.elemIndex = (byte) (TestLibrary.Generator.GetByte() % OpElementCount); + + return testStruct; + } + + public void RunStructFldScenario({Method}x4Test__{Op1BaseType} testClass) + { + {Isa}.{Method}(({Op1BaseType}*)testClass._dataTable.outArrayPtr, (_fld1, _fld2, _fld3, _fld4), elemIndex); + testClass.ValidateResult(_fld1, _fld2, _fld3, _fld4, testClass._dataTable.outArrayPtr, elemIndex); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int OpElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int DestElementCount = 4; + + private static {Op2BaseType}[] _data1 = new {Op2BaseType}[OpElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[OpElementCount]; + private static {Op2BaseType}[] _data3 = new {Op2BaseType}[OpElementCount]; + private static {Op2BaseType}[] _data4 = new {Op2BaseType}[OpElementCount]; + + private {Op2VectorType}<{Op2BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + private {Op2VectorType}<{Op2BaseType}> _fld3; + private {Op2VectorType}<{Op2BaseType}> _fld4; + + public byte elemIndex; + + private DataTable _dataTable; + + public {Method}x4Test__{Op1BaseType}() + { + Succeeded = true; + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; _data3[i] = {NextValueOp2}; _data4[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op2BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op2BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld4), ref Unsafe.As<{Op2BaseType}, byte>(ref _data4[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < OpElementCount; i++) { _data1[i] = {NextValueOp2}; _data2[i] = {NextValueOp2}; _data3[i] = {NextValueOp2}; _data4[i] = {NextValueOp2}; } + _dataTable = new DataTable(_data1, _data2, _data3, _data4, new {Op1BaseType}[DestElementCount], LargestVectorSize); + elemIndex = (byte) (TestLibrary.Generator.GetByte() % OpElementCount); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray3Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray4Ptr)), elemIndex); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.inArray4Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, ({LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray1Ptr)), {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray3Ptr)), {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray4Ptr))), elemIndex); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.inArray4Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}*), typeof(({Op2VectorType}<{Op2BaseType}>, {Op2VectorType}<{Op2BaseType}>, {Op2VectorType}<{Op2BaseType}>, {Op2VectorType}<{Op2BaseType}>)), typeof(byte)}). + Invoke(null, new object[] { + Pointer.Box(_dataTable.outArrayPtr, typeof({Op1BaseType}*)), + (Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray3Ptr), Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray4Ptr)), elemIndex}); + + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.inArray4Ptr, _dataTable.outArrayPtr, elemIndex); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var op3 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray3Ptr); + var op4 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray4Ptr); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (op1, op2, op3, op4), elemIndex); + + ValidateResult(op1, op2, op3, op4, _dataTable.outArrayPtr, elemIndex); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (_fld1, _fld2, _fld3, _fld4), elemIndex); + + ValidateResult(_fld1, _fld2, _fld3, _fld4, _dataTable.outArrayPtr, elemIndex); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, (test._fld1, test._fld2, test._fld3, test._fld4), test.elemIndex); + + ValidateResult(test._fld1, test._fld2, test._fld3, test._fld4, _dataTable.outArrayPtr, test.elemIndex); + } + + 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(void* op1, void* op2, void* op3, void* op4, void* result, byte index, [CallerMemberName] string method = "") + { + {Op2BaseType}[] inArray1 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray3 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray4 = new {Op2BaseType}[OpElementCount]; + {Op1BaseType}[] outArray = new {Op1BaseType}[DestElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray4[0]), ref Unsafe.AsRef(op4), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)sizeof({Op1BaseType}) * 4); + + ValidateResult(inArray1, inArray2, inArray3, inArray4, outArray, index, method); + } + + private void ValidateResult({Op2BaseType}[] input1, {Op2BaseType}[] input2, {Op2BaseType}[] input3, {Op2BaseType}[] input4, {Op1BaseType}[] result, byte index, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]) + { + succeeded = false; + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{Op2BaseType}>({Op2VectorType}<{Op2BaseType}>): StoreSelectedScalar128x4 failed:"); + TestLibrary.TestFramework.LogInformation($" input1: ({string.Join(", ", input1)})"); + TestLibrary.TestFramework.LogInformation($" input2: ({string.Join(", ", input2)})"); + TestLibrary.TestFramework.LogInformation($" input3: ({string.Join(", ", input3)})"); + TestLibrary.TestFramework.LogInformation($" input4: ({string.Join(", ", input4)})"); + TestLibrary.TestFramework.LogInformation($" index: ({string.Join(", ", index)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateResult({Op2VectorType}<{Op2BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op2VectorType}<{Op2BaseType}> op3, {Op2VectorType}<{Op2BaseType}> op4, void* result, byte index, [CallerMemberName] string method = "") + { + {Op2BaseType}[] inArray1 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray3 = new {Op2BaseType}[OpElementCount]; + {Op2BaseType}[] inArray4 = new {Op2BaseType}[OpElementCount]; + {Op1BaseType}[] outArray = new {Op1BaseType}[DestElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray3[0]), op3); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray4[0]), op4); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)sizeof({Op1BaseType}) * 4); + + ValidateResult(inArray1, inArray2, inArray3, inArray4, outArray, index, method); + } + } +} \ No newline at end of file