void genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins);
void genHWIntrinsic_R_R_R_RM(
instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTree* op3);
+ void genBaseIntrinsic(GenTreeHWIntrinsic* node);
void genSSEIntrinsic(GenTreeHWIntrinsic* node);
void genSSE2Intrinsic(GenTreeHWIntrinsic* node);
void genSSE41Intrinsic(GenTreeHWIntrinsic* node);
}
__fallthrough;
case InstructionSet_SSE:
- return JitConfig.EnableSSE() != 0;
+ if (JitConfig.EnableSSE() == 0)
+ {
+ return false;
+ }
+ __fallthrough;
+ case InstructionSet_Base:
+ return (JitConfig.EnableHWIntrinsic() != 0);
// TODO: BMI1/BMI2 actually don't depend on AVX, they depend on the VEX encoding; which is currently controlled
// by InstructionSet_AVX
if (!jitFlags.IsSet(JitFlags::JIT_FLAG_PREJIT))
{
+ if (configEnableISA(InstructionSet_Base))
+ {
+ opts.setSupportedISA(InstructionSet_Base);
+ }
if (configEnableISA(InstructionSet_SSE))
{
opts.setSupportedISA(InstructionSet_SSE);
NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method);
#ifdef FEATURE_HW_INTRINSICS
+ GenTree* impBaseIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
GenTree* impHWIntrinsic(NamedIntrinsic intrinsic,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
switch (isa)
{
+ case InstructionSet_Base:
+ genBaseIntrinsic(node);
+ break;
case InstructionSet_SSE:
genSSEIntrinsic(node);
break;
}
//------------------------------------------------------------------------
+// genBaseIntrinsic: Generates the code for a base hardware intrinsic node
+//
+// Arguments:
+// node - The hardware intrinsic node
+//
+void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node)
+{
+ NamedIntrinsic intrinsicId = node->gtHWIntrinsicId;
+ regNumber targetReg = node->gtRegNum;
+ var_types targetType = node->TypeGet();
+ var_types baseType = node->gtSIMDBaseType;
+
+ assert(node->gtGetOp1() == nullptr);
+ assert(node->gtGetOp2() == nullptr);
+ assert(baseType >= TYP_BYTE && baseType <= TYP_DOUBLE);
+
+ emitter* emit = getEmitter();
+ emitAttr attr = EA_ATTR(node->gtSIMDSize);
+
+ switch (intrinsicId)
+ {
+ case NI_Base_Vector128_Zero:
+ {
+ // When SSE2 is supported, we generate pxor for integral types otherwise just use xorps
+ instruction ins =
+ (compiler->compSupports(InstructionSet_SSE2) && varTypeIsIntegral(baseType)) ? INS_pxor : INS_xorps;
+ emit->emitIns_SIMD_R_R_R(ins, attr, targetReg, targetReg, targetReg);
+ break;
+ }
+
+ case NI_Base_Vector256_Zero:
+ {
+ // When AVX2 is supported, we generate pxor for integral types otherwise just use xorps
+ instruction ins =
+ (compiler->compSupports(InstructionSet_AVX2) && varTypeIsIntegral(baseType)) ? INS_pxor : INS_xorps;
+ emit->emitIns_SIMD_R_R_R(ins, attr, targetReg, targetReg, targetReg);
+ break;
+ }
+
+ default:
+ {
+ unreached();
+ break;
+ }
+ }
+
+ genProduceReg(node);
+}
+
+//------------------------------------------------------------------------
// genSSEIntrinsic: Generates the code for an SSE hardware intrinsic node
//
// Arguments:
// Base
HARDWARE_INTRINSIC(NI_ARM64_BASE_CLS, Base, LeadingSignCount, UnaryOp, INS_invalid, INS_cls, INS_cls, None )
HARDWARE_INTRINSIC(NI_ARM64_BASE_CLZ, Base, LeadingZeroCount, UnaryOp, INS_invalid, INS_clz, INS_clz, None )
+HARDWARE_INTRINSIC(NI_Base_Vector64_AsByte, Base, AsByte, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector64_AsInt16, Base, AsInt16, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector64_AsInt32, Base, AsInt32, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector64_AsSByte, Base, AsSByte, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector64_AsSingle, Base, AsSingle, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector64_AsUInt16, Base, AsUInt16, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector64_AsUInt32, Base, AsUInt32, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_As, Base, As, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsByte, Base, AsByte, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsDouble, Base, AsDouble, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsInt16, Base, AsInt16, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsInt32, Base, AsInt32, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsInt64, Base, AsInt64, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsSByte, Base, AsSByte, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsSingle, Base, AsSingle, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsUInt16, Base, AsUInt16, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsUInt32, Base, AsUInt32, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
+HARDWARE_INTRINSIC(NI_Base_Vector128_AsUInt64, Base, AsUInt64, UnaryOp, INS_invalid, INS_invalid, INS_invalid, None )
#if NYI
// Crc32
HARDWARE_INTRINSIC(NI_ARM64_CRC32_CRC32, Crc32, Crc32, CrcOp, INS_invalid, INS_invalid, INS_crc32, None )
HARDWARE_INTRINSIC(NI_ARM64_SIMD_Min, Simd, Min, SimdBinaryOp, INS_fmin, INS_smin, INS_umin, None )
HARDWARE_INTRINSIC(NI_ARM64_SIMD_Mul, Simd, Multiply, SimdBinaryOp, INS_fmul, INS_mul, INS_mul, None )
HARDWARE_INTRINSIC(NI_ARM64_SIMD_Sqrt, Simd, Sqrt, SimdUnaryOp, INS_fsqrt, INS_invalid, INS_invalid, None )
-HARDWARE_INTRINSIC(NI_ARM64_SIMD_StaticCast, Simd, StaticCast, SimdUnaryOp, INS_mov, INS_mov, INS_mov, None )
HARDWARE_INTRINSIC(NI_ARM64_SIMD_Sub, Simd, Subtract, SimdBinaryOp, INS_fsub, INS_sub, INS_sub, None )
HARDWARE_INTRINSIC(NI_ARM64_SIMD_GetItem, Simd, Extract, SimdExtractOp, INS_mov, INS_mov, INS_mov, None )
HARDWARE_INTRINSIC(NI_ARM64_SIMD_SetItem, Simd, Insert, SimdInsertOp, INS_mov, INS_mov, INS_mov, None )
8) Each intrinsic has one category with type of `enum HWIntrinsicCategory`, please see the definition of HWIntrinsicCategory for details
9) Each intrinsic has one or more flags with type of `enum HWIntrinsicFlag`
*/
+// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
+// Intrinsic ID Function name ISA ival SIMD size NumArg instructions Category Flags
+// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
+// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
+// Base Intrinsics
+HARDWARE_INTRINSIC(Base_Vector128_As, "As`1", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsByte, "AsByte", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsDouble, "AsDouble", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsInt16, "AsInt16", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsInt32, "AsInt32", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsInt64, "AsInt64", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsSByte, "AsSByte", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsSingle, "AsSingle", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsUInt16, "AsUInt16", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsUInt32, "AsUInt32", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_AsUInt64, "AsUInt64", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector128_Zero, "get_Zero", Base, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_As, "As`1", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsByte, "AsByte", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsDouble, "AsDouble", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsInt16, "AsInt16", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsInt32, "AsInt32", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsInt64, "AsInt64", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsSByte, "AsSByte", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsSingle, "AsSingle", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsUInt16, "AsUInt16", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsUInt32, "AsUInt32", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_AsUInt64, "AsUInt64", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(Base_Vector256_Zero, "get_Zero", Base, -1, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// Intrinsic ID Function name ISA ival SIMD size NumArg instructions Category Flags
}
}
- if ((HWIntrinsicInfo::IsOneTypeGeneric(intrinsic) || HWIntrinsicInfo::IsTwoTypeGeneric(intrinsic)) &&
- !HWIntrinsicInfo::HasSpecialImport(intrinsic))
+ if (HWIntrinsicInfo::IsOneTypeGeneric(intrinsic) && !HWIntrinsicInfo::HasSpecialImport(intrinsic))
{
if (!varTypeIsArithmetic(baseType))
{
return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, method, sig, mustExpand);
}
-
- if (HWIntrinsicInfo::IsTwoTypeGeneric(intrinsic))
- {
- // StaticCast<T, U> has two type parameters.
- assert(numArgs == 1);
- var_types srcType = getBaseTypeOfSIMDType(info.compCompHnd->getArgClass(sig, sig->args));
- if (!varTypeIsArithmetic(srcType))
- {
- return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, method, sig, mustExpand);
- }
- }
}
if (HWIntrinsicInfo::IsFloatingPointUsed(intrinsic))
// Generic
// - must throw NotSupportException if the type argument is not numeric type
HW_Flag_OneTypeGeneric = 0x4,
- // Two-type Generic
- // - the intrinsic has two type parameters
- HW_Flag_TwoTypeGeneric = 0x8,
// NoCodeGen
// - should be transformed in the compiler front-end, cannot reach CodeGen
return (flags & HW_Flag_OneTypeGeneric) != 0;
}
- static bool IsTwoTypeGeneric(NamedIntrinsic id)
- {
- HWIntrinsicFlag flags = lookupFlags(id);
- return (flags & HW_Flag_TwoTypeGeneric) != 0;
- }
-
static bool RequiresCodegen(NamedIntrinsic id)
{
HWIntrinsicFlag flags = lookupFlags(id);
ni = lookupNamedIntrinsic(method);
#ifdef FEATURE_HW_INTRINSICS
- if (ni > NI_HW_INTRINSIC_START && ni < NI_HW_INTRINSIC_END)
+ switch (ni)
+ {
+#if defined(_TARGET_ARM64_)
+ case NI_Base_Vector64_AsByte:
+ case NI_Base_Vector64_AsInt16:
+ case NI_Base_Vector64_AsInt32:
+ case NI_Base_Vector64_AsSByte:
+ case NI_Base_Vector64_AsSingle:
+ case NI_Base_Vector64_AsUInt16:
+ case NI_Base_Vector64_AsUInt32:
+#endif // _TARGET_ARM64_
+ case NI_Base_Vector128_As:
+ case NI_Base_Vector128_AsByte:
+ case NI_Base_Vector128_AsDouble:
+ case NI_Base_Vector128_AsInt16:
+ case NI_Base_Vector128_AsInt32:
+ case NI_Base_Vector128_AsInt64:
+ case NI_Base_Vector128_AsSByte:
+ case NI_Base_Vector128_AsSingle:
+ case NI_Base_Vector128_AsUInt16:
+ case NI_Base_Vector128_AsUInt32:
+ case NI_Base_Vector128_AsUInt64:
+#if defined(_TARGET_XARCH_)
+ case NI_Base_Vector128_Zero:
+ case NI_Base_Vector256_As:
+ case NI_Base_Vector256_AsByte:
+ case NI_Base_Vector256_AsDouble:
+ case NI_Base_Vector256_AsInt16:
+ case NI_Base_Vector256_AsInt32:
+ case NI_Base_Vector256_AsInt64:
+ case NI_Base_Vector256_AsSByte:
+ case NI_Base_Vector256_AsSingle:
+ case NI_Base_Vector256_AsUInt16:
+ case NI_Base_Vector256_AsUInt32:
+ case NI_Base_Vector256_AsUInt64:
+ case NI_Base_Vector256_Zero:
+#endif // _TARGET_XARCH_
+ {
+ return impBaseIntrinsic(ni, method, sig);
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ if ((ni > NI_HW_INTRINSIC_START) && (ni < NI_HW_INTRINSIC_END))
{
GenTree* hwintrinsic = impHWIntrinsic(ni, method, sig, mustExpand);
return retNode;
}
+#ifdef FEATURE_HW_INTRINSICS
+//------------------------------------------------------------------------
+// impBaseIntrinsic: dispatch intrinsics to their own implementation
+//
+// Arguments:
+// intrinsic -- id of the intrinsic function.
+// method -- method handle of the intrinsic function.
+// sig -- signature of the intrinsic call
+//
+// Return Value:
+// the expanded intrinsic.
+//
+GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
+{
+ GenTree* retNode = nullptr;
+ unsigned simdSize = 0;
+ var_types baseType = getBaseTypeAndSizeOfSIMDType(sig->retTypeClass, &simdSize);
+ var_types retType = getSIMDTypeForSize(simdSize);
+
+ if (sig->hasThis())
+ {
+ CORINFO_CLASS_HANDLE thisClass = info.compCompHnd->getArgClass(sig, sig->args);
+ var_types thisType = getBaseTypeOfSIMDType(thisClass);
+
+ if (!varTypeIsArithmetic(thisType))
+ {
+ return nullptr;
+ }
+ }
+
+ if (!varTypeIsArithmetic(baseType))
+ {
+ return nullptr;
+ }
+
+ switch (intrinsic)
+ {
+#if defined(_TARGET_ARM64_)
+ case NI_Base_Vector64_AsByte:
+ case NI_Base_Vector64_AsInt16:
+ case NI_Base_Vector64_AsInt32:
+ case NI_Base_Vector64_AsSByte:
+ case NI_Base_Vector64_AsSingle:
+ case NI_Base_Vector64_AsUInt16:
+ case NI_Base_Vector64_AsUInt32:
+#endif // _TARGET_ARM64_
+ case NI_Base_Vector128_As:
+ case NI_Base_Vector128_AsByte:
+ case NI_Base_Vector128_AsDouble:
+ case NI_Base_Vector128_AsInt16:
+ case NI_Base_Vector128_AsInt32:
+ case NI_Base_Vector128_AsInt64:
+ case NI_Base_Vector128_AsSByte:
+ case NI_Base_Vector128_AsSingle:
+ case NI_Base_Vector128_AsUInt16:
+ case NI_Base_Vector128_AsUInt32:
+ case NI_Base_Vector128_AsUInt64:
+#if defined(_TARGET_XARCH_)
+ case NI_Base_Vector256_As:
+ case NI_Base_Vector256_AsByte:
+ case NI_Base_Vector256_AsDouble:
+ case NI_Base_Vector256_AsInt16:
+ case NI_Base_Vector256_AsInt32:
+ case NI_Base_Vector256_AsInt64:
+ case NI_Base_Vector256_AsSByte:
+ case NI_Base_Vector256_AsSingle:
+ case NI_Base_Vector256_AsUInt16:
+ case NI_Base_Vector256_AsUInt32:
+ case NI_Base_Vector256_AsUInt64:
+#endif // _TARGET_XARCH_
+ {
+ // We fold away the cast here, as it only exists to satisfy
+ // the type system. It is safe to do this here since the retNode type
+ // and the signature return type are both the same TYP_SIMD.
+
+ assert(sig->numArgs == 0);
+ assert(sig->hasThis());
+
+ retNode = impSIMDPopStack(retType, true, sig->retTypeClass);
+ SetOpLclRelatedToSIMDIntrinsic(retNode);
+ assert(retNode->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass)));
+ break;
+ }
+
+#ifdef _TARGET_XARCH_
+ case NI_Base_Vector128_Zero:
+ {
+ assert(sig->numArgs == 0);
+
+ if (compSupports(InstructionSet_SSE))
+ {
+ retNode = gtNewSimdHWIntrinsicNode(retType, intrinsic, baseType, simdSize);
+ }
+ break;
+ }
+
+ case NI_Base_Vector256_Zero:
+ {
+ assert(sig->numArgs == 0);
+
+ if (compSupports(InstructionSet_AVX))
+ {
+ retNode = gtNewSimdHWIntrinsicNode(retType, intrinsic, baseType, simdSize);
+ }
+ break;
+ }
+#endif // _TARGET_XARCH_
+
+ default:
+ {
+ unreached();
+ break;
+ }
+ }
+
+ return retNode;
+}
+#endif // FEATURE_HW_INTRINSICS
+
GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
var_types callType,
result = NI_System_Collections_Generic_EqualityComparer_get_Default;
}
}
-
#ifdef FEATURE_HW_INTRINSICS
-#if defined(_TARGET_XARCH_)
- if (strcmp(namespaceName, "System.Runtime.Intrinsics.X86") == 0)
+ else if (strncmp(namespaceName, "System.Runtime.Intrinsics", 25) == 0)
{
- result = HWIntrinsicInfo::lookupId(className, methodName);
- }
+ namespaceName += 25;
+
+ if (namespaceName[0] == '\0')
+ {
+ if (strncmp(className, "Vector", 6) == 0)
+ {
+ className += 6;
+
+#if defined(_TARGET_ARM64_)
+ if (strncmp(className, "64", 2) == 0)
+ {
+ className += 2;
+
+ if (strcmp(className, "`1") == 0)
+ {
+ if (strncmp(methodName, "As", 2) == 0)
+ {
+ methodName += 2;
+
+ // Vector64_As, Vector64_AsDouble, Vector64_AsInt64, and Vector64_AsUInt64
+ // are not currently supported as they require additional plumbing to be
+ // supported by the JIT as TYP_SIMD8.
+
+ if (strcmp(methodName, "Byte") == 0)
+ {
+ result = NI_Base_Vector64_AsByte;
+ }
+ else if (strcmp(methodName, "Int16") == 0)
+ {
+ result = NI_Base_Vector64_AsInt16;
+ }
+ else if (strcmp(methodName, "Int32") == 0)
+ {
+ result = NI_Base_Vector64_AsInt32;
+ }
+ else if (strcmp(methodName, "SByte") == 0)
+ {
+ result = NI_Base_Vector64_AsSByte;
+ }
+ else if (strcmp(methodName, "Single") == 0)
+ {
+ result = NI_Base_Vector64_AsSingle;
+ }
+ else if (strcmp(methodName, "UInt16") == 0)
+ {
+ result = NI_Base_Vector64_AsUInt16;
+ }
+ else if (strcmp(methodName, "UInt32") == 0)
+ {
+ result = NI_Base_Vector64_AsUInt32;
+ }
+ }
+ }
+ }
+ else
+#endif // _TARGET_ARM64_
+ if (strncmp(className, "128", 3) == 0)
+ {
+ className += 3;
+
+ if (strcmp(className, "`1") == 0)
+ {
+ if (strncmp(methodName, "As", 2) == 0)
+ {
+ methodName += 2;
+
+ if (strcmp(methodName, "`1") == 0)
+ {
+ result = NI_Base_Vector128_As;
+ }
+ else if (strcmp(methodName, "Byte") == 0)
+ {
+ result = NI_Base_Vector128_AsByte;
+ }
+ else if (strcmp(methodName, "Double") == 0)
+ {
+ result = NI_Base_Vector128_AsDouble;
+ }
+ else if (strcmp(methodName, "Int16") == 0)
+ {
+ result = NI_Base_Vector128_AsInt16;
+ }
+ else if (strcmp(methodName, "Int32") == 0)
+ {
+ result = NI_Base_Vector128_AsInt32;
+ }
+ else if (strcmp(methodName, "Int64") == 0)
+ {
+ result = NI_Base_Vector128_AsInt64;
+ }
+ else if (strcmp(methodName, "SByte") == 0)
+ {
+ result = NI_Base_Vector128_AsSByte;
+ }
+ else if (strcmp(methodName, "Single") == 0)
+ {
+ result = NI_Base_Vector128_AsSingle;
+ }
+ else if (strcmp(methodName, "UInt16") == 0)
+ {
+ result = NI_Base_Vector128_AsUInt16;
+ }
+ else if (strcmp(methodName, "UInt32") == 0)
+ {
+ result = NI_Base_Vector128_AsUInt32;
+ }
+ else if (strcmp(methodName, "UInt64") == 0)
+ {
+ result = NI_Base_Vector128_AsUInt64;
+ }
+ }
+#if defined(_TARGET_XARCH_)
+ else if (strcmp(methodName, "get_Zero") == 0)
+ {
+ result = NI_Base_Vector128_Zero;
+ }
+#endif // _TARGET_XARCH_
+ }
+ }
+#if defined(_TARGET_XARCH_)
+ else if (strncmp(className, "256", 3) == 0)
+ {
+ className += 3;
+
+ if (strcmp(className, "`1") == 0)
+ {
+ if (strncmp(methodName, "As", 2) == 0)
+ {
+ methodName += 2;
+
+ if (strcmp(methodName, "`1") == 0)
+ {
+ result = NI_Base_Vector256_As;
+ }
+ else if (strcmp(methodName, "Byte") == 0)
+ {
+ result = NI_Base_Vector256_AsByte;
+ }
+ else if (strcmp(methodName, "Double") == 0)
+ {
+ result = NI_Base_Vector256_AsDouble;
+ }
+ else if (strcmp(methodName, "Int16") == 0)
+ {
+ result = NI_Base_Vector256_AsInt16;
+ }
+ else if (strcmp(methodName, "Int32") == 0)
+ {
+ result = NI_Base_Vector256_AsInt32;
+ }
+ else if (strcmp(methodName, "Int64") == 0)
+ {
+ result = NI_Base_Vector256_AsInt64;
+ }
+ else if (strcmp(methodName, "SByte") == 0)
+ {
+ result = NI_Base_Vector256_AsSByte;
+ }
+ else if (strcmp(methodName, "Single") == 0)
+ {
+ result = NI_Base_Vector256_AsSingle;
+ }
+ else if (strcmp(methodName, "UInt16") == 0)
+ {
+ result = NI_Base_Vector256_AsUInt16;
+ }
+ else if (strcmp(methodName, "UInt32") == 0)
+ {
+ result = NI_Base_Vector256_AsUInt32;
+ }
+ else if (strcmp(methodName, "UInt64") == 0)
+ {
+ result = NI_Base_Vector256_AsUInt64;
+ }
+ }
+ else if (strcmp(methodName, "get_Zero") == 0)
+ {
+ result = NI_Base_Vector256_Zero;
+ }
+ }
+ }
+#endif // _TARGET_XARCH_
+ }
+ }
+#if defined(_TARGET_XARCH_)
+ else if (strcmp(namespaceName, ".X86") == 0)
+ {
+ result = HWIntrinsicInfo::lookupId(className, methodName);
+ }
#elif defined(_TARGET_ARM64_)
- if (strcmp(namespaceName, "System.Runtime.Intrinsics.Arm.Arm64") == 0)
- {
- result = lookupHWIntrinsic(className, methodName);
- }
+ else if (strcmp(namespaceName, ".Arm.Arm64") == 0)
+ {
+ result = lookupHWIntrinsic(className, methodName);
+ }
#else // !defined(_TARGET_XARCH_) && !defined(_TARGET_ARM64_)
#error Unsupported platform
#endif // !defined(_TARGET_XARCH_) && !defined(_TARGET_ARM64_)
+ }
#endif // FEATURE_HW_INTRINSICS
return result;
{
InstructionSet_ILLEGAL = 0,
#ifdef _TARGET_XARCH_
+ InstructionSet_Base,
// Start linear order SIMD instruction sets
// These ISAs have strictly generation to generation order.
- InstructionSet_SSE = 1,
- InstructionSet_SSE2 = 2,
- InstructionSet_SSE3 = 3,
- InstructionSet_SSSE3 = 4,
- InstructionSet_SSE41 = 5,
- InstructionSet_SSE42 = 6,
- InstructionSet_AVX = 7,
- InstructionSet_AVX2 = 8,
- // Reserve values <32 for future SIMD instruction sets (i.e., AVX512),
+ InstructionSet_SSE,
+ InstructionSet_SSE2,
+ InstructionSet_SSE3,
+ InstructionSet_SSSE3,
+ InstructionSet_SSE41,
+ InstructionSet_SSE42,
+ InstructionSet_AVX,
+ InstructionSet_AVX2,
// End linear order SIMD instruction sets.
-
- InstructionSet_AES = 32,
- InstructionSet_BMI1 = 33,
- InstructionSet_BMI2 = 34,
- InstructionSet_FMA = 35,
- InstructionSet_LZCNT = 36,
- InstructionSet_PCLMULQDQ = 37,
- InstructionSet_POPCNT = 38,
+ InstructionSet_AES,
+ InstructionSet_BMI1,
+ InstructionSet_BMI2,
+ InstructionSet_FMA,
+ InstructionSet_LZCNT,
+ InstructionSet_PCLMULQDQ,
+ InstructionSet_POPCNT,
#elif defined(_TARGET_ARM_)
InstructionSet_NEON,
#elif defined(_TARGET_ARM64_)
#if defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
// Enable AVX instruction set for wide operations as default. When both AVX and SSE3_4 are set, we will use the most
// capable instruction set available which will prefer AVX over SSE3/4.
-CONFIG_INTEGER(EnableSSE, W("EnableSSE"), 1) // Enable SSE
-CONFIG_INTEGER(EnableSSE2, W("EnableSSE2"), 1) // Enable SSE2
-CONFIG_INTEGER(EnableSSE3, W("EnableSSE3"), 1) // Enable SSE3
-CONFIG_INTEGER(EnableSSSE3, W("EnableSSSE3"), 1) // Enable SSSE3
-CONFIG_INTEGER(EnableSSE41, W("EnableSSE41"), 1) // Enable SSE41
-CONFIG_INTEGER(EnableSSE42, W("EnableSSE42"), 1) // Enable SSE42
-CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 1) // Enable AVX
-CONFIG_INTEGER(EnableAVX2, W("EnableAVX2"), 1) // Enable AVX2
-CONFIG_INTEGER(EnableFMA, W("EnableFMA"), 1) // Enable FMA
-CONFIG_INTEGER(EnableAES, W("EnableAES"), 1) // Enable AES
-CONFIG_INTEGER(EnableBMI1, W("EnableBMI1"), 1) // Enable BMI1
-CONFIG_INTEGER(EnableBMI2, W("EnableBMI2"), 1) // Enable BMI2
-CONFIG_INTEGER(EnableLZCNT, W("EnableLZCNT"), 1) // Enable AES
-CONFIG_INTEGER(EnablePCLMULQDQ, W("EnablePCLMULQDQ"), 1) // Enable PCLMULQDQ
-CONFIG_INTEGER(EnablePOPCNT, W("EnablePOPCNT"), 1) // Enable POPCNT
-#else // !defined(_TARGET_AMD64_) && !defined(_TARGET_X86_)
+CONFIG_INTEGER(EnableHWIntrinsic, W("EnableHWIntrinsic"), 1) // Enable Base
+CONFIG_INTEGER(EnableSSE, W("EnableSSE"), 1) // Enable SSE
+CONFIG_INTEGER(EnableSSE2, W("EnableSSE2"), 1) // Enable SSE2
+CONFIG_INTEGER(EnableSSE3, W("EnableSSE3"), 1) // Enable SSE3
+CONFIG_INTEGER(EnableSSSE3, W("EnableSSSE3"), 1) // Enable SSSE3
+CONFIG_INTEGER(EnableSSE41, W("EnableSSE41"), 1) // Enable SSE41
+CONFIG_INTEGER(EnableSSE42, W("EnableSSE42"), 1) // Enable SSE42
+CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 1) // Enable AVX
+CONFIG_INTEGER(EnableAVX2, W("EnableAVX2"), 1) // Enable AVX2
+CONFIG_INTEGER(EnableFMA, W("EnableFMA"), 1) // Enable FMA
+CONFIG_INTEGER(EnableAES, W("EnableAES"), 1) // Enable AES
+CONFIG_INTEGER(EnableBMI1, W("EnableBMI1"), 1) // Enable BMI1
+CONFIG_INTEGER(EnableBMI2, W("EnableBMI2"), 1) // Enable BMI2
+CONFIG_INTEGER(EnableLZCNT, W("EnableLZCNT"), 1) // Enable AES
+CONFIG_INTEGER(EnablePCLMULQDQ, W("EnablePCLMULQDQ"), 1) // Enable PCLMULQDQ
+CONFIG_INTEGER(EnablePOPCNT, W("EnablePOPCNT"), 1) // Enable POPCNT
+#else // !defined(_TARGET_AMD64_) && !defined(_TARGET_X86_)
// Enable AVX instruction set for wide operations as default
CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 0)
-#endif // !defined(_TARGET_AMD64_) && !defined(_TARGET_X86_)
+#endif // !defined(_TARGET_AMD64_) && !defined(_TARGET_X86_)
///
/// JIT
///
NI_Math_Round = 3,
NI_System_Collections_Generic_EqualityComparer_get_Default = 4,
NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness = 5,
+
#ifdef FEATURE_HW_INTRINSICS
NI_HW_INTRINSIC_START,
#if defined(_TARGET_XARCH_)
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
public static Vector128<T> Zero
{
+ [Intrinsic]
get
{
ThrowIfUnsupportedType();
/// <typeparam name="U">The type of the vector the current instance should be reinterpreted as.</typeparam>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{U}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) or the type of the target (<typeparamref name="U" />) is not supported.</exception>
+ [Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector128<U> As<U>() where U : struct
{
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{byte}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{byte}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector128<byte> AsByte() => As<byte>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{double}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{double}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector128<double> AsDouble() => As<double>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{short}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{short}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector128<short> AsInt16() => As<short>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{int}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{int}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector128<int> AsInt32() => As<int>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{long}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{long}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector128<long> AsInt64() => As<long>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{sbyte}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{sbyte}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector128<sbyte> AsSByte() => As<sbyte>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{float}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{float}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector128<float> AsSingle() => As<float>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{ushort}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{ushort}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector128<ushort> AsUInt16() => As<ushort>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{uint}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{uint}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector128<uint> AsUInt32() => As<uint>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector128{ulong}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector128{ulong}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector128<ulong> AsUInt64() => As<ulong>();
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
public static Vector256<T> Zero
{
+ [Intrinsic]
get
{
ThrowIfUnsupportedType();
/// <typeparam name="U">The type of the vector the current instance should be reinterpreted as.</typeparam>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{U}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) or the type of the target (<typeparamref name="U" />) is not supported.</exception>
+ [Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector256<U> As<U>() where U : struct
{
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{byte}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{byte}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector256<byte> AsByte() => As<byte>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{double}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{double}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector256<double> AsDouble() => As<double>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{short}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{short}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector256<short> AsInt16() => As<short>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{int}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{int}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector256<int> AsInt32() => As<int>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{long}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{long}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector256<long> AsInt64() => As<long>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{sbyte}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{sbyte}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector256<sbyte> AsSByte() => As<sbyte>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{float}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{float}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector256<float> AsSingle() => As<float>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{ushort}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{ushort}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector256<ushort> AsUInt16() => As<ushort>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{uint}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{uint}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector256<uint> AsUInt32() => As<uint>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector256{ulong}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector256{ulong}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector256<ulong> AsUInt64() => As<ulong>();
/// <typeparam name="U">The type of the vector the current instance should be reinterpreted as.</typeparam>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{U}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) or the type of the target (<typeparamref name="U" />) is not supported.</exception>
+ [Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector64<U> As<U>() where U : struct
{
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{byte}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{byte}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector64<byte> AsByte() => As<byte>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{double}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{double}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector64<double> AsDouble() => As<double>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{short}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{short}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector64<short> AsInt16() => As<short>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{int}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{int}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector64<int> AsInt32() => As<int>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{long}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{long}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector64<long> AsInt64() => As<long>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{sbyte}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{sbyte}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector64<sbyte> AsSByte() => As<sbyte>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{float}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{float}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
public Vector64<float> AsSingle() => As<float>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{ushort}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{ushort}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector64<ushort> AsUInt16() => As<ushort>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{uint}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{uint}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector64<uint> AsUInt32() => As<uint>();
/// <summary>Reinterprets the current instance as a new <see cref="Vector64{ulong}" />.</summary>
/// <returns>The current instance reinterpreted as a new <see cref="Vector64{ulong}" />.</returns>
/// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception>
+ [Intrinsic]
[CLSCompliant(false)]
public Vector64<ulong> AsUInt64() => As<ulong>();