diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 755a1e91d7f839..e5e82024f440de 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -2814,6 +2814,7 @@ class Compiler #ifdef TARGET_ARM64 GenTreeFieldList* gtConvertTableOpToFieldList(GenTree* op, unsigned fieldCount); + GenTreeFieldList* gtConvertParamOpToFieldList(GenTree* op, unsigned fieldCount, CORINFO_CLASS_HANDLE clsHnd); #endif #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index e83f155ca874e9..27e3b0f89a12ba 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -25046,6 +25046,43 @@ GenTreeFieldList* Compiler::gtConvertTableOpToFieldList(GenTree* op, unsigned fi } return fieldList; } + +//------------------------------------------------------------------------ +// gtConvertParamOpToFieldList: Convert a operand that represents tuple of struct into +// field list, where each field represents a struct in the tuple. +// +// Arguments: +// op -- Operand to convert. +// fieldCount -- Number of fields or rows present. +// clsHnd -- Class handle of the tuple. +// +// Return Value: +// The GenTreeFieldList node. +// +GenTreeFieldList* Compiler::gtConvertParamOpToFieldList(GenTree* op, unsigned fieldCount, CORINFO_CLASS_HANDLE clsHnd) +{ + LclVarDsc* opVarDsc = lvaGetDesc(op->AsLclVar()); + unsigned lclNum = lvaGetLclNum(opVarDsc); + unsigned fieldSize = opVarDsc->lvSize() / fieldCount; + GenTreeFieldList* fieldList = new (this, GT_FIELD_LIST) GenTreeFieldList(); + int offset = 0; + unsigned sizeBytes = 0; + CORINFO_CLASS_HANDLE structType; + + for (unsigned fieldId = 0; fieldId < fieldCount; fieldId++) + { + CORINFO_FIELD_HANDLE fieldHandle = info.compCompHnd->getFieldInClass(clsHnd, fieldId); + JitType2PreciseVarType(info.compCompHnd->getFieldType(fieldHandle, &structType)); + getBaseJitTypeAndSizeOfSIMDType(structType, &sizeBytes); + var_types simdType = getSIMDTypeForSize(sizeBytes); + + GenTreeLclFld* fldNode = gtNewLclFldNode(lclNum, simdType, offset); + fieldList->AddField(this, fldNode, offset, simdType); + + offset += fieldSize; + } + return fieldList; +} #endif // TARGET_ARM64 GenTree* Compiler::gtNewSimdWithLowerNode( @@ -25195,6 +25232,13 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const #ifdef TARGET_ARM64 case NI_AdvSimd_LoadAndInsertScalar: + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: + addr = Op(3); break; #endif // TARGET_ARM64 @@ -25555,6 +25599,7 @@ ClassLayout* GenTreeHWIntrinsic::GetLayout(Compiler* compiler) const case NI_AdvSimd_Arm64_LoadPairVector64: case NI_AdvSimd_Arm64_LoadPairVector64NonTemporal: case NI_AdvSimd_LoadVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x2: case NI_AdvSimd_LoadAndReplicateToVector64x2: return compiler->typGetBlkLayout(16); @@ -25564,17 +25609,22 @@ ClassLayout* GenTreeHWIntrinsic::GetLayout(Compiler* compiler) const case NI_AdvSimd_LoadVector64x4: case NI_AdvSimd_LoadAndReplicateToVector64x4: case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: return compiler->typGetBlkLayout(32); case NI_AdvSimd_LoadVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: case NI_AdvSimd_LoadAndReplicateToVector64x3: return compiler->typGetBlkLayout(24); case NI_AdvSimd_Arm64_LoadVector128x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x3: return compiler->typGetBlkLayout(48); case NI_AdvSimd_Arm64_LoadVector128x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x4: return compiler->typGetBlkLayout(64); diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index a0496737343a52..287b214d0f40b8 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1071,9 +1071,53 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, if (HWIntrinsicInfo::IsMultiReg(intrinsic)) { - // We don't have generic multireg APIs assert(sizeBytes == 0); } + +#ifdef TARGET_ARM64 + else if ((intrinsic == NI_AdvSimd_LoadAndInsertScalar) || (intrinsic == NI_AdvSimd_Arm64_LoadAndInsertScalar)) + { + CorInfoType pSimdBaseJitType = CORINFO_TYPE_UNDEF; + var_types retFieldType = impNormStructType(sig->retTypeSigClass, &pSimdBaseJitType); + + if (retFieldType == TYP_STRUCT) + { + CORINFO_CLASS_HANDLE structType; + unsigned int sizeBytes = 0; + + // LoadAndInsertScalar that returns 2,3 or 4 vectors + assert(pSimdBaseJitType == CORINFO_TYPE_UNDEF); + unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(sig->retTypeSigClass); + assert(fieldCount > 1); + CORINFO_FIELD_HANDLE fieldHandle = info.compCompHnd->getFieldInClass(sig->retTypeClass, 0); + CorInfoType fieldType = info.compCompHnd->getFieldType(fieldHandle, &structType); + simdBaseJitType = getBaseJitTypeAndSizeOfSIMDType(structType, &sizeBytes); + switch (fieldCount) + { + case 2: + intrinsic = sizeBytes == 8 ? NI_AdvSimd_LoadAndInsertScalarVector64x2 + : NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2; + break; + case 3: + intrinsic = sizeBytes == 8 ? NI_AdvSimd_LoadAndInsertScalarVector64x3 + : NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3; + break; + case 4: + intrinsic = sizeBytes == 8 ? NI_AdvSimd_LoadAndInsertScalarVector64x4 + : NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4; + break; + default: + assert("unsupported"); + } + } + else + { + assert((retFieldType == TYP_SIMD8) || (retFieldType == TYP_SIMD16)); + assert(isSupportedBaseType(intrinsic, simdBaseJitType)); + retType = getSIMDTypeForSize(sizeBytes); + } + } +#endif else { // We want to return early here for cases where retType was TYP_STRUCT as per method signature and @@ -1130,7 +1174,9 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, #ifdef TARGET_ARM64 if ((intrinsic == NI_AdvSimd_Insert) || (intrinsic == NI_AdvSimd_InsertScalar) || - (intrinsic == NI_AdvSimd_LoadAndInsertScalar)) + ((intrinsic >= NI_AdvSimd_LoadAndInsertScalar) && (intrinsic <= NI_AdvSimd_LoadAndInsertScalarVector64x4)) || + ((intrinsic >= NI_AdvSimd_Arm64_LoadAndInsertScalar) && + (intrinsic <= NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4))) { assert(sig->numArgs == 3); immOp = impStackTop(1).val; diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h index 0cc8e5f8b51e52..4695af2a770963 100644 --- a/src/coreclr/jit/hwintrinsic.h +++ b/src/coreclr/jit/hwintrinsic.h @@ -770,18 +770,24 @@ struct HWIntrinsicInfo case NI_AdvSimd_Arm64_LoadPairVector128NonTemporal: case NI_AdvSimd_LoadVector64x2: case NI_AdvSimd_Arm64_LoadVector128x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: case NI_AdvSimd_LoadAndReplicateToVector64x2: case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x2: return 2; case NI_AdvSimd_LoadVector64x3: case NI_AdvSimd_Arm64_LoadVector128x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: case NI_AdvSimd_LoadAndReplicateToVector64x3: case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x3: return 3; case NI_AdvSimd_LoadVector64x4: case NI_AdvSimd_Arm64_LoadVector128x4: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: case NI_AdvSimd_LoadAndReplicateToVector64x4: case NI_AdvSimd_Arm64_LoadAndReplicateToVector128x4: return 4; diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 2365638e4f4ced..01f64f47ce3cc5 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -253,6 +253,12 @@ void HWIntrinsicInfo::lookupImmBounds( case NI_AdvSimd_Insert: case NI_AdvSimd_InsertScalar: case NI_AdvSimd_LoadAndInsertScalar: + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: case NI_AdvSimd_StoreSelectedScalar: case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: case NI_AdvSimd_Arm64_InsertSelectedScalar: @@ -1916,6 +1922,57 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, retNode = impStoreMultiRegValueToVar(op1, sig->retTypeSigClass DEBUGARG(CorInfoCallConvExtension::Managed)); break; } + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: + { + assert(sig->numArgs == 3); + + 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 = getArgForHWIntrinsic(argType, argClass); + argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); + op2 = getArgForHWIntrinsic(argType, argClass); + argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass))); + op1 = impPopStack().val; + + if (op3->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 (op3->gtGetOp1()->TypeGet() == TYP_BYREF) + { + op3 = op3->gtGetOp1(); + } + } + + assert(HWIntrinsicInfo::IsMultiReg(intrinsic)); + assert(op1->TypeGet() == TYP_STRUCT); + + info.compNeedsConsecutiveRegisters = true; + unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(argClass); + + if (!op1->OperIs(GT_LCL_VAR)) + { + unsigned tmp = lvaGrabTemp(true DEBUGARG("LoadAndInsertScalar temp tree")); + + impStoreTemp(tmp, op1, CHECK_SPILL_NONE); + op1 = gtNewLclvNode(tmp, argType); + } + + op1 = gtConvertParamOpToFieldList(op1, fieldCount, argClass); + op1 = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize); + retNode = impStoreMultiRegValueToVar(op1, sig->retTypeSigClass DEBUGARG(CorInfoCallConvExtension::Managed)); + break; + } case NI_AdvSimd_VectorTableLookup: case NI_AdvSimd_Arm64_VectorTableLookup: { diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 4a013ca084cd5a..bcdf6ba8bb1b96 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -728,6 +728,52 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } break; + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: + { + assert(isRMW); + unsigned fieldIdx = 0; + op2Reg = intrin.op2->GetRegNum(); + op3Reg = intrin.op3->GetRegNum(); + assert(intrin.op1->OperIsFieldList()); + + GenTreeFieldList* fieldList = intrin.op1->AsFieldList(); + GenTree* firstField = fieldList->Uses().GetHead()->GetNode(); + op1Reg = firstField->GetRegNum(); + + regNumber targetFieldReg = REG_NA; + regNumber op1FieldReg = REG_NA; + + for (GenTreeFieldList::Use& use : fieldList->Uses()) + { + GenTree* fieldNode = use.GetNode(); + + targetFieldReg = node->GetRegByIndex(fieldIdx); + op1FieldReg = fieldNode->GetRegNum(); + + if (targetFieldReg != op1FieldReg) + { + GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(fieldNode), targetFieldReg, op1FieldReg, + /* canSkip */ true); + } + fieldIdx++; + } + + HWIntrinsicImmOpHelper helper(this, intrin.op2, node); + + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + const int elementIndex = helper.ImmValue(); + + GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op3Reg, elementIndex); + } + + break; + } case NI_AdvSimd_Arm64_LoadPairVector128: case NI_AdvSimd_Arm64_LoadPairVector128NonTemporal: case NI_AdvSimd_Arm64_LoadPairVector64: diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h index be6e4bb2d313df..c704f4e080c510 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/jit/hwintrinsiclistarm64.h @@ -316,6 +316,9 @@ HARDWARE_INTRINSIC(AdvSimd, InsertScalar, HARDWARE_INTRINSIC(AdvSimd, LeadingSignCount, -1, 1, true, {INS_cls, INS_invalid, INS_cls, INS_invalid, INS_cls, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, LeadingZeroCount, -1, 1, true, {INS_clz, INS_clz, INS_clz, INS_clz, INS_clz, INS_clz, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, LoadAndInsertScalar, -1, 3, true, {INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1}, HW_Category_MemoryLoad, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, LoadAndInsertScalarVector64x2, 8, 3, true, {INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_invalid, INS_invalid, INS_ld2, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_HasImmediateOperand|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) +HARDWARE_INTRINSIC(AdvSimd, LoadAndInsertScalarVector64x3, 8, 3, true, {INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_invalid, INS_invalid, INS_ld3, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_HasImmediateOperand|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) +HARDWARE_INTRINSIC(AdvSimd, LoadAndInsertScalarVector64x4, 8, 3, true, {INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_invalid, INS_invalid, INS_ld4, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_HasImmediateOperand|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd, LoadAndReplicateToVector64, 8, 1, true, {INS_ld1r, INS_ld1r, INS_ld1r, INS_ld1r, INS_ld1r, INS_ld1r, INS_invalid, INS_invalid, INS_ld1r, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, LoadAndReplicateToVector128, 16, 1, true, {INS_ld1r, INS_ld1r, INS_ld1r, INS_ld1r, INS_ld1r, INS_ld1r, INS_invalid, INS_invalid, INS_ld1r, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, LoadAndReplicateToVector64x2, 8, 1, true, {INS_ld2r, INS_ld2r, INS_ld2r, INS_ld2r, INS_ld2r, INS_ld2r, INS_invalid, INS_invalid, INS_ld2r, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) @@ -582,6 +585,10 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadPairVector64, HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadPairVector64NonTemporal, 8, 1, true, {INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp}, HW_Category_MemoryLoad, HW_Flag_BaseTypeFromFirstArg|HW_Flag_MultiReg|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadPairVector128, 16, 1, true, {INS_ldp, INS_ldp, INS_ldp, INS_ldp, INS_ldp, INS_ldp, INS_ldp, INS_ldp, INS_ldp, INS_ldp}, HW_Category_MemoryLoad, HW_Flag_BaseTypeFromFirstArg|HW_Flag_MultiReg|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadPairVector128NonTemporal, 16, 1, true, {INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp, INS_ldnp}, HW_Category_MemoryLoad, HW_Flag_BaseTypeFromFirstArg|HW_Flag_MultiReg|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadAndInsertScalar, -1, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadAndInsertScalarVector128x2, 16, 3, true, {INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2}, HW_Category_MemoryLoad, HW_Flag_HasImmediateOperand|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) +HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadAndInsertScalarVector128x3, 16, 3, true, {INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3}, HW_Category_MemoryLoad, HW_Flag_HasImmediateOperand|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) +HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadAndInsertScalarVector128x4, 16, 3, true, {INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4}, HW_Category_MemoryLoad, HW_Flag_HasImmediateOperand|HW_Flag_SpecialImport|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadVector128x2, 16, 1, true, {INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2, INS_ld2}, HW_Category_MemoryLoad, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadVector128x3, 16, 1, true, {INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3, INS_ld3}, HW_Category_MemoryLoad, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) HARDWARE_INTRINSIC(AdvSimd_Arm64, LoadVector128x4, 16, 1, true, {INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4, INS_ld4}, HW_Category_MemoryLoad, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_MultiReg|HW_Flag_NeedsConsecutiveRegisters) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index ceefc04ed068ae..7cc32c018d3986 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -3013,6 +3013,12 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_Extract: case NI_AdvSimd_InsertScalar: case NI_AdvSimd_LoadAndInsertScalar: + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op2)); diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index debecf4e912446..01e20719d83e27 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1409,6 +1409,12 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou case NI_AdvSimd_Insert: case NI_AdvSimd_InsertScalar: case NI_AdvSimd_LoadAndInsertScalar: + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: needBranchTargetReg = !intrin.op2->isContainedIntOrIImmed(); break; @@ -1440,8 +1446,8 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou // is not allocated the same register as the target. const bool isRMW = intrinsicTree->isRMWHWIntrinsic(compiler); - bool tgtPrefOp1 = false; - + bool tgtPrefOp1 = false; + bool delayFreeMultiple = false; if (intrin.op1 != nullptr) { bool simdRegToSimdRegMove = false; @@ -1475,6 +1481,16 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou simdRegToSimdRegMove = true; break; } + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x2: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x3: + case NI_AdvSimd_Arm64_LoadAndInsertScalarVector128x4: + { + delayFreeMultiple = true; + break; + } default: { @@ -1489,7 +1505,20 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou tgtPrefOp1 = !intrin.op1->isContained(); } - if (intrinsicTree->OperIsMemoryLoadOrStore()) + if (delayFreeMultiple) + { + assert(isRMW); + assert(intrin.op1->OperIs(GT_FIELD_LIST)); + GenTreeFieldList* op1 = intrin.op1->AsFieldList(); + assert(compiler->info.compNeedsConsecutiveRegisters); + + for (GenTreeFieldList::Use& use : op1->Uses()) + { + BuildDelayFreeUses(use.GetNode(), intrinsicTree); + srcCount++; + } + } + else if (intrinsicTree->OperIsMemoryLoadOrStore()) { srcCount += BuildAddrUses(intrin.op1); } @@ -1586,6 +1615,20 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou buildInternalRegisterUses(); *pDstCount = 0; break; + case NI_AdvSimd_LoadAndInsertScalarVector64x2: + case NI_AdvSimd_LoadAndInsertScalarVector64x3: + case NI_AdvSimd_LoadAndInsertScalarVector64x4: + 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); + srcCount += BuildOperandUses(intrin.op2); + + assert(intrinsicTree->OperIsMemoryLoadOrStore()); + srcCount += BuildAddrUses(intrin.op3); + FALLTHROUGH; case NI_AdvSimd_LoadVector64x2: case NI_AdvSimd_LoadVector64x3: case NI_AdvSimd_LoadVector64x4: diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index c1ba537716ddee..7d9803c645799d 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3526,6 +3526,10 @@ int LinearScan::BuildDelayFreeUses(GenTree* node, if (use != nullptr) { AddDelayFreeUses(use, rmwNode); + if (useRefPositionRef != nullptr) + { + *useRefPositionRef = use; + } return 1; } 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 3a7daf50c428fa..d386e1c299ee67 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 @@ -1550,6 +1550,156 @@ internal Arm64() { } /// public static Vector128 InsertSelectedScalar(Vector128 result, [ConstantExpected(Max = (byte)(1))] byte resultIndex, Vector128 value, [ConstantExpected(Max = (byte)(1))] byte valueIndex) { throw new PlatformNotSupportedException(); } + /// + /// A64: LD2 { Vn.16B, Vn+1.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, byte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.16B, Vn+1.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, sbyte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.8H, Vn+1.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, short* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.8H, Vn+1.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, ushort* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.4S, Vn+1.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, int* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.4S, Vn+1.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, uint* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.2D, Vn+1.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, long* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.2D, Vn+1.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, ulong* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.4S, Vn+1.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, float* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.2D, Vn+1.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, double* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.16B, Vn+1.16B, Vn+2.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, byte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.16B, Vn+1.16B, Vn+2.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, sbyte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.8H, Vn+1.8H, Vn+2.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, short* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.8H, Vn+1.8H, Vn+2.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, ushort* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.4S, Vn+1.4S, Vn+2.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, int* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.4S, Vn+1.4S, Vn+2.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, uint* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.2D, Vn+1.2D, Vn+2.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, long* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.2D, Vn+1.2D, Vn+2.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, ulong* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.4S, Vn+1.4S, Vn+2.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, float* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.2D, Vn+1.2D, Vn+2.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, double* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.16B, Vn+1.16B, Vn+2.16B, Vn+3.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, byte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.16B, Vn+1.16B, Vn+2.16B, Vn+3.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, sbyte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.8H, Vn+1.8H, Vn+2.8H, Vn+3.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, short* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.8H, Vn+1.8H, Vn+2.8H, Vn+3.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, ushort* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.4S, Vn+1.4S, Vn+2.4S, Vn+3.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, int* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.4S, Vn+1.4S, Vn+2.4S, Vn+3.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, uint* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.2D, Vn+1.2D, Vn+2.2D, Vn+3.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, long* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.2D, Vn+1.2D, Vn+2.2D, Vn+3.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, ulong* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.4S, Vn+1.4S, Vn+2.4S, Vn+3.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, float* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.2D, Vn+1.2D, Vn+2.2D, Vn+3.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, double* address) { throw new PlatformNotSupportedException(); } + /// /// float64x2_t vld1q_dup_f64 (float64_t const * ptr) /// A64: LD1R { Vt.2D }, [Xn] @@ -8439,6 +8589,111 @@ internal Arm64() { } /// public static unsafe Vector128 LoadAndInsertScalar(Vector128 value, [ConstantExpected(Max = (byte)(1))] byte index, ulong* address) { throw new PlatformNotSupportedException(); } + /// + /// A64: LD2 { Vn.8B, Vn+1.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, byte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.8B, Vn+1.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, sbyte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.4H, Vn+1.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, short* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.4H, Vn+1.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, ushort* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.2S, Vn+1.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, int* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.2S, Vn+1.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, uint* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD2 { Vn.2S, Vn+1.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, float* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.8B, Vn+1.8B, Vn+2.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, byte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.8B, Vn+1.8B, Vn+2.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, sbyte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.4H, Vn+1.4H, Vn+2.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, short* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.4H, Vn+1.4H, Vn+2.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, ushort* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.2S, Vn+1.2S, Vn+2.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, int* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.2S, Vn+1.2S, Vn+2.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, uint* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD3 { Vn.2S, Vn+1.2S, Vn+2.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, float* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.8B, Vn+1.8B, Vn+2.8B, Vn+3.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, byte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.8B, Vn+1.8B, Vn+2.8B, Vn+3.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, sbyte* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.4H, Vn+1.4H, Vn+2.4H, Vn+3.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, short* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.4H, Vn+1.4H, Vn+2.4H, Vn+3.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, ushort* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.2S, Vn+1.2S, Vn+2.2S, Vn+3.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, int* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.2S, Vn+1.2S, Vn+2.2S, Vn+3.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, uint* address) { throw new PlatformNotSupportedException(); } + + /// + /// A64: LD4 { Vn.2S, Vn+1.2S, Vn+2.2S, Vn+3.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, float* address) { throw new PlatformNotSupportedException(); } + /// /// uint8x8_t vld1_dup_u8 (uint8_t const * ptr) /// A32: VLD1.8 { Dd[] }, [Rn] 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 a18575100d4fe8..7ad85399285d1c 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 @@ -1548,6 +1548,156 @@ internal Arm64() { } /// public static Vector128 InsertSelectedScalar(Vector128 result, [ConstantExpected(Max = (byte)(1))] byte resultIndex, Vector128 value, [ConstantExpected(Max = (byte)(1))] byte valueIndex) => Insert(result, resultIndex, Extract(value, valueIndex)); + /// + /// A64: LD2 { Vn.16B, Vn+1.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, byte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.16B, Vn+1.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, sbyte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.8H, Vn+1.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, short* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.8H, Vn+1.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, ushort* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.4S, Vn+1.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, int* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.4S, Vn+1.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, uint* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.2D, Vn+1.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, long* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.2D, Vn+1.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, ulong* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.4S, Vn+1.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, float* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.2D, Vn+1.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, double* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.16B, Vn+1.16B, Vn+2.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, byte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.16B, Vn+1.16B, Vn+2.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, sbyte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.8H, Vn+1.8H, Vn+2.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, short* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.8H, Vn+1.8H, Vn+2.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, ushort* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.4S, Vn+1.4S, Vn+2.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, int* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.4S, Vn+1.4S, Vn+2.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, uint* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.2D, Vn+1.2D, Vn+2.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, long* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.2D, Vn+1.2D, Vn+2.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, ulong* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.4S, Vn+1.4S, Vn+2.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, float* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.2D, Vn+1.2D, Vn+2.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, double* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.16B, Vn+1.16B, Vn+2.16B, Vn+3.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, byte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.16B, Vn+1.16B, Vn+2.16B, Vn+3.16B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(15))] byte index, sbyte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.8H, Vn+1.8H, Vn+2.8H, Vn+3.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, short* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.8H, Vn+1.8H, Vn+2.8H, Vn+3.8H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(7))] byte index, ushort* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.4S, Vn+1.4S, Vn+2.4S, Vn+3.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, int* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.4S, Vn+1.4S, Vn+2.4S, Vn+3.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, uint* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.2D, Vn+1.2D, Vn+2.2D, Vn+3.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, long* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.2D, Vn+1.2D, Vn+2.2D, Vn+3.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, ulong* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.4S, Vn+1.4S, Vn+2.4S, Vn+3.4S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(3))] byte index, float* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.2D, Vn+1.2D, Vn+2.2D, Vn+3.2D }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [ConstantExpected(Max = (byte)(1))] byte index, double* address) => LoadAndInsertScalar(values, index, address); + /// /// float64x2_t vld1q_dup_f64 (float64_t const * ptr) /// A64: LD1R { Vt.2D }, [Xn] @@ -8436,6 +8586,111 @@ internal Arm64() { } /// public static unsafe Vector128 LoadAndInsertScalar(Vector128 value, [ConstantExpected(Max = (byte)(1))] byte index, ulong* address) => LoadAndInsertScalar(value, index, address); + /// + /// A64: LD2 { Vn.8B, Vn+1.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, byte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.8B, Vn+1.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, sbyte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.4H, Vn+1.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, short* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.4H, Vn+1.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, ushort* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.2S, Vn+1.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, int* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.2S, Vn+1.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, uint* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD2 { Vn.2S, Vn+1.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, float* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.8B, Vn+1.8B, Vn+2.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, byte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.8B, Vn+1.8B, Vn+2.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, sbyte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.4H, Vn+1.4H, Vn+2.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, short* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.4H, Vn+1.4H, Vn+2.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, ushort* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.2S, Vn+1.2S, Vn+2.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, int* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.2S, Vn+1.2S, Vn+2.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, uint* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD3 { Vn.2S, Vn+1.2S, Vn+2.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, float* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.8B, Vn+1.8B, Vn+2.8B, Vn+3.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, byte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.8B, Vn+1.8B, Vn+2.8B, Vn+3.8B }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(7))] byte index, sbyte* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.4H, Vn+1.4H, Vn+2.4H, Vn+3.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, short* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.4H, Vn+1.4H, Vn+2.4H, Vn+3.4H }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(3))] byte index, ushort* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.2S, Vn+1.2S, Vn+2.2S, Vn+3.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, int* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.2S, Vn+1.2S, Vn+2.2S, Vn+3.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, uint* address) => LoadAndInsertScalar(values, index, address); + + /// + /// A64: LD4 { Vn.2S, Vn+1.2S, Vn+2.2S, Vn+3.2S }[Vm], [Xn] + /// + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [ConstantExpected(Max = (byte)(1))] byte index, float* address) => LoadAndInsertScalar(values, index, address); + /// /// uint8x8_t vld1_dup_u8 (uint8_t const * ptr) /// A32: VLD1.8 { Dd[] }, [Rn] 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 847350a19f5997..8e9a0a50fbf275 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -1884,6 +1884,27 @@ internal AdvSimd() { } public static unsafe System.Runtime.Intrinsics.Vector64 LoadAndInsertScalar(System.Runtime.Intrinsics.Vector64 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, float* address) { throw null; } public static unsafe System.Runtime.Intrinsics.Vector64 LoadAndInsertScalar(System.Runtime.Intrinsics.Vector64 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, ushort* address) { throw null; } public static unsafe System.Runtime.Intrinsics.Vector64 LoadAndInsertScalar(System.Runtime.Intrinsics.Vector64 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, uint* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, byte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, sbyte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, short* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, ushort* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, int* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, uint* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, float* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, byte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, sbyte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, short* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, ushort* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, int* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, uint* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, float* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, byte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, sbyte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, short* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, ushort* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, int* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, uint* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector64 Value1, System.Runtime.Intrinsics.Vector64 Value2, System.Runtime.Intrinsics.Vector64 Value3, System.Runtime.Intrinsics.Vector64 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64, System.Runtime.Intrinsics.Vector64) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, float* address) { throw null; } public static unsafe System.Runtime.Intrinsics.Vector128 LoadAndReplicateToVector128(byte* address) { throw null; } public static unsafe System.Runtime.Intrinsics.Vector128 LoadAndReplicateToVector128(short* address) { throw null; } public static unsafe System.Runtime.Intrinsics.Vector128 LoadAndReplicateToVector128(int* address) { throw null; } @@ -3205,6 +3226,36 @@ internal Arm64() { } public static System.Runtime.Intrinsics.Vector64 InsertSelectedScalar(System.Runtime.Intrinsics.Vector64 result, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte resultIndex, System.Runtime.Intrinsics.Vector64 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte valueIndex) { throw null; } public static System.Runtime.Intrinsics.Vector64 InsertSelectedScalar(System.Runtime.Intrinsics.Vector64 result, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte resultIndex, System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte valueIndex) { throw null; } public static System.Runtime.Intrinsics.Vector64 InsertSelectedScalar(System.Runtime.Intrinsics.Vector64 result, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte resultIndex, System.Runtime.Intrinsics.Vector64 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte valueIndex) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index, byte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index, sbyte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, short* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, ushort* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, int* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, uint* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, long* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, ulong* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, float* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, double* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index, byte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index, sbyte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, short* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, ushort* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, int* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, uint* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, long* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, ulong* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, float* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, double* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index, byte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(15))] byte index, sbyte* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, short* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(7))] byte index, ushort* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, int* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, uint* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, long* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, ulong* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(3))] byte index, float* address) { throw null; } + public static unsafe (System.Runtime.Intrinsics.Vector128 Value1, System.Runtime.Intrinsics.Vector128 Value2, System.Runtime.Intrinsics.Vector128 Value3, System.Runtime.Intrinsics.Vector128 Value4) LoadAndInsertScalar((System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128, System.Runtime.Intrinsics.Vector128) values, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute(Max = (byte)(1))] byte index, double* address) { throw null; } public static unsafe System.Runtime.Intrinsics.Vector128 LoadAndReplicateToVector128(double* address) { throw null; } public static unsafe System.Runtime.Intrinsics.Vector128 LoadAndReplicateToVector128(long* address) { throw null; } public static unsafe System.Runtime.Intrinsics.Vector128 LoadAndReplicateToVector128(ulong* address) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 6e2f3dde300906..894fb2b159eb91 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -714,6 +714,27 @@ ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i]))"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i]))"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.SingleToInt32Bits(result4[i]))"}), ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), @@ -2039,6 +2060,36 @@ ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt32_3_Vector128_UInt32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt64_1_Vector128_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[0]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i]))"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i]))"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i]))"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.DoubleToInt64Bits(result3[i]))"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.SingleToInt32Bits(result4[i]))"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.DoubleToInt64Bits(result3[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.DoubleToInt64Bits(result4[i]))"}), ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarTest.template index f74ef42e057e92..12c87a5134c74a 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarTest.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarTest.template @@ -23,7 +23,7 @@ namespace JIT.HardwareIntrinsics.Arm [Fact] public static void {TestName}() { - var test = new LoadAndInsertTest__{TestName}(); + var test = new {TestName}Test(); if (test.IsSupported) { @@ -64,7 +64,7 @@ namespace JIT.HardwareIntrinsics.Arm } } - public sealed unsafe class LoadAndInsertTest__{TestName} + public sealed unsafe class {TestName}Test { private struct DataTable { @@ -128,7 +128,7 @@ namespace JIT.HardwareIntrinsics.Arm return testStruct; } - public void RunStructFldScenario(LoadAndInsertTest__{TestName} testClass) + public void RunStructFldScenario({TestName}Test testClass) { fixed ({Op1BaseType}* pFld3 = &_fld3) { @@ -154,7 +154,7 @@ namespace JIT.HardwareIntrinsics.Arm private DataTable _dataTable; - public LoadAndInsertTest__{TestName}() + public {TestName}Test() { Succeeded = true; diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx2Test.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx2Test.template new file mode 100644 index 00000000000000..46d0f81b614451 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx2Test.template @@ -0,0 +1,409 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.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 {TestName}Test(); + + 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 {TestName}Test + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray1; + private byte[] outArray2; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle1; + private GCHandle outHandle2; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {Op1BaseType}[] inArray2, {Op1BaseType}[] outArray1, {RetBaseType}[] outArray2, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfoutArray1 = outArray1.Length * Unsafe.SizeOf<{RetBaseType}>(); + int sizeOfoutArray2 = outArray2.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray1|| (alignment * 2) < sizeOfoutArray2) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray1 = new byte[alignment * 2]; + this.outArray2 = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle1 = GCHandle.Alloc(this.outArray1, GCHandleType.Pinned); + this.outHandle2 = GCHandle.Alloc(this.outArray2, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr1), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr2), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArrayPtr1 => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArrayPtr2 => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr1 => Align((byte*)(outHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr2 => Align((byte*)(outHandle2.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle1.Free(); + outHandle2.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op1VectorType}<{Op1BaseType}> _fld2; + public {Op1BaseType}[] _newData; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] _data2 = new {Op1BaseType}[Op1ElementCount]; + testStruct._newData = new {Op1BaseType}[Op1ElementCount*2]; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[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<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount*2; i++) { testStruct._newData[i] = {NextValueOp1}; } + + return testStruct; + } + + public void RunStructFldScenario({TestName}Test testClass) + { + fixed ({Op1BaseType}* pNewData = _newData) + { + var result = {Isa}.{Method}((_fld1, _fld2), {ElementIndex}, pNewData); + + Unsafe.Write(testClass._dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(testClass._dataTable.outArrayPtr2, result.Item2); + + testClass.ValidateResult(_fld1, _fld2, pNewData, testClass._dataTable.outArrayPtr1, testClass._dataTable.outArrayPtr2); + } + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static readonly byte ElementIndex = {ElementIndex}; + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op1BaseType}[] _data2 = new {Op1BaseType}[Op1ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op1VectorType}<{Op1BaseType}> _fld2; + private {Op1BaseType}[] _newData = new {Op1BaseType}[Op1ElementCount*2]; + + private DataTable _dataTable; + + public {TestName}Test() + { + 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}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount*2; i++) { _newData[i] = {NextValueOp1}; } + + _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}( + (Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2)), + {ElementIndex}, + pNewData + ); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2); + } + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}( + ({LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr1)), {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr2))), + {ElementIndex}, + pNewData + ); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2); + } + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof(({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>)), typeof(byte), typeof({Op1BaseType}*) }) + .Invoke(null, new object[] { + (Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2)), + ElementIndex, + Pointer.Box(pNewData, typeof({Op1BaseType}*)) + }); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1); + var op2 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}((op1, op2), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + ValidateResult(op1, op2, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + fixed ({Op1BaseType}* pNewData = _newData) + { + var result = {Isa}.{Method}((_fld1, _fld2), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + + ValidateResult(_fld1, _fld2, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + + fixed ({Op1BaseType}* pNewData = test._newData) + { + var result = {Isa}.{Method}((test._fld1, test._fld2), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + ValidateResult(test._fld1, test._fld2, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2); + } + } + + 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({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1BaseType}* newData, void* result1, void* result2, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray1 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray2 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] newDataArray = new {RetBaseType}[Op1ElementCount*2]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray1[0]), ref Unsafe.AsRef(result1), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray2[0]), ref Unsafe.AsRef(result2), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref newDataArray[0]), ref Unsafe.AsRef(newData), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()*2); + + ValidateResult(inArray1, inArray2, newDataArray, outArray1, outArray2, method); + } + + private void ValidateResult(void* op1, void* op2, {Op1BaseType}* newData, void* result1, void* result2, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray1 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray2 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] newDataArray = new {RetBaseType}[Op1ElementCount*2]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray1[0]), ref Unsafe.AsRef(result1), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray2[0]), ref Unsafe.AsRef(result2), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref newDataArray[0]), ref Unsafe.AsRef(newData), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()*2); + + ValidateResult(inArray1, inArray2, newDataArray, outArray1, outArray2, method); + } + + private void ValidateResult({Op1BaseType}[] input1, {Op1BaseType}[] input2, {Op1BaseType}[] newData, {RetBaseType}[] result1, {RetBaseType}[] result2, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {ElementIndex}, {Op1BaseType}*): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" input1: ({string.Join(", ", input1)})"); + TestLibrary.TestFramework.LogInformation($" input2: ({string.Join(", ", input2)})"); + TestLibrary.TestFramework.LogInformation($" newData: ({string.Join(", ", newData)})"); + TestLibrary.TestFramework.LogInformation($" result1: ({string.Join(", ", result1)})"); + TestLibrary.TestFramework.LogInformation($" result2: ({string.Join(", ", result2)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx3Test.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx3Test.template new file mode 100644 index 00000000000000..a52c9751bbfc12 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx3Test.template @@ -0,0 +1,452 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.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 {TestName}Test(); + + 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 {TestName}Test + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] inArray3; + private byte[] outArray1; + private byte[] outArray2; + private byte[] outArray3; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle inHandle3; + private GCHandle outHandle1; + private GCHandle outHandle2; + private GCHandle outHandle3; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {Op1BaseType}[] inArray2, {Op1BaseType}[] inArray3, {RetBaseType}[] outArray1, {RetBaseType}[] outArray2, {RetBaseType}[] outArray3, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfoutArray1 = outArray1.Length * Unsafe.SizeOf<{RetBaseType}>(); + int sizeOfoutArray2 = outArray2.Length * Unsafe.SizeOf<{RetBaseType}>(); + int sizeOfoutArray3 = outArray3.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray1 || (alignment * 2) < sizeOfoutArray2 || (alignment * 2) < sizeOfoutArray3) + { + 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.outArray1 = new byte[alignment * 2]; + this.outArray2 = new byte[alignment * 2]; + this.outArray3 = 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.outHandle1 = GCHandle.Alloc(this.outArray1, GCHandleType.Pinned); + this.outHandle2 = GCHandle.Alloc(this.outArray2, GCHandleType.Pinned); + this.outHandle3 = GCHandle.Alloc(this.outArray3, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr1), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr2), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr3), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); + } + + public void* inArrayPtr1 => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArrayPtr2 => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArrayPtr3 => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr1 => Align((byte*)(outHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr2 => Align((byte*)(outHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr3 => Align((byte*)(outHandle3.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + inHandle3.Free(); + outHandle1.Free(); + outHandle2.Free(); + outHandle3.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op1VectorType}<{Op1BaseType}> _fld2; + public {Op1VectorType}<{Op1BaseType}> _fld3; + public {Op1BaseType}[] _newData; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] _data2 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] _data3 = new {Op1BaseType}[Op1ElementCount]; + testStruct._newData = new {Op1BaseType}[Op1ElementCount*2]; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data3[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<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount*2; i++) { testStruct._newData[i] = {NextValueOp1}; } + + return testStruct; + } + + public void RunStructFldScenario({TestName}Test testClass) + { + fixed ({Op1BaseType}* pNewData = _newData) + { + var result = {Isa}.{Method}((_fld1, _fld2, _fld3), {ElementIndex}, pNewData); + + Unsafe.Write(testClass._dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(testClass._dataTable.outArrayPtr2, result.Item2); + Unsafe.Write(testClass._dataTable.outArrayPtr3, result.Item3); + + testClass.ValidateResult(_fld1, _fld2, _fld3, pNewData, testClass._dataTable.outArrayPtr1, testClass._dataTable.outArrayPtr2, testClass._dataTable.outArrayPtr3); + } + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static readonly byte ElementIndex = {ElementIndex}; + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op1BaseType}[] _data2 = new {Op1BaseType}[Op1ElementCount]; + private static {Op1BaseType}[] _data3 = new {Op1BaseType}[Op1ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op1VectorType}<{Op1BaseType}> _fld2; + private {Op1VectorType}<{Op1BaseType}> _fld3; + private {Op1BaseType}[] _newData = new {Op1BaseType}[Op1ElementCount*2]; + + private DataTable _dataTable; + + public {TestName}Test() + { + 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}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount*2; i++) { _newData[i] = {NextValueOp1}; } + + _dataTable = new DataTable(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], new {RetBaseType}[RetElementCount], new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}( + (Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr3)), + {ElementIndex}, + pNewData + ); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, output.Item3); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, _dataTable.inArrayPtr3, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3); + } + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}( + ({LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr1)), {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr2)), {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr3))), + {ElementIndex}, + pNewData + ); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, output.Item3); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, _dataTable.inArrayPtr3, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3); + } + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof(({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>)), typeof(byte), typeof({Op1BaseType}*) }) + .Invoke(null, new object[] { + (Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr3)), + ElementIndex, + Pointer.Box(pNewData, typeof({Op1BaseType}*)) + }); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, output.Item3); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, _dataTable.inArrayPtr3, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1); + var op2 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2); + var op3 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr3); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}((op1, op2, op3), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, result.Item3); + ValidateResult(op1, op2, op3, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + fixed ({Op1BaseType}* pNewData = _newData) + { + var result = {Isa}.{Method}((_fld1, _fld2, _fld3), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, result.Item3); + + ValidateResult(_fld1, _fld2, _fld3, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + + fixed ({Op1BaseType}* pNewData = test._newData) + { + var result = {Isa}.{Method}((test._fld1, test._fld2, test._fld3), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, result.Item3); + + ValidateResult(test._fld1, test._fld2, test._fld3, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3); + } + } + + 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({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> op3, {Op1BaseType}* newData, void* result1, void* result2, void* result3, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray3 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray1 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray2 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray3 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] newDataArray = new {RetBaseType}[Op1ElementCount*2]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), op3); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray1[0]), ref Unsafe.AsRef(result1), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray2[0]), ref Unsafe.AsRef(result2), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray3[0]), ref Unsafe.AsRef(result3), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref newDataArray[0]), ref Unsafe.AsRef(newData), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()*2); + + ValidateResult(inArray1, inArray2, inArray3, newDataArray, outArray1, outArray2, outArray3, method); + } + + private void ValidateResult(void* op1, void* op2, void* op3, {Op1BaseType}* newData, void* result1, void* result2, void* result3, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray3 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray1 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray2 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray3 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] newDataArray = new {RetBaseType}[Op1ElementCount*2]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray1[0]), ref Unsafe.AsRef(result1), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray2[0]), ref Unsafe.AsRef(result2), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray3[0]), ref Unsafe.AsRef(result3), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref newDataArray[0]), ref Unsafe.AsRef(newData), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()*2); + + ValidateResult(inArray1, inArray2, inArray3, newDataArray, outArray1, outArray2, outArray3, method); + } + + private void ValidateResult({Op1BaseType}[] input1, {Op1BaseType}[] input2, {Op1BaseType}[] input3, {Op1BaseType}[] newData, {Op1BaseType}[] result1, {Op1BaseType}[] result2, {Op1BaseType}[] result3, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {ElementIndex}, {Op1BaseType}*): {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($" newData: ({string.Join(", ", newData)})"); + TestLibrary.TestFramework.LogInformation($" result1: ({string.Join(", ", result1)})"); + TestLibrary.TestFramework.LogInformation($" result2: ({string.Join(", ", result2)})"); + TestLibrary.TestFramework.LogInformation($" result3: ({string.Join(", ", result3)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx4Test.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx4Test.template new file mode 100644 index 00000000000000..15df9830d4d0ed --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/LoadAndInsertScalarx4Test.template @@ -0,0 +1,492 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.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 {TestName}Test(); + + 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 {TestName}Test + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] inArray3; + private byte[] inArray4; + private byte[] outArray1; + private byte[] outArray2; + private byte[] outArray3; + private byte[] outArray4; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle inHandle3; + private GCHandle inHandle4; + private GCHandle outHandle1; + private GCHandle outHandle2; + private GCHandle outHandle3; + private GCHandle outHandle4; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {Op1BaseType}[] inArray2, {Op1BaseType}[] inArray3, {Op1BaseType}[] inArray4, {RetBaseType}[] outArray1, {RetBaseType}[] outArray2, {RetBaseType}[] outArray3, {RetBaseType}[] outArray4, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray4 = inArray4.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfoutArray1 = outArray1.Length * Unsafe.SizeOf<{RetBaseType}>(); + int sizeOfoutArray2 = outArray2.Length * Unsafe.SizeOf<{RetBaseType}>(); + int sizeOfoutArray3 = outArray3.Length * Unsafe.SizeOf<{RetBaseType}>(); + int sizeOfoutArray4 = outArray4.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfinArray4 || (alignment * 2) < sizeOfoutArray1 || (alignment * 2) < sizeOfoutArray2 || (alignment * 2) < sizeOfoutArray3 || (alignment * 2) < sizeOfoutArray4) + { + 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.outArray1 = new byte[alignment * 2]; + this.outArray2 = new byte[alignment * 2]; + this.outArray3 = new byte[alignment * 2]; + this.outArray4 = 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.inHandle4 = GCHandle.Alloc(this.inArray4, GCHandleType.Pinned); + this.outHandle1 = GCHandle.Alloc(this.outArray1, GCHandleType.Pinned); + this.outHandle2 = GCHandle.Alloc(this.outArray2, GCHandleType.Pinned); + this.outHandle3 = GCHandle.Alloc(this.outArray3, GCHandleType.Pinned); + this.outHandle4 = GCHandle.Alloc(this.outArray4, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr1), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr2), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr3), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr4), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray4[0]), (uint)sizeOfinArray4); + } + + public void* inArrayPtr1 => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArrayPtr2 => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArrayPtr3 => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArrayPtr4 => Align((byte*)(inHandle4.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr1 => Align((byte*)(outHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr2 => Align((byte*)(outHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr3 => Align((byte*)(outHandle3.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr4 => Align((byte*)(outHandle4.AddrOfPinnedObject().ToPointer()), alignment); + + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + inHandle3.Free(); + inHandle4.Free(); + outHandle1.Free(); + outHandle2.Free(); + outHandle3.Free(); + outHandle4.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op1VectorType}<{Op1BaseType}> _fld2; + public {Op1VectorType}<{Op1BaseType}> _fld3; + public {Op1VectorType}<{Op1BaseType}> _fld4; + public {Op1BaseType}[] _newData; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] _data2 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] _data3 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] _data4 = new {Op1BaseType}[Op1ElementCount]; + testStruct._newData = new {Op1BaseType}[Op1ElementCount*2]; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data4[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<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld4), ref Unsafe.As<{Op1BaseType}, byte>(ref _data4[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount*2; i++) { testStruct._newData[i] = {NextValueOp1}; } + + return testStruct; + } + public void RunStructFldScenario({TestName}Test testClass) + { + fixed ({Op1BaseType}* pNewData = _newData) + { + var result = {Isa}.{Method}((_fld1, _fld2, _fld3, _fld4), {ElementIndex}, pNewData); + Unsafe.Write(testClass._dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(testClass._dataTable.outArrayPtr2, result.Item2); + Unsafe.Write(testClass._dataTable.outArrayPtr3, result.Item3); + Unsafe.Write(testClass._dataTable.outArrayPtr4, result.Item4); + testClass.ValidateResult(_fld1, _fld2, _fld3, _fld4, pNewData, testClass._dataTable.outArrayPtr1, testClass._dataTable.outArrayPtr2, testClass._dataTable.outArrayPtr3, testClass._dataTable.outArrayPtr4); + } + } + } + private static readonly int LargestVectorSize = {LargestVectorSize}; + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static readonly byte ElementIndex = {ElementIndex}; + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op1BaseType}[] _data2 = new {Op1BaseType}[Op1ElementCount]; + private static {Op1BaseType}[] _data3 = new {Op1BaseType}[Op1ElementCount]; + private static {Op1BaseType}[] _data4 = new {Op1BaseType}[Op1ElementCount]; + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op1VectorType}<{Op1BaseType}> _fld2; + private {Op1VectorType}<{Op1BaseType}> _fld3; + private {Op1VectorType}<{Op1BaseType}> _fld4; + private {Op1BaseType}[] _newData = new {Op1BaseType}[Op1ElementCount*2]; + private DataTable _dataTable; + + public {TestName}Test() + { + 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}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data4[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld4), ref Unsafe.As<{Op1BaseType}, byte>(ref _data4[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount*2; i++) { _newData[i] = {NextValueOp1}; } + + _dataTable = new DataTable(_data1, _data2, _data3, _data4, new {RetBaseType}[RetElementCount], new {RetBaseType}[RetElementCount], new {RetBaseType}[RetElementCount], new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}( + (Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr3), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr4)), + {ElementIndex}, + pNewData + ); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, output.Item3); + Unsafe.Write(_dataTable.outArrayPtr4, output.Item4); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, _dataTable.inArrayPtr3, _dataTable.inArrayPtr4, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3, _dataTable.outArrayPtr4); + } + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}( + ( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr1)), + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr2)), + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr3)), + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr4)) + ), + {ElementIndex}, + pNewData + ); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, output.Item3); + Unsafe.Write(_dataTable.outArrayPtr4, output.Item4); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, _dataTable.inArrayPtr3, _dataTable.inArrayPtr4, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3, _dataTable.outArrayPtr4); + } + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof(({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>)), typeof(byte), typeof({Op1BaseType}*) }) + .Invoke(null, new object[] { + (Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr3), Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr4)), + ElementIndex, + Pointer.Box(pNewData, typeof({Op1BaseType}*)) + }); + + var output = (({Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>,{Op1VectorType}<{Op1BaseType}>))result; + Unsafe.Write(_dataTable.outArrayPtr1, output.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, output.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, output.Item3); + Unsafe.Write(_dataTable.outArrayPtr4, output.Item4); + ValidateResult(_dataTable.inArrayPtr1, _dataTable.inArrayPtr2, _dataTable.inArrayPtr3, _dataTable.inArrayPtr4, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3, _dataTable.outArrayPtr4); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr1); + var op2 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr2); + var op3 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr3); + var op4 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr4); + + {Op1BaseType}[] newData = new {Op1BaseType}[Op1ElementCount*2]; + for (var i = 0; i < Op1ElementCount*2; i++) { newData[i] = {NextValueOp1}; } + + fixed ({Op1BaseType}* pNewData = newData) + { + var result = {Isa}.{Method}((op1, op2, op3, op4), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, result.Item3); + Unsafe.Write(_dataTable.outArrayPtr4, result.Item4); + ValidateResult(op1, op2, op3, op4, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3, _dataTable.outArrayPtr4); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + fixed ({Op1BaseType}* pNewData = _newData) + { + var result = {Isa}.{Method}((_fld1, _fld2, _fld3, _fld4), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, result.Item3); + Unsafe.Write(_dataTable.outArrayPtr4, result.Item4); + + ValidateResult(_fld1, _fld2, _fld3, _fld4, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3, _dataTable.outArrayPtr4); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + + fixed ({Op1BaseType}* pNewData = test._newData) + { + var result = {Isa}.{Method}((test._fld1, test._fld2, test._fld3, test._fld4), {ElementIndex}, pNewData); + + Unsafe.Write(_dataTable.outArrayPtr1, result.Item1); + Unsafe.Write(_dataTable.outArrayPtr2, result.Item2); + Unsafe.Write(_dataTable.outArrayPtr3, result.Item3); + Unsafe.Write(_dataTable.outArrayPtr4, result.Item4); + + ValidateResult(test._fld1, test._fld2, test._fld3, test._fld4, pNewData, _dataTable.outArrayPtr1, _dataTable.outArrayPtr2, _dataTable.outArrayPtr3, _dataTable.outArrayPtr4); + } + } + + 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({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> op3, {Op1VectorType}<{Op1BaseType}> op4, {Op1BaseType}* newData, void* result1, void* result2, void* result3, void* result4, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray3 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray4 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray1 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray2 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray3 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray4 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] newDataArray = new {RetBaseType}[Op1ElementCount*2]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), op3); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray4[0]), op4); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray1[0]), ref Unsafe.AsRef(result1), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray2[0]), ref Unsafe.AsRef(result2), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray3[0]), ref Unsafe.AsRef(result3), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray4[0]), ref Unsafe.AsRef(result4), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref newDataArray[0]), ref Unsafe.AsRef(newData), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()*2); + + ValidateResult(inArray1, inArray2, inArray3, inArray4, newDataArray, outArray1, outArray2, outArray3, outArray4, method); + } + + private void ValidateResult(void* op1, void* op2, void* op3, void* op4, {Op1BaseType}* newData, void* result1, void* result2, void* result3, void* result4, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray3 = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] inArray4 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray1 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray2 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray3 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] outArray4 = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] newDataArray = new {RetBaseType}[Op1ElementCount*2]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray4[0]), ref Unsafe.AsRef(op4), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray1[0]), ref Unsafe.AsRef(result1), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray2[0]), ref Unsafe.AsRef(result2), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray3[0]), ref Unsafe.AsRef(result3), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray4[0]), ref Unsafe.AsRef(result4), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref newDataArray[0]), ref Unsafe.AsRef(newData), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()*2); + + ValidateResult(inArray1, inArray2, inArray3, inArray4, newDataArray, outArray1, outArray2, outArray3, outArray4, method); + } + + private void ValidateResult({Op1BaseType}[] input1, {Op1BaseType}[] input2, {Op1BaseType}[] input3, {Op1BaseType}[] input4, {Op1BaseType}[] newData, {Op1BaseType}[] result1, {Op1BaseType}[] result2, {Op1BaseType}[] result3, {Op1BaseType}[] result4, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {ElementIndex}, {Op1BaseType}*): {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($" input4: ({string.Join(", ", input4)})"); + TestLibrary.TestFramework.LogInformation($" newData: ({string.Join(", ", newData)})"); + TestLibrary.TestFramework.LogInformation($" result1: ({string.Join(", ", result1)})"); + TestLibrary.TestFramework.LogInformation($" result2: ({string.Join(", ", result2)})"); + TestLibrary.TestFramework.LogInformation($" result3: ({string.Join(", ", result3)})"); + TestLibrary.TestFramework.LogInformation($" result4: ({string.Join(", ", result4)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +}