diff --git a/eng/Versions.props b/eng/Versions.props
index 47d338c5f21c4..a5d5d2971a27f 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -186,6 +186,8 @@
3.12.0
4.5.0
6.0.0
+ 5.0.0
+ 7.0.2
13.0.3
1.0.2
2.0.4
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs
index 5dd46b02d4231..1384da2c81d1f 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs
@@ -92,6 +92,7 @@ public static partial class Math
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Sin(double a);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe (double Sin, double Cos) SinCos(double x)
{
double sin, cos;
diff --git a/src/coreclr/System.Private.CoreLib/src/System/MathF.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/MathF.CoreCLR.cs
index e9caae4c18a38..2bef2b8d3e175 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/MathF.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/MathF.CoreCLR.cs
@@ -89,6 +89,7 @@ public static partial class MathF
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern float Sin(float x);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe (float Sin, float Cos) SinCos(float x)
{
float sin, cos;
diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h
index 5dca9aa7f5e32..8ccaeec161f06 100644
--- a/src/coreclr/jit/compiler.h
+++ b/src/coreclr/jit/compiler.h
@@ -4562,8 +4562,7 @@ class Compiler
GenTreeLclVarCommon* data, WCHAR* cns, int len, int dataOffset, StringComparison cmpMode);
GenTreeStrCon* impGetStrConFromSpan(GenTree* span);
- GenTree* impIntrinsic(GenTree* newobjThis,
- CORINFO_CLASS_HANDLE clsHnd,
+ GenTree* impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
unsigned methodFlags,
@@ -4628,7 +4627,6 @@ class Compiler
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
- GenTree* newobjThis,
bool mustExpand);
protected:
@@ -4640,7 +4638,6 @@ class Compiler
var_types retType,
CorInfoType simdBaseJitType,
unsigned simdSize,
- GenTree* newobjThis,
bool mustExpand);
GenTree* impSpecialIntrinsic(NamedIntrinsic intrinsic,
@@ -4653,10 +4650,7 @@ class Compiler
unsigned simdSize,
bool mustExpand);
- GenTree* getArgForHWIntrinsic(var_types argType,
- CORINFO_CLASS_HANDLE argClass,
- bool expectAddr = false,
- GenTree* newobjThis = nullptr);
+ GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass);
GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType);
GenTree* addRangeCheckIfNeeded(
NamedIntrinsic intrinsic, GenTree* immOp, bool mustExpand, int immLowerBound, int immUpperBound);
diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp
index 4b3f0cc9afd2b..653ff015c3272 100644
--- a/src/coreclr/jit/fgbasic.cpp
+++ b/src/coreclr/jit/fgbasic.cpp
@@ -1395,15 +1395,10 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
case NI_Vector64_CreateScalar:
case NI_Vector64_CreateScalarUnsafe:
#endif // TARGET_ARM64
- case NI_Vector2_Create:
- case NI_Vector2_CreateBroadcast:
- case NI_Vector3_Create:
- case NI_Vector3_CreateBroadcast:
- case NI_Vector3_CreateFromVector2:
case NI_Vector128_Create:
case NI_Vector128_CreateScalar:
case NI_Vector128_CreateScalarUnsafe:
- case NI_VectorT_CreateBroadcast:
+ case NI_VectorT_Create:
#if defined(TARGET_XARCH)
case NI_BMI1_TrailingZeroCount:
case NI_BMI1_X64_TrailingZeroCount:
diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp
index ec22b00d63639..9a899443294b5 100644
--- a/src/coreclr/jit/gentree.cpp
+++ b/src/coreclr/jit/gentree.cpp
@@ -27176,6 +27176,7 @@ GenTree* Compiler::gtNewSimdWithElementNode(
assert(varTypeIsArithmetic(simdBaseType));
assert(op2->IsCnsIntOrI());
+ assert(varTypeIsArithmetic(op3));
ssize_t imm8 = op2->AsIntCon()->IconValue();
ssize_t count = simdSize / genTypeSize(simdBaseType);
diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp
index 26af49073c5d6..f2f04b4a820a6 100644
--- a/src/coreclr/jit/hwintrinsic.cpp
+++ b/src/coreclr/jit/hwintrinsic.cpp
@@ -745,16 +745,11 @@ bool HWIntrinsicInfo::isImmOp(NamedIntrinsic id, const GenTree* op)
// Arguments:
// argType -- the required type of argument
// argClass -- the class handle of argType
-// expectAddr -- if true indicates we are expecting type stack entry to be a TYP_BYREF.
-// newobjThis -- For CEE_NEWOBJ, this is the temp grabbed for the allocated uninitialized object.
//
// Return Value:
// the validated argument
//
-GenTree* Compiler::getArgForHWIntrinsic(var_types argType,
- CORINFO_CLASS_HANDLE argClass,
- bool expectAddr,
- GenTree* newobjThis)
+GenTree* Compiler::getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass)
{
GenTree* arg = nullptr;
@@ -768,31 +763,12 @@ GenTree* Compiler::getArgForHWIntrinsic(var_types argType,
}
assert(varTypeIsSIMD(argType));
- if (newobjThis == nullptr)
- {
- if (expectAddr)
- {
- arg = gtNewLoadValueNode(argType, impPopStack().val);
- }
- else
- {
- arg = impSIMDPopStack();
- }
- assert(varTypeIsSIMDOrMask(arg));
- }
- else
- {
- assert(newobjThis->IsLclVarAddr());
- arg = newobjThis;
-
- // push newobj result on type stack
- unsigned lclNum = arg->AsLclVarCommon()->GetLclNum();
- impPushOnStack(gtNewLclvNode(lclNum, lvaGetRealType(lclNum)), verMakeTypeInfo(argClass));
- }
+ arg = impSIMDPopStack();
+ assert(varTypeIsSIMDOrMask(arg));
}
else
{
- assert(varTypeIsArithmetic(argType) || ((argType == TYP_BYREF) && (newobjThis == nullptr)));
+ assert(varTypeIsArithmetic(argType) || (argType == TYP_BYREF));
arg = impPopStack().val;
assert(varTypeIsArithmetic(arg->TypeGet()) || ((argType == TYP_BYREF) && arg->TypeIs(TYP_BYREF)));
diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp
index 3a481e2934517..5a32b4cbeee3d 100644
--- a/src/coreclr/jit/hwintrinsicarm64.cpp
+++ b/src/coreclr/jit/hwintrinsicarm64.cpp
@@ -721,6 +721,18 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
+ case NI_Vector128_AsVector128Unsafe:
+ {
+ assert(sig->numArgs == 1);
+ assert(retType == TYP_SIMD16);
+ assert(simdBaseJitType == CORINFO_TYPE_FLOAT);
+ assert((simdSize == 8) || (simdSize == 12));
+
+ op1 = impSIMDPopStack();
+ retNode = gtNewSimdHWIntrinsicNode(retType, op1, NI_Vector128_AsVector128Unsafe, simdBaseJitType, simdSize);
+ break;
+ }
+
case NI_Vector64_op_BitwiseAnd:
case NI_Vector128_op_BitwiseAnd:
{
diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp
index b44c9cf0785e7..5acac342b6211 100644
--- a/src/coreclr/jit/hwintrinsicxarch.cpp
+++ b/src/coreclr/jit/hwintrinsicxarch.cpp
@@ -1279,6 +1279,18 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
+ case NI_Vector128_AsVector128Unsafe:
+ {
+ assert(sig->numArgs == 1);
+ assert(retType == TYP_SIMD16);
+ assert(simdBaseJitType == CORINFO_TYPE_FLOAT);
+ assert((simdSize == 8) || (simdSize == 12));
+
+ op1 = impSIMDPopStack();
+ retNode = gtNewSimdHWIntrinsicNode(retType, op1, NI_Vector128_AsVector128Unsafe, simdBaseJitType, simdSize);
+ break;
+ }
+
case NI_Vector256_AsVector:
case NI_Vector256_AsVector256:
{
diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp
index 59a3fadf40f1e..c920ac70cfef5 100644
--- a/src/coreclr/jit/importercalls.cpp
+++ b/src/coreclr/jit/importercalls.cpp
@@ -242,7 +242,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
}
#endif // FEATURE_READYTORUN
- call = impIntrinsic(newobjThis, clsHnd, methHnd, sig, mflags, pResolvedToken, isReadonlyCall, isTailCall,
+ call = impIntrinsic(clsHnd, methHnd, sig, mflags, pResolvedToken, isReadonlyCall, isTailCall,
opcode == CEE_CALLVIRT, pConstrainedResolvedToken,
callInfo->thisTransform R2RARG(&entryPoint), &ni, &isSpecialIntrinsic);
@@ -2818,7 +2818,6 @@ GenTree* Compiler::impCreateSpanIntrinsic(CORINFO_SIG_INFO* sig)
// impIntrinsic: possibly expand intrinsic call into alternate IR sequence
//
// Arguments:
-// newobjThis - for constructor calls, the tree for the newly allocated object
// clsHnd - handle for the intrinsic method's class
// method - handle for the intrinsic method
// sig - signature of the intrinsic method
@@ -2861,8 +2860,7 @@ GenTree* Compiler::impCreateSpanIntrinsic(CORINFO_SIG_INFO* sig)
// identified as "must expand" if they are invoked from within their
// own method bodies.
//
-GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
- CORINFO_CLASS_HANDLE clsHnd,
+GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
unsigned methodFlags,
@@ -3088,7 +3086,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
if (isIntrinsic)
{
- GenTree* hwintrinsic = impSimdAsHWIntrinsic(ni, clsHnd, method, sig, newobjThis, mustExpand);
+ GenTree* hwintrinsic = impSimdAsHWIntrinsic(ni, clsHnd, method, sig, mustExpand);
if (hwintrinsic == nullptr)
{
diff --git a/src/coreclr/jit/lclmorph.cpp b/src/coreclr/jit/lclmorph.cpp
index 0c005f1909a54..1774aea55c831 100644
--- a/src/coreclr/jit/lclmorph.cpp
+++ b/src/coreclr/jit/lclmorph.cpp
@@ -1307,9 +1307,10 @@ class LocalAddressVisitor final : public GenTreeVisitor
break;
#ifdef FEATURE_HW_INTRINSICS
- // We have two cases we want to handle:
- // 1. Vector2/3/4 and Quaternion where we have 4x float fields
+ // We have three cases we want to handle:
+ // 1. Vector2/3/4 and Quaternion where we have 2-4x float fields
// 2. Plane where we have 1x Vector3 and 1x float field
+ // 3. Accesses of halves of larger SIMD types
case IndirTransform::GetElement:
{
@@ -1321,24 +1322,29 @@ class LocalAddressVisitor final : public GenTreeVisitor
{
case TYP_FLOAT:
{
+ // Handle case 1 or the float field of case 2
GenTree* indexNode = m_compiler->gtNewIconNode(offset / genTypeSize(elementType));
hwiNode = m_compiler->gtNewSimdGetElementNode(elementType, lclNode, indexNode,
CORINFO_TYPE_FLOAT, genTypeSize(varDsc));
break;
}
+
case TYP_SIMD12:
{
+ // Handle the Vector3 field of case 2
assert(genTypeSize(varDsc) == 16);
hwiNode = m_compiler->gtNewSimdHWIntrinsicNode(elementType, lclNode, NI_Vector128_AsVector3,
CORINFO_TYPE_FLOAT, 16);
break;
}
+
case TYP_SIMD8:
#if defined(FEATURE_SIMD) && defined(TARGET_XARCH)
case TYP_SIMD16:
case TYP_SIMD32:
#endif
{
+ // Handle case 3
assert(genTypeSize(elementType) * 2 == genTypeSize(varDsc));
if (offset == 0)
{
@@ -1374,29 +1380,44 @@ class LocalAddressVisitor final : public GenTreeVisitor
{
case TYP_FLOAT:
{
+ // Handle case 1 or the float field of case 2
GenTree* indexNode = m_compiler->gtNewIconNode(offset / genTypeSize(elementType));
hwiNode =
m_compiler->gtNewSimdWithElementNode(varDsc->TypeGet(), simdLclNode, indexNode, elementNode,
CORINFO_TYPE_FLOAT, genTypeSize(varDsc));
break;
}
+
case TYP_SIMD12:
{
+ // Handle the Vector3 field of case 2
assert(varDsc->TypeGet() == TYP_SIMD16);
- // We inverse the operands here and take elementNode as the main value and simdLclNode[3] as the
- // new value. This gives us a new TYP_SIMD16 with all elements in the right spots
- GenTree* indexNode = m_compiler->gtNewIconNode(3, TYP_INT);
- hwiNode = m_compiler->gtNewSimdWithElementNode(TYP_SIMD16, elementNode, indexNode, simdLclNode,
+ // We effectively inverse the operands here and take elementNode as the main value and
+ // simdLclNode[3] as the new value. This gives us a new TYP_SIMD16 with all elements in the
+ // right spots
+
+ elementNode = m_compiler->gtNewSimdHWIntrinsicNode(TYP_SIMD16, elementNode,
+ NI_Vector128_AsVector128Unsafe,
+ CORINFO_TYPE_FLOAT, 12);
+
+ GenTree* indexNode1 = m_compiler->gtNewIconNode(3, TYP_INT);
+ simdLclNode = m_compiler->gtNewSimdGetElementNode(TYP_FLOAT, simdLclNode, indexNode1,
+ CORINFO_TYPE_FLOAT, 16);
+
+ GenTree* indexNode2 = m_compiler->gtNewIconNode(3, TYP_INT);
+ hwiNode = m_compiler->gtNewSimdWithElementNode(TYP_SIMD16, elementNode, indexNode2, simdLclNode,
CORINFO_TYPE_FLOAT, 16);
break;
}
+
case TYP_SIMD8:
#if defined(FEATURE_SIMD) && defined(TARGET_XARCH)
case TYP_SIMD16:
case TYP_SIMD32:
#endif
{
+ // Handle case 3
assert(genTypeSize(elementType) * 2 == genTypeSize(varDsc));
if (offset == 0)
{
@@ -1412,6 +1433,7 @@ class LocalAddressVisitor final : public GenTreeVisitor
break;
}
+
default:
unreached();
}
@@ -1541,7 +1563,7 @@ class LocalAddressVisitor final : public GenTreeVisitor
if (varTypeIsSIMD(varDsc))
{
// We have three cases we want to handle:
- // 1. Vector2/3/4 and Quaternion where we have 4x float fields
+ // 1. Vector2/3/4 and Quaternion where we have 2-4x float fields
// 2. Plane where we have 1x Vector3 and 1x float field
// 3. Accesses of halves of larger SIMD types
diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp
index 2137874887e70..c7790fb6199d6 100644
--- a/src/coreclr/jit/lower.cpp
+++ b/src/coreclr/jit/lower.cpp
@@ -1752,18 +1752,23 @@ void Lowering::LowerArg(GenTreeCall* call, CallArg* callArg, bool late)
}
else if (arg->OperIs(GT_HWINTRINSIC))
{
- GenTreeJitIntrinsic* jitIntrinsic = reinterpret_cast(arg);
+ GenTreeHWIntrinsic* hwintrinsic = arg->AsHWIntrinsic();
// For HWIntrinsic, there are some intrinsics like ExtractVector128 which have
- // a gtType of TYP_SIMD16 but a SimdSize of 32, so we need to include that in
- // the assert below.
+ // a gtType of TYP_SIMD16 but a SimdSize of 32, so we can't necessarily assert
+ // the simd size
- assert((jitIntrinsic->GetSimdSize() == 12) || (jitIntrinsic->GetSimdSize() == 16) ||
- (jitIntrinsic->GetSimdSize() == 32) || (jitIntrinsic->GetSimdSize() == 64));
-
- if (jitIntrinsic->GetSimdSize() == 12)
+ if (hwintrinsic->GetSimdSize() == 12)
{
- type = TYP_SIMD12;
+ if (hwintrinsic->GetHWIntrinsicId() != NI_Vector128_AsVector128Unsafe)
+ {
+ // Most nodes that have a simdSize of 12 are actually producing a TYP_SIMD12
+ // and have been massaged to TYP_SIMD16 to match the actual product size. This
+ // is not the case for NI_Vector128_AsVector128Unsafe which is explicitly taking
+ // a TYP_SIMD12 and producing a TYP_SIMD16.
+
+ type = TYP_SIMD12;
+ }
}
}
}
diff --git a/src/coreclr/jit/simdashwintrinsic.cpp b/src/coreclr/jit/simdashwintrinsic.cpp
index b15a9988195e1..d04c5f10009b9 100644
--- a/src/coreclr/jit/simdashwintrinsic.cpp
+++ b/src/coreclr/jit/simdashwintrinsic.cpp
@@ -65,13 +65,11 @@ NamedIntrinsic SimdAsHWIntrinsicInfo::lookupId(Compiler* comp,
return NI_Illegal;
}
- unsigned numArgs = sig->numArgs;
- bool isInstanceMethod = false;
+ unsigned numArgs = sig->numArgs;
if (sig->hasThis())
{
- numArgs++;
- isInstanceMethod = true;
+ return NI_Illegal;
}
if (classId == SimdAsHWIntrinsicClassId::Vector)
@@ -79,8 +77,6 @@ NamedIntrinsic SimdAsHWIntrinsicInfo::lookupId(Compiler* comp,
// We want to avoid doing anything that would unnecessarily trigger a recorded dependency against Vector
// so we duplicate a few checks here to ensure this works smoothly for the static Vector class.
- assert(!isInstanceMethod);
-
if (strcmp(methodName, "get_IsHardwareAccelerated") == 0)
{
return comp->IsBaselineSimdIsaSupported() ? NI_IsSupported_True : NI_IsSupported_False;
@@ -128,11 +124,6 @@ NamedIntrinsic SimdAsHWIntrinsicInfo::lookupId(Compiler* comp,
continue;
}
- if (isInstanceMethod != SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsicInfo.id))
- {
- continue;
- }
-
if (strcmp(methodName, intrinsicInfo.name) != 0)
{
continue;
@@ -165,24 +156,6 @@ SimdAsHWIntrinsicClassId SimdAsHWIntrinsicInfo::lookupClassId(Compiler* comp,
switch (className[0])
{
- case 'P':
- {
- if (strcmp(className, "Plane") == 0)
- {
- return SimdAsHWIntrinsicClassId::Plane;
- }
- break;
- }
-
- case 'Q':
- {
- if (strcmp(className, "Quaternion") == 0)
- {
- return SimdAsHWIntrinsicClassId::Quaternion;
- }
- break;
- }
-
case 'V':
{
if (strncmp(className, "Vector", 6) != 0)
@@ -196,18 +169,6 @@ SimdAsHWIntrinsicClassId SimdAsHWIntrinsicInfo::lookupClassId(Compiler* comp,
{
return SimdAsHWIntrinsicClassId::Vector;
}
- else if (strcmp(className, "2") == 0)
- {
- return SimdAsHWIntrinsicClassId::Vector2;
- }
- else if (strcmp(className, "3") == 0)
- {
- return SimdAsHWIntrinsicClassId::Vector3;
- }
- else if (strcmp(className, "4") == 0)
- {
- return SimdAsHWIntrinsicClassId::Vector4;
- }
else if (strcmp(className, "`1") == 0)
{
uint32_t vectorTByteLength = comp->getVectorTByteLength();
@@ -253,7 +214,6 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
- GenTree* newobjThis,
bool mustExpand)
{
if (!IsBaselineSimdIsaSupported())
@@ -270,13 +230,12 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
return nullptr;
}
- CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;
- var_types retType = genActualType(JITtype2varType(sig->retType));
- CorInfoType simdBaseJitType = CORINFO_TYPE_UNDEF;
- var_types simdType = TYP_UNKNOWN;
- unsigned simdSize = 0;
- unsigned numArgs = sig->numArgs;
- bool isInstanceMethod = false;
+ CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;
+ var_types retType = genActualType(JITtype2varType(sig->retType));
+ CorInfoType simdBaseJitType = CORINFO_TYPE_UNDEF;
+ var_types simdType = TYP_UNKNOWN;
+ unsigned simdSize = 0;
+ unsigned numArgs = sig->numArgs;
// We want to resolve and populate the handle cache for this type even
// if it isn't the basis for anything carried on the node.
@@ -314,22 +273,10 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
}
}
- if (sig->hasThis())
- {
- assert(SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsic));
- numArgs++;
-
- isInstanceMethod = true;
- argClass = clsHnd;
+ assert(!sig->hasThis());
- if (SimdAsHWIntrinsicInfo::BaseTypeFromThisArg(intrinsic))
- {
- assert((simdBaseJitType == CORINFO_TYPE_UNDEF) || (simdBaseJitType == CORINFO_TYPE_VALUECLASS));
- simdBaseJitType = getBaseJitTypeAndSizeOfSIMDType(clsHnd, &simdSize);
- }
- }
- else if ((clsHnd == m_simdHandleCache->VectorHandle) && (numArgs != 0) &&
- !SimdAsHWIntrinsicInfo::KeepBaseTypeFromRet(intrinsic))
+ if ((clsHnd == m_simdHandleCache->VectorHandle) && (numArgs != 0) &&
+ !SimdAsHWIntrinsicInfo::KeepBaseTypeFromRet(intrinsic))
{
// We need to fixup the clsHnd in the case we are an intrinsic on Vector
// The first argument will be the appropriate Vector handle to use
@@ -362,18 +309,14 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
return nullptr;
}
- if (SimdAsHWIntrinsicInfo::IsFloatingPointUsed(intrinsic))
- {
- // Set `compFloatingPointUsed` to cover the scenario where an intrinsic
- // is operating on SIMD fields, but where no SIMD local vars are in use.
- compFloatingPointUsed = true;
- }
+ // Set `compFloatingPointUsed` to cover the scenario where an intrinsic
+ // is operating on SIMD fields, but where no SIMD local vars are in use.
+ compFloatingPointUsed = true;
if (hwIntrinsic == intrinsic)
{
// The SIMD intrinsic requires special handling outside the normal code path
- return impSimdAsHWIntrinsicSpecial(intrinsic, clsHnd, sig, retType, simdBaseJitType, simdSize, newobjThis,
- mustExpand);
+ return impSimdAsHWIntrinsicSpecial(intrinsic, clsHnd, sig, retType, simdBaseJitType, simdSize, mustExpand);
}
CORINFO_InstructionSet hwIntrinsicIsa = HWIntrinsicInfo::lookupIsa(hwIntrinsic);
@@ -399,9 +342,8 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
case 1:
{
- argType = isInstanceMethod ? simdType
- : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
- op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod);
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
+ op1 = getArgForHWIntrinsic(argType, argClass);
return gtNewSimdAsHWIntrinsicNode(retType, op1, hwIntrinsic, simdBaseJitType, simdSize);
}
@@ -410,20 +352,18 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
{
if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp1(intrinsic))
{
- assert(newobjThis == nullptr);
impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op1 side effects for SimdAsHWIntrinsic"));
}
assert(!SimdAsHWIntrinsicInfo::SpillSideEffectsOp2(intrinsic));
- CORINFO_ARG_LIST_HANDLE arg2 = isInstanceMethod ? argList : info.compCompHnd->getArgNext(argList);
+ CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(argList);
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
op2 = getArgForHWIntrinsic(argType, argClass);
- argType = isInstanceMethod ? simdType
- : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
- op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod);
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
+ op1 = getArgForHWIntrinsic(argType, argClass);
return gtNewSimdAsHWIntrinsicNode(retType, op1, op2, hwIntrinsic, simdBaseJitType, simdSize);
}
@@ -455,7 +395,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
var_types retType,
CorInfoType simdBaseJitType,
unsigned simdSize,
- GenTree* newobjThis,
bool mustExpand)
{
var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType);
@@ -478,17 +417,8 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
GenTree* op4 = nullptr;
GenTree* op5 = nullptr;
- unsigned numArgs = sig->numArgs;
- bool isInstanceMethod = false;
-
- if (sig->hasThis())
- {
- assert(SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsic));
- numArgs++;
-
- isInstanceMethod = true;
- argClass = clsHnd;
- }
+ unsigned numArgs = sig->numArgs;
+ assert(!sig->hasThis());
#if defined(TARGET_XARCH)
// We should have already exited early if SSE2 isn't supported
@@ -544,8 +474,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector2_MultiplyAddEstimate:
- case NI_Vector3_MultiplyAddEstimate:
case NI_VectorT_MultiplyAddEstimate:
{
if (BlockNonDeterministicIntrinsics(mustExpand))
@@ -601,7 +529,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
#endif // TARGET_XARCH
#if defined(TARGET_X86)
- case NI_VectorT_CreateBroadcast:
+ case NI_VectorT_Create:
{
if (varTypeIsLong(simdBaseType) && !impStackTop(0).val->IsIntegralConst())
{
@@ -728,8 +656,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector2_WithElement:
- case NI_Vector3_WithElement:
case NI_VectorT_WithElement:
{
assert(sig->numArgs == 3);
@@ -810,8 +736,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
break;
}
- case NI_Vector2_WithElement:
- case NI_Vector3_WithElement:
case NI_VectorT_WithElement:
{
assert(numArgs == 3);
@@ -849,8 +773,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
}
#endif // TARGET_XARCH
- case NI_Vector2_FusedMultiplyAdd:
- case NI_Vector3_FusedMultiplyAdd:
case NI_VectorT_FusedMultiplyAdd:
{
bool isFmaAccelerated = false;
@@ -917,8 +839,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
{
case 0:
{
- assert(newobjThis == nullptr);
-
switch (intrinsic)
{
case NI_VectorT_get_AllBitsSet:
@@ -954,8 +874,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
case 1:
{
- assert(newobjThis == nullptr);
-
isOpExplicit |= (intrinsic == NI_VectorT_op_Explicit);
if (isOpExplicit)
@@ -970,14 +888,11 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return op1;
}
- argType = isInstanceMethod ? simdType
- : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
- op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod);
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
+ op1 = getArgForHWIntrinsic(argType, argClass);
switch (intrinsic)
{
- case NI_Vector2_Abs:
- case NI_Vector3_Abs:
case NI_VectorT_Abs:
{
return gtNewSimdAbsNode(retType, op1, simdBaseJitType, simdSize);
@@ -1026,8 +941,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdLoadNonTemporalNode(retType, op1, simdBaseJitType, simdSize);
}
- case NI_Vector2_op_UnaryNegation:
- case NI_Vector3_op_UnaryNegation:
case NI_VectorT_op_UnaryNegation:
{
return gtNewSimdUnOpNode(GT_NEG, retType, op1, simdBaseJitType, simdSize);
@@ -1038,8 +951,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdUnOpNode(GT_NOT, retType, op1, simdBaseJitType, simdSize);
}
- case NI_Vector2_Sqrt:
- case NI_Vector3_Sqrt:
case NI_VectorT_Sqrt:
{
return gtNewSimdSqrtNode(retType, op1, simdBaseJitType, simdSize);
@@ -1257,7 +1168,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
case 2:
{
- if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp1(intrinsic) && (newobjThis == nullptr))
+ if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp1(intrinsic))
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op1 side effects for SimdAsHWIntrinsic"));
@@ -1265,30 +1176,16 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
assert(!SimdAsHWIntrinsicInfo::SpillSideEffectsOp2(intrinsic));
- CORINFO_ARG_LIST_HANDLE arg2 = isInstanceMethod ? argList : info.compCompHnd->getArgNext(argList);
+ CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(argList);
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
op2 = getArgForHWIntrinsic(argType, argClass);
- bool implicitConstructor = isInstanceMethod && (newobjThis == nullptr) && (retType == TYP_VOID);
-
- if (implicitConstructor)
- {
- op1 = getArgForHWIntrinsic(TYP_BYREF, argClass, isInstanceMethod, newobjThis);
- }
- else
- {
- argType = isInstanceMethod
- ? simdType
- : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
- op1 = getArgForHWIntrinsic(argType, (newobjThis != nullptr) ? clsHnd : argClass, isInstanceMethod,
- newobjThis);
- }
+ op1 = getArgForHWIntrinsic(argType, argClass);
switch (intrinsic)
{
- case NI_Vector2_op_Addition:
- case NI_Vector3_op_Addition:
case NI_VectorT_op_Addition:
{
return gtNewSimdBinOpNode(GT_ADD, retType, op1, op2, simdBaseJitType, simdSize);
@@ -1309,9 +1206,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdBinOpNode(GT_OR, retType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_Vector2_CreateBroadcast:
- case NI_Vector3_CreateBroadcast:
- case NI_VectorT_CreateBroadcast:
+ case NI_VectorT_Create:
{
assert(retType == TYP_VOID);
@@ -1325,15 +1220,11 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdCreateSequenceNode(simdType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_Vector2_op_Division:
- case NI_Vector3_op_Division:
case NI_VectorT_op_Division:
{
return gtNewSimdBinOpNode(GT_DIV, retType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_Vector2_Dot:
- case NI_Vector3_Dot:
case NI_VectorT_Dot:
{
op1 = gtNewSimdDotProdNode(simdType, op1, op2, simdBaseJitType, simdSize);
@@ -1345,8 +1236,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdCmpOpNode(GT_EQ, retType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_Vector2_op_Equality:
- case NI_Vector3_op_Equality:
case NI_VectorT_op_Equality:
{
return gtNewSimdCmpOpAllNode(GT_EQ, retType, op1, op2, simdBaseJitType, simdSize);
@@ -1362,8 +1251,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdBinOpNode(GT_XOR, retType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_Vector2_GetElement:
- case NI_Vector3_GetElement:
case NI_VectorT_GetElement:
{
return gtNewSimdGetElementNode(retType, op1, op2, simdBaseJitType, simdSize);
@@ -1399,8 +1286,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdCmpOpAnyNode(GT_GE, retType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_Vector2_op_Inequality:
- case NI_Vector3_op_Inequality:
case NI_VectorT_op_Inequality:
{
return gtNewSimdCmpOpAnyNode(GT_NE, retType, op1, op2, simdBaseJitType, simdSize);
@@ -1453,22 +1338,16 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdLoadNode(retType, op1, simdBaseJitType, simdSize);
}
- case NI_Vector2_Max:
- case NI_Vector3_Max:
case NI_VectorT_Max:
{
return gtNewSimdMaxNode(retType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_Vector2_Min:
- case NI_Vector3_Min:
case NI_VectorT_Min:
{
return gtNewSimdMinNode(retType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_Vector2_op_Multiply:
- case NI_Vector3_op_Multiply:
case NI_VectorT_op_Multiply:
{
return gtNewSimdBinOpNode(GT_MUL, retType, op1, op2, simdBaseJitType, simdSize);
@@ -1534,8 +1413,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdStoreNonTemporalNode(op2, op1, simdBaseJitType, simdSize);
}
- case NI_Vector2_op_Subtraction:
- case NI_Vector3_op_Subtraction:
case NI_VectorT_op_Subtraction:
{
return gtNewSimdBinOpNode(GT_SUB, retType, op1, op2, simdBaseJitType, simdSize);
@@ -1553,19 +1430,19 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
case 3:
{
- if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp1(intrinsic) && (newobjThis == nullptr))
+ if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp1(intrinsic))
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
3 DEBUGARG("Spilling op1 side effects for SimdAsHWIntrinsic"));
}
- if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp2(intrinsic) && (newobjThis == nullptr))
+ if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp2(intrinsic))
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op2 side effects for SimdAsHWIntrinsic"));
}
- CORINFO_ARG_LIST_HANDLE arg2 = isInstanceMethod ? argList : info.compCompHnd->getArgNext(argList);
+ CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(argList);
CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2);
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass)));
@@ -1574,21 +1451,8 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
op2 = getArgForHWIntrinsic(argType, argClass);
- bool implicitConstructor = isInstanceMethod && (newobjThis == nullptr) && (retType == TYP_VOID);
-
- if (implicitConstructor)
- {
- op1 = getArgForHWIntrinsic(TYP_BYREF, argClass, isInstanceMethod, newobjThis);
- }
- else
- {
- argType = isInstanceMethod
- ? simdType
- : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
-
- op1 = getArgForHWIntrinsic(argType, (newobjThis != nullptr) ? clsHnd : argClass, isInstanceMethod,
- newobjThis);
- }
+ argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass)));
+ op1 = getArgForHWIntrinsic(argType, argClass);
switch (intrinsic)
{
@@ -1597,55 +1461,11 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdCndSelNode(retType, op1, op2, op3, simdBaseJitType, simdSize);
}
- case NI_Vector2_FusedMultiplyAdd:
- case NI_Vector3_FusedMultiplyAdd:
case NI_VectorT_FusedMultiplyAdd:
{
return gtNewSimdFmaNode(retType, op1, op2, op3, simdBaseJitType, simdSize);
}
- case NI_Vector2_Lerp:
- case NI_Vector3_Lerp:
- {
- // We generate nodes equivalent to `(op1 * (1.0f - op3)) + (op2 * op3)`
- // optimizing for xarch by doing a single broadcast and for arm64 by
- // using multiply by scalar
-
- assert(simdBaseType == TYP_FLOAT);
-
-#if defined(TARGET_XARCH)
- // op3 = broadcast(op3)
- op3 = gtNewSimdCreateBroadcastNode(retType, op3, simdBaseJitType, simdSize);
-#endif // TARGET_XARCH
-
- // clonedOp3 = op3
- GenTree* clonedOp3;
- op3 = impCloneExpr(op3, &clonedOp3, CHECK_SPILL_ALL, nullptr DEBUGARG("Clone op3 for vector lerp"));
-
-#if defined(TARGET_XARCH)
- // op3 = 1.0f - op3
- GenTree* oneCon = gtNewOneConNode(retType, simdBaseType);
- op3 = gtNewSimdBinOpNode(GT_SUB, retType, oneCon, op3, simdBaseJitType, simdSize);
-#elif defined(TARGET_ARM64)
- // op3 = 1.0f - op3
- GenTree* oneCon = gtNewOneConNode(simdBaseType);
- op3 = gtNewOperNode(GT_SUB, TYP_FLOAT, oneCon, op3);
-#else
-#error Unsupported platform
-#endif
-
- // op1 *= op3
- op1 = gtNewSimdBinOpNode(GT_MUL, retType, op1, op3, simdBaseJitType, simdSize);
-
- // op2 *= clonedOp3
- op2 = gtNewSimdBinOpNode(GT_MUL, retType, op2, clonedOp3, simdBaseJitType, simdSize);
-
- // return op1 + op2
- return gtNewSimdBinOpNode(GT_ADD, retType, op1, op2, simdBaseJitType, simdSize);
- }
-
- case NI_Vector2_MultiplyAddEstimate:
- case NI_Vector3_MultiplyAddEstimate:
case NI_VectorT_MultiplyAddEstimate:
{
bool isFmaAccelerated = false;
@@ -1683,88 +1503,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdStoreNode(op2, op1, simdBaseJitType, simdSize);
}
- case NI_Vector2_Create:
- {
- assert(retType == TYP_VOID);
- assert(simdBaseType == TYP_FLOAT);
- assert(simdSize == 8);
-
- if (op2->IsCnsFltOrDbl() && op3->IsCnsFltOrDbl())
- {
- GenTreeVecCon* vecCon = gtNewVconNode(TYP_SIMD8);
-
- float cnsVal = 0;
-
- vecCon->gtSimdVal.f32[0] = static_cast(op2->AsDblCon()->DconValue());
- vecCon->gtSimdVal.f32[1] = static_cast(op3->AsDblCon()->DconValue());
-
- copyBlkSrc = vecCon;
- }
- else if (areArgumentsContiguous(op2, op3))
- {
- GenTree* op2Address = CreateAddressNodeForSimdHWIntrinsicCreate(op2, simdBaseType, 8);
- copyBlkSrc = gtNewIndir(TYP_SIMD8, op2Address);
- }
- else
- {
-#if defined(TARGET_XARCH)
- IntrinsicNodeBuilder nodeBuilder(getAllocator(CMK_ASTNode), 4);
-
- nodeBuilder.AddOperand(0, op2);
- nodeBuilder.AddOperand(1, op3);
- nodeBuilder.AddOperand(2, gtNewZeroConNode(TYP_FLOAT));
- nodeBuilder.AddOperand(3, gtNewZeroConNode(TYP_FLOAT));
-
- copyBlkSrc = gtNewSimdHWIntrinsicNode(TYP_SIMD8, std::move(nodeBuilder), NI_Vector128_Create,
- simdBaseJitType, 16);
-#elif defined(TARGET_ARM64)
- copyBlkSrc =
- gtNewSimdHWIntrinsicNode(TYP_SIMD8, op2, op3, NI_Vector64_Create, simdBaseJitType, 8);
-#else
-#error Unsupported platform
-#endif // !TARGET_XARCH && !TARGET_ARM64
- }
-
- copyBlkDst = op1;
- break;
- }
-
- case NI_Vector3_CreateFromVector2:
- {
- assert(retType == TYP_VOID);
- assert(simdBaseType == TYP_FLOAT);
- assert(simdSize == 12);
- assert(simdType == TYP_SIMD12);
-
- // TODO-CQ: We should be able to check for contiguous args here after
- // the relevant methods are updated to support more than just float
-
- if (op2->IsCnsVec() && op3->IsCnsFltOrDbl())
- {
- GenTreeVecCon* vecCon = op2->AsVecCon();
- vecCon->gtType = simdType;
-
- vecCon->gtSimdVal.f32[2] = static_cast(op3->AsDblCon()->DconValue());
- copyBlkSrc = vecCon;
- }
- else
- {
- GenTree* idx = gtNewIconNode(2, TYP_INT);
-
- op2 = gtNewSimdHWIntrinsicNode(TYP_SIMD16, op2, NI_Vector128_AsVector128Unsafe, simdBaseJitType,
- 12);
- op2 = gtNewSimdWithElementNode(TYP_SIMD16, op2, idx, op3, simdBaseJitType, 16);
-
- copyBlkSrc =
- gtNewSimdHWIntrinsicNode(TYP_SIMD12, op2, NI_Vector128_AsVector3, simdBaseJitType, 16);
- }
-
- copyBlkDst = op1;
- break;
- }
-
- case NI_Vector2_WithElement:
- case NI_Vector3_WithElement:
case NI_VectorT_WithElement:
{
return gtNewSimdWithElementNode(retType, op1, op2, op3, simdBaseJitType, simdSize);
@@ -1779,93 +1517,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
}
break;
}
-
- case 4:
- {
- assert(isInstanceMethod);
- assert(SimdAsHWIntrinsicInfo::SpillSideEffectsOp1(intrinsic));
- assert(!SimdAsHWIntrinsicInfo::SpillSideEffectsOp2(intrinsic));
-
- if (newobjThis == nullptr)
- {
- impSpillSideEffect(true, verCurrentState.esStackDepth -
- 4 DEBUGARG("Spilling op1 side effects for SimdAsHWIntrinsic"));
- }
-
- CORINFO_ARG_LIST_HANDLE arg2 = argList;
- CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2);
- CORINFO_ARG_LIST_HANDLE arg4 = info.compCompHnd->getArgNext(arg3);
-
- argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg4, &argClass)));
- op4 = getArgForHWIntrinsic(argType, argClass);
-
- 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);
-
- if ((newobjThis == nullptr) && (retType == TYP_VOID))
- {
- op1 = getArgForHWIntrinsic(TYP_BYREF, argClass, isInstanceMethod, newobjThis);
- }
- else
- {
- op1 = getArgForHWIntrinsic(simdType, (newobjThis != nullptr) ? clsHnd : argClass, isInstanceMethod,
- newobjThis);
- }
-
- switch (intrinsic)
- {
- case NI_Vector3_Create:
- {
- assert(retType == TYP_VOID);
- assert(simdBaseType == TYP_FLOAT);
- assert(simdSize == 12);
-
- if (op2->IsCnsFltOrDbl() && op3->IsCnsFltOrDbl() && op4->IsCnsFltOrDbl())
- {
- GenTreeVecCon* vecCon = gtNewVconNode(TYP_SIMD12);
-
- float cnsVal = 0;
-
- vecCon->gtSimdVal.f32[0] = static_cast(op2->AsDblCon()->DconValue());
- vecCon->gtSimdVal.f32[1] = static_cast(op3->AsDblCon()->DconValue());
- vecCon->gtSimdVal.f32[2] = static_cast(op4->AsDblCon()->DconValue());
-
- copyBlkSrc = vecCon;
- }
- else if (areArgumentsContiguous(op2, op3) && areArgumentsContiguous(op3, op4))
- {
- GenTree* op2Address = CreateAddressNodeForSimdHWIntrinsicCreate(op2, simdBaseType, 12);
- copyBlkSrc = gtNewIndir(TYP_SIMD12, op2Address);
- }
- else
- {
- IntrinsicNodeBuilder nodeBuilder(getAllocator(CMK_ASTNode), 4);
-
- nodeBuilder.AddOperand(0, op2);
- nodeBuilder.AddOperand(1, op3);
- nodeBuilder.AddOperand(2, op4);
- nodeBuilder.AddOperand(3, gtNewZeroConNode(TYP_FLOAT));
-
- copyBlkSrc = gtNewSimdHWIntrinsicNode(TYP_SIMD12, std::move(nodeBuilder), NI_Vector128_Create,
- simdBaseJitType, 16);
- }
-
- copyBlkDst = op1;
- break;
- }
-
- default:
- {
- // Some platforms warn about unhandled switch cases
- // We handle it more generally via the assert and nullptr return below.
- break;
- }
- }
- break;
- }
}
if (copyBlkDst != nullptr)
diff --git a/src/coreclr/jit/simdashwintrinsic.h b/src/coreclr/jit/simdashwintrinsic.h
index d42fff256ab8e..77fc25ae74f4e 100644
--- a/src/coreclr/jit/simdashwintrinsic.h
+++ b/src/coreclr/jit/simdashwintrinsic.h
@@ -7,11 +7,6 @@
enum class SimdAsHWIntrinsicClassId
{
Unknown,
- Plane,
- Quaternion,
- Vector2,
- Vector3,
- Vector4,
Vector,
VectorT,
};
@@ -20,25 +15,14 @@ enum class SimdAsHWIntrinsicFlag : unsigned int
{
None = 0,
- // Indicates compFloatingPointUsed does not need to be set.
- NoFloatingPointUsed = 0x1,
-
- // Indicates the intrinsic is for an instance method.
- InstanceMethod = 0x02,
-
- /* UnusedFlag = 0x04, */
-
- // Base type should come from the this argument
- BaseTypeFromThisArg = 0x08,
-
// For SIMDVectorHandle, keep the base type from the result type
- KeepBaseTypeFromRet = 0x10,
+ KeepBaseTypeFromRet = 0x01,
// Indicates that side effects need to be spilled for op1
- SpillSideEffectsOp1 = 0x20,
+ SpillSideEffectsOp1 = 0x02,
// Indicates that side effects need to be spilled for op2
- SpillSideEffectsOp2 = 0x40,
+ SpillSideEffectsOp2 = 0x04,
};
inline SimdAsHWIntrinsicFlag operator~(SimdAsHWIntrinsicFlag value)
@@ -121,24 +105,6 @@ struct SimdAsHWIntrinsicInfo
// Flags lookup
- static bool IsFloatingPointUsed(NamedIntrinsic id)
- {
- SimdAsHWIntrinsicFlag flags = lookupFlags(id);
- return (flags & SimdAsHWIntrinsicFlag::NoFloatingPointUsed) == SimdAsHWIntrinsicFlag::None;
- }
-
- static bool IsInstanceMethod(NamedIntrinsic id)
- {
- SimdAsHWIntrinsicFlag flags = lookupFlags(id);
- return (flags & SimdAsHWIntrinsicFlag::InstanceMethod) == SimdAsHWIntrinsicFlag::InstanceMethod;
- }
-
- static bool BaseTypeFromThisArg(NamedIntrinsic id)
- {
- SimdAsHWIntrinsicFlag flags = lookupFlags(id);
- return (flags & SimdAsHWIntrinsicFlag::BaseTypeFromThisArg) == SimdAsHWIntrinsicFlag::BaseTypeFromThisArg;
- }
-
static bool KeepBaseTypeFromRet(NamedIntrinsic id)
{
SimdAsHWIntrinsicFlag flags = lookupFlags(id);
diff --git a/src/coreclr/jit/simdashwintrinsiclistarm64.h b/src/coreclr/jit/simdashwintrinsiclistarm64.h
index bcf8364e75d6f..efb3107930b03 100644
--- a/src/coreclr/jit/simdashwintrinsiclistarm64.h
+++ b/src/coreclr/jit/simdashwintrinsiclistarm64.h
@@ -32,57 +32,6 @@
* Each intrinsic has one or more flags with type of `enum SimdAsHWIntrinsicFlag`
*/
-// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
-// ISA ID Name NumArg Instructions Flags
-// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
-// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
-// Vector2 Intrinsics
-SIMD_AS_HWINTRINSIC_ID(Vector2, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(Vector2, Create, ".ctor", 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Create, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
-SIMD_AS_HWINTRINSIC_NM(Vector2, CreateBroadcast, ".ctor", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_CreateBroadcast, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
-SIMD_AS_HWINTRINSIC_ID(Vector2, Dot, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Dot, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, FusedMultiplyAdd, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_FusedMultiplyAdd, NI_Illegal}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1 | SimdAsHWIntrinsicFlag::SpillSideEffectsOp2)
-SIMD_AS_HWINTRINSIC_ID(Vector2, GetElement, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_GetElement, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, Lerp, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Lerp, NI_Illegal}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1 | SimdAsHWIntrinsicFlag::SpillSideEffectsOp2)
-SIMD_AS_HWINTRINSIC_ID(Vector2, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, MultiplyAddEstimate, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_MultiplyAddEstimate, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Addition, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Division, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Subtraction, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_UnaryNegation, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_UnaryNegation, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(Vector2, Sqrt, "SquareRoot", 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, WithElement, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_WithElement, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-
-// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
-// ISA ID Name NumArg Instructions Flags
-// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
-// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
-// Vector3 Intrinsics
-SIMD_AS_HWINTRINSIC_ID(Vector3, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(Vector3, Create, ".ctor", 4, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Create, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
-SIMD_AS_HWINTRINSIC_NM(Vector3, CreateBroadcast, ".ctor", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_CreateBroadcast, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
-SIMD_AS_HWINTRINSIC_NM(Vector3, CreateFromVector2, ".ctor", 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_CreateFromVector2, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1 | SimdAsHWIntrinsicFlag::BaseTypeFromThisArg)
-SIMD_AS_HWINTRINSIC_ID(Vector3, Dot, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Dot, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, FusedMultiplyAdd, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_FusedMultiplyAdd, NI_Illegal}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1 | SimdAsHWIntrinsicFlag::SpillSideEffectsOp2)
-SIMD_AS_HWINTRINSIC_ID(Vector3, GetElement, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_GetElement, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, Lerp, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Lerp, NI_Illegal}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1 | SimdAsHWIntrinsicFlag::SpillSideEffectsOp2)
-SIMD_AS_HWINTRINSIC_ID(Vector3, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, MultiplyAddEstimate, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_MultiplyAddEstimate, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Addition, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Division, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Subtraction, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_UnaryNegation, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_UnaryNegation, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(Vector3, Sqrt, "SquareRoot", 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, WithElement, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_WithElement, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-
// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// ISA ID Name NumArg Instructions Flags
// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
@@ -115,7 +64,7 @@ SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32,
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt32Native, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64Native}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(VectorT, CreateBroadcast, ".ctor", 2, {NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
+SIMD_AS_HWINTRINSIC_ID(VectorT, Create, 1, {NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, CreateSequence, 2, {NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
SIMD_AS_HWINTRINSIC_ID(VectorT, Dot, 2, {NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_Illegal, NI_Illegal, NI_VectorT_Dot, NI_VectorT_Dot}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, Equals, 2, {NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals}, SimdAsHWIntrinsicFlag::None)
diff --git a/src/coreclr/jit/simdashwintrinsiclistxarch.h b/src/coreclr/jit/simdashwintrinsiclistxarch.h
index f8ccbeb90cb08..4074204e29ea4 100644
--- a/src/coreclr/jit/simdashwintrinsiclistxarch.h
+++ b/src/coreclr/jit/simdashwintrinsiclistxarch.h
@@ -32,57 +32,6 @@
* Each intrinsic has one or more flags with type of `enum SimdAsHWIntrinsicFlag`
*/
-// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
-// ISA ID Name NumArg Instructions Flags
-// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
-// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
-// Vector2 Intrinsics
-SIMD_AS_HWINTRINSIC_ID(Vector2, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(Vector2, Create, ".ctor", 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Create, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
-SIMD_AS_HWINTRINSIC_NM(Vector2, CreateBroadcast, ".ctor", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_CreateBroadcast, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
-SIMD_AS_HWINTRINSIC_ID(Vector2, Dot, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Dot, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, FusedMultiplyAdd, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_FusedMultiplyAdd, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, GetElement, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_GetElement, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, Lerp, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Lerp, NI_Illegal}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1 | SimdAsHWIntrinsicFlag::SpillSideEffectsOp2)
-SIMD_AS_HWINTRINSIC_ID(Vector2, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, MultiplyAddEstimate, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_MultiplyAddEstimate, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Addition, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Division, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Subtraction, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, op_UnaryNegation, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_UnaryNegation, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(Vector2, Sqrt, "SquareRoot", 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector2, WithElement, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_WithElement, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-
-// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
-// ISA ID Name NumArg Instructions Flags
-// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
-// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
-// Vector3 Intrinsics
-SIMD_AS_HWINTRINSIC_ID(Vector3, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(Vector3, Create, ".ctor", 4, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Create, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
-SIMD_AS_HWINTRINSIC_NM(Vector3, CreateBroadcast, ".ctor", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_CreateBroadcast, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
-SIMD_AS_HWINTRINSIC_NM(Vector3, CreateFromVector2, ".ctor", 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_CreateFromVector2, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1 | SimdAsHWIntrinsicFlag::BaseTypeFromThisArg)
-SIMD_AS_HWINTRINSIC_ID(Vector3, Dot, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Dot, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, FusedMultiplyAdd, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_FusedMultiplyAdd, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, GetElement, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_GetElement, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, Lerp, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Lerp, NI_Illegal}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1 | SimdAsHWIntrinsicFlag::SpillSideEffectsOp2)
-SIMD_AS_HWINTRINSIC_ID(Vector3, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, MultiplyAddEstimate, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_MultiplyAddEstimate, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Addition, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Division, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Subtraction, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, op_UnaryNegation, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_UnaryNegation, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(Vector3, Sqrt, "SquareRoot", 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(Vector3, WithElement, 3, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_WithElement, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
-
// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
// ISA ID Name NumArg Instructions Flags
// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE}
@@ -115,7 +64,7 @@ SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32,
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt32Native, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64Native}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_NM(VectorT, CreateBroadcast, ".ctor", 2, {NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
+SIMD_AS_HWINTRINSIC_ID(VectorT, Create, 1, {NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, CreateSequence, 2, {NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
SIMD_AS_HWINTRINSIC_ID(VectorT, Dot, 2, {NI_Illegal, NI_Illegal, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_Illegal, NI_Illegal, NI_VectorT_Dot, NI_VectorT_Dot}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, Equals, 2, {NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals}, SimdAsHWIntrinsicFlag::None)
diff --git a/src/libraries/Common/src/System/Net/TlsStream.cs b/src/libraries/Common/src/System/Net/TlsStream.cs
index 503253099aac1..28c344a659a31 100644
--- a/src/libraries/Common/src/System/Net/TlsStream.cs
+++ b/src/libraries/Common/src/System/Net/TlsStream.cs
@@ -8,6 +8,9 @@
using System.Threading;
using System.Threading.Tasks;
+#pragma warning disable SYSLIB0014 // ServicePointManager is obsolete
+// This type is used by FtpWebRequest (already obsolete) and SmtpClient (discouraged).
+
namespace System.Net
{
internal sealed class TlsStream : NetworkStream
diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpConnection.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpConnection.cs
index b9d99349dabb9..10e75797cfd4b 100644
--- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpConnection.cs
+++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpConnection.cs
@@ -30,6 +30,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net.Security;
@@ -100,7 +101,11 @@ public HttpConnection(Socket sock, HttpEndPointListener epl, bool secure, X509Ce
}
_timer = new Timer(OnTimeout, null, Timeout.Infinite, Timeout.Infinite);
+
+#pragma warning disable SYSLIB0014 // ServicePointManager is obsolete
_sslStream?.AuthenticateAsServer(_cert, true, (SslProtocols)ServicePointManager.SecurityProtocol, false);
+#pragma warning restore SYSLIB0014
+
Init();
}
diff --git a/src/libraries/System.Net.Requests/ref/System.Net.Requests.cs b/src/libraries/System.Net.Requests/ref/System.Net.Requests.cs
index cd52c0bfb0c6b..2e10e5fca4666 100644
--- a/src/libraries/System.Net.Requests/ref/System.Net.Requests.cs
+++ b/src/libraries/System.Net.Requests/ref/System.Net.Requests.cs
@@ -486,6 +486,7 @@ internal ServicePoint() { }
public bool CloseConnectionGroup(string connectionGroupName) { throw null; }
public void SetTcpKeepAlive(bool enabled, int keepAliveTime, int keepAliveInterval) { }
}
+ [System.ObsoleteAttribute("WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead. Settings on ServicePointManager no longer affect SslStream or HttpClient.", DiagnosticId = "SYSLIB0014", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
public partial class ServicePointManager
{
internal ServicePointManager() { }
@@ -504,11 +505,8 @@ internal ServicePointManager() { }
public static System.Net.SecurityProtocolType SecurityProtocol { get { throw null; } set { } }
public static System.Net.Security.RemoteCertificateValidationCallback? ServerCertificateValidationCallback { get { throw null; } set { } }
public static bool UseNagleAlgorithm { get { throw null; } set { } }
- [System.ObsoleteAttribute("WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.", DiagnosticId = "SYSLIB0014", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
public static System.Net.ServicePoint FindServicePoint(string uriString, System.Net.IWebProxy? proxy) { throw null; }
- [System.ObsoleteAttribute("WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.", DiagnosticId = "SYSLIB0014", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
public static System.Net.ServicePoint FindServicePoint(System.Uri address) { throw null; }
- [System.ObsoleteAttribute("WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.", DiagnosticId = "SYSLIB0014", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
public static System.Net.ServicePoint FindServicePoint(System.Uri address, System.Net.IWebProxy? proxy) { throw null; }
public static void SetTcpKeepAlive(bool enabled, int keepAliveTime, int keepAliveInterval) { }
}
diff --git a/src/libraries/System.Net.Requests/src/System/Net/FileWebRequest.cs b/src/libraries/System.Net.Requests/src/System/Net/FileWebRequest.cs
index 85d9097da906b..a7368b0fdafd2 100644
--- a/src/libraries/System.Net.Requests/src/System/Net/FileWebRequest.cs
+++ b/src/libraries/System.Net.Requests/src/System/Net/FileWebRequest.cs
@@ -9,6 +9,8 @@
namespace System.Net
{
+ // NOTE: While this class is not explicitly marked as obsolete,
+ // it effectively is by virtue of WebRequest.Create being obsolete.
public class FileWebRequest : WebRequest, ISerializable
{
private readonly WebHeaderCollection _headers = new WebHeaderCollection();
diff --git a/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs b/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs
index 4f55ea7b9048c..7694b7007fdaa 100644
--- a/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs
+++ b/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs
@@ -176,6 +176,9 @@ internal static FtpMethodInfo GetMethodInfo(string method)
};
}
+ // NOTE: While this class is not explicitly marked as obsolete,
+ // it effectively is by virtue of WebRequest.Create being obsolete.
+
///
/// The FtpWebRequest class implements a basic FTP client interface.
///
diff --git a/src/libraries/System.Net.Requests/src/System/Net/HttpWebRequest.cs b/src/libraries/System.Net.Requests/src/System/Net/HttpWebRequest.cs
index 7510495533be9..fbc32738ef21d 100644
--- a/src/libraries/System.Net.Requests/src/System/Net/HttpWebRequest.cs
+++ b/src/libraries/System.Net.Requests/src/System/Net/HttpWebRequest.cs
@@ -26,6 +26,8 @@ namespace System.Net
{
public delegate void HttpContinueDelegate(int StatusCode, WebHeaderCollection httpHeaders);
+ // NOTE: While this class is not explicitly marked as obsolete,
+ // it effectively is by virtue of WebRequest.Create being obsolete.
public class HttpWebRequest : WebRequest, ISerializable
{
private const int DefaultContinueTimeout = 350; // Current default value from .NET Desktop.
diff --git a/src/libraries/System.Net.Requests/src/System/Net/ServicePoint/ServicePoint.cs b/src/libraries/System.Net.Requests/src/System/Net/ServicePoint/ServicePoint.cs
index d48ac0760992c..fdf6964981b12 100644
--- a/src/libraries/System.Net.Requests/src/System/Net/ServicePoint/ServicePoint.cs
+++ b/src/libraries/System.Net.Requests/src/System/Net/ServicePoint/ServicePoint.cs
@@ -7,6 +7,9 @@
namespace System.Net
{
+ // NOTE: While this class is not explicitly marked as obsolete,
+ // it effectively is by virtue of ServicePointManager being obsolete,
+ // where ServicePointManager is the only way to obtain ServicePoint instances.
public class ServicePoint
{
private int _connectionLeaseTimeout = -1;
diff --git a/src/libraries/System.Net.Requests/src/System/Net/ServicePoint/ServicePointManager.cs b/src/libraries/System.Net.Requests/src/System/Net/ServicePoint/ServicePointManager.cs
index 8245e309efd93..be282f8401a92 100644
--- a/src/libraries/System.Net.Requests/src/System/Net/ServicePoint/ServicePointManager.cs
+++ b/src/libraries/System.Net.Requests/src/System/Net/ServicePoint/ServicePointManager.cs
@@ -9,6 +9,7 @@
namespace System.Net
{
+ [Obsolete(Obsoletions.WebRequestMessage + " Settings on ServicePointManager no longer affect SslStream or HttpClient.", DiagnosticId = Obsoletions.WebRequestDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public class ServicePointManager
{
public const int DefaultNonPersistentConnectionLimit = 4;
@@ -99,13 +100,10 @@ public static int DnsRefreshTimeout
[UnsupportedOSPlatform("browser")]
public static EncryptionPolicy EncryptionPolicy { get; } = EncryptionPolicy.RequireEncryption;
- [Obsolete(Obsoletions.WebRequestMessage, DiagnosticId = Obsoletions.WebRequestDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public static ServicePoint FindServicePoint(Uri address) => FindServicePoint(address, null);
- [Obsolete(Obsoletions.WebRequestMessage, DiagnosticId = Obsoletions.WebRequestDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public static ServicePoint FindServicePoint(string uriString, IWebProxy? proxy) => FindServicePoint(new Uri(uriString), proxy);
- [Obsolete(Obsoletions.WebRequestMessage, DiagnosticId = Obsoletions.WebRequestDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public static ServicePoint FindServicePoint(Uri address, IWebProxy? proxy)
{
ArgumentNullException.ThrowIfNull(address);
diff --git a/src/libraries/System.Net.Requests/src/System/Net/WebRequest.cs b/src/libraries/System.Net.Requests/src/System/Net/WebRequest.cs
index 5442fdeef0fac..da55677ba160a 100644
--- a/src/libraries/System.Net.Requests/src/System/Net/WebRequest.cs
+++ b/src/libraries/System.Net.Requests/src/System/Net/WebRequest.cs
@@ -15,6 +15,8 @@
using System.Threading.Tasks;
namespace System.Net
{
+ // NOTE: While this class is not explicitly marked as obsolete,
+ // it effectively is by virtue of WebRequest.Create being obsolete.
public abstract class WebRequest : MarshalByRefObject, ISerializable
{
internal sealed class WebRequestPrefixElement
diff --git a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs
index 98b2db5e13365..13b94b02fd2cf 100644
--- a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs
+++ b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs
@@ -207,6 +207,16 @@ public static partial class Vector
public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; }
public static System.Numerics.Vector AndNot(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; }
public static System.Numerics.Vector As(this System.Numerics.Vector vector) { throw null; }
+ public static System.Numerics.Plane AsPlane(this System.Numerics.Vector4 value) { throw null; }
+ public static System.Numerics.Quaternion AsQuaternion(this System.Numerics.Vector4 value) { throw null; }
+ public static System.Numerics.Vector2 AsVector2(this System.Numerics.Vector4 value) { throw null; }
+ public static System.Numerics.Vector3 AsVector3(this System.Numerics.Vector4 value) { throw null; }
+ public static System.Numerics.Vector4 AsVector4(this System.Numerics.Plane value) { throw null; }
+ public static System.Numerics.Vector4 AsVector4(this System.Numerics.Quaternion value) { throw null; }
+ public static System.Numerics.Vector4 AsVector4(this System.Numerics.Vector2 value) { throw null; }
+ public static System.Numerics.Vector4 AsVector4(this System.Numerics.Vector3 value) { throw null; }
+ public static System.Numerics.Vector4 AsVector4Unsafe(this System.Numerics.Vector2 value) { throw null; }
+ public static System.Numerics.Vector4 AsVector4Unsafe(this System.Numerics.Vector3 value) { throw null; }
public static System.Numerics.Vector AsVectorByte(System.Numerics.Vector value) { throw null; }
public static System.Numerics.Vector AsVectorDouble(System.Numerics.Vector value) { throw null; }
public static System.Numerics.Vector AsVectorInt16(System.Numerics.Vector value) { throw null; }
@@ -249,6 +259,8 @@ public static partial class Vector
public static System.Numerics.Vector ConvertToUInt64(System.Numerics.Vector value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static System.Numerics.Vector ConvertToUInt64Native(System.Numerics.Vector value) { throw null; }
+ public static System.Numerics.Vector Create(T value) { throw null; }
+ public static System.Numerics.Vector Create(System.ReadOnlySpan values) { throw null; }
public static System.Numerics.Vector CreateSequence(T start, T step) { throw null; }
public static System.Numerics.Vector Divide(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; }
public static System.Numerics.Vector Divide(System.Numerics.Vector left, T right) { throw null; }
@@ -426,6 +438,9 @@ public partial struct Vector2 : System.IEquatable, Syst
public static System.Numerics.Vector2 Abs(System.Numerics.Vector2 value) { throw null; }
public static System.Numerics.Vector2 Add(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; }
public static System.Numerics.Vector2 Clamp(System.Numerics.Vector2 value1, System.Numerics.Vector2 min, System.Numerics.Vector2 max) { throw null; }
+ public static System.Numerics.Vector2 Create(float value) { throw null; }
+ public static System.Numerics.Vector2 Create(float x, float y) { throw null; }
+ public static System.Numerics.Vector2 Create(System.ReadOnlySpan values) { throw null; }
public readonly void CopyTo(float[] array) { }
public readonly void CopyTo(float[] array, int index) { }
public readonly void CopyTo(System.Span destination) { }
@@ -490,6 +505,10 @@ public partial struct Vector3 : System.IEquatable, Syst
public static System.Numerics.Vector3 Abs(System.Numerics.Vector3 value) { throw null; }
public static System.Numerics.Vector3 Add(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; }
public static System.Numerics.Vector3 Clamp(System.Numerics.Vector3 value1, System.Numerics.Vector3 min, System.Numerics.Vector3 max) { throw null; }
+ public static System.Numerics.Vector3 Create(float value) { throw null; }
+ public static System.Numerics.Vector3 Create(System.Numerics.Vector2 vector, float z) { throw null; }
+ public static System.Numerics.Vector3 Create(float x, float y, float z) { throw null; }
+ public static System.Numerics.Vector3 Create(System.ReadOnlySpan values) { throw null; }
public readonly void CopyTo(float[] array) { }
public readonly void CopyTo(float[] array, int index) { }
public readonly void CopyTo(System.Span destination) { }
@@ -556,6 +575,11 @@ public partial struct Vector4 : System.IEquatable, Syst
public static System.Numerics.Vector4 Abs(System.Numerics.Vector4 value) { throw null; }
public static System.Numerics.Vector4 Add(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; }
public static System.Numerics.Vector4 Clamp(System.Numerics.Vector4 value1, System.Numerics.Vector4 min, System.Numerics.Vector4 max) { throw null; }
+ public static System.Numerics.Vector4 Create(float value) { throw null; }
+ public static System.Numerics.Vector4 Create(System.Numerics.Vector2 vector, float z, float w) { throw null; }
+ public static System.Numerics.Vector4 Create(System.Numerics.Vector3 vector, float w) { throw null; }
+ public static System.Numerics.Vector4 Create(float x, float y, float z, float w) { throw null; }
+ public static System.Numerics.Vector4 Create(System.ReadOnlySpan values) { throw null; }
public readonly void CopyTo(float[] array) { }
public readonly void CopyTo(float[] array, int index) { }
public readonly void CopyTo(System.Span destination) { }
diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index 4d68dc5729e26..77475d432d57a 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -599,6 +599,7 @@
+
@@ -2794,4 +2795,4 @@
-
\ No newline at end of file
+
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix3x2.Impl.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix3x2.Impl.cs
index 4fb270baa096b..7d270c17cc0de 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix3x2.Impl.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix3x2.Impl.cs
@@ -32,7 +32,7 @@ internal struct Impl : IEquatable
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref Matrix3x2 AsM3x2() => ref Unsafe.As(ref this);
- private const float RotationEpsilon = 0.001f * MathF.PI / 180f; // 0.1% of a degree
+ private const float RotationEpsilon = 0.001f * float.Pi / 180f; // 0.1% of a degree
public Vector2 X;
public Vector2 Y;
@@ -43,9 +43,9 @@ public void Init(float m11, float m12,
float m21, float m22,
float m31, float m32)
{
- X = new Vector2(m11, m12);
- Y = new Vector2(m21, m22);
- Z = new Vector2(m31, m32);
+ X = Vector2.Create(m11, m12);
+ Y = Vector2.Create(m21, m22);
+ Z = Vector2.Create(m31, m32);
}
public static Impl Identity
@@ -146,15 +146,15 @@ readonly get
{
Impl result;
- result.X = new Vector2(
+ result.X = Vector2.Create(
left.X.X * right.X.X + left.X.Y * right.Y.X,
left.X.X * right.X.Y + left.X.Y * right.Y.Y
);
- result.Y = new Vector2(
+ result.Y = Vector2.Create(
left.Y.X * right.X.X + left.Y.Y * right.Y.X,
left.Y.X * right.X.Y + left.Y.Y * right.Y.Y
);
- result.Z = new Vector2(
+ result.Z = Vector2.Create(
left.Z.X * right.X.X + left.Z.Y * right.Y.X + right.Z.X,
left.Z.X * right.X.Y + left.Z.Y * right.Y.Y + right.Z.Y
);
@@ -201,7 +201,7 @@ readonly get
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateRotation(float radians)
{
- radians = MathF.IEEERemainder(radians, MathF.PI * 2);
+ radians = float.Ieee754Remainder(radians, float.Tau);
float c;
float s;
@@ -212,19 +212,19 @@ public static Impl CreateRotation(float radians)
c = 1;
s = 0;
}
- else if (radians > MathF.PI / 2 - RotationEpsilon && radians < MathF.PI / 2 + RotationEpsilon)
+ else if (radians > float.Pi / 2 - RotationEpsilon && radians < float.Pi / 2 + RotationEpsilon)
{
// Exact case for 90 degree rotation.
c = 0;
s = 1;
}
- else if (radians < -MathF.PI + RotationEpsilon || radians > MathF.PI - RotationEpsilon)
+ else if (radians < -float.Pi + RotationEpsilon || radians > float.Pi - RotationEpsilon)
{
// Exact case for 180 degree rotation.
c = -1;
s = 0;
}
- else if (radians > -MathF.PI / 2 - RotationEpsilon && radians < -MathF.PI / 2 + RotationEpsilon)
+ else if (radians > -float.Pi / 2 - RotationEpsilon && radians < -float.Pi / 2 + RotationEpsilon)
{
// Exact case for 270 degree rotation.
c = 0;
@@ -233,8 +233,7 @@ public static Impl CreateRotation(float radians)
else
{
// Arbitrary rotation.
- c = MathF.Cos(radians);
- s = MathF.Sin(radians);
+ (s, c) = float.SinCos(radians);
}
// [ c s ]
@@ -243,8 +242,8 @@ public static Impl CreateRotation(float radians)
Impl result;
- result.X = new Vector2( c, s);
- result.Y = new Vector2(-s, c);
+ result.X = Vector2.Create( c, s);
+ result.Y = Vector2.Create(-s, c);
result.Z = Vector2.Zero;
return result;
@@ -253,7 +252,7 @@ public static Impl CreateRotation(float radians)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateRotation(float radians, Vector2 centerPoint)
{
- radians = MathF.IEEERemainder(radians, MathF.PI * 2);
+ radians = float.Ieee754Remainder(radians, float.Tau);
float c, s;
@@ -263,19 +262,19 @@ public static Impl CreateRotation(float radians, Vector2 centerPoint)
c = 1;
s = 0;
}
- else if (radians > MathF.PI / 2 - RotationEpsilon && radians < MathF.PI / 2 + RotationEpsilon)
+ else if (radians > float.Pi / 2 - RotationEpsilon && radians < float.Pi / 2 + RotationEpsilon)
{
// Exact case for 90 degree rotation.
c = 0;
s = 1;
}
- else if (radians < -MathF.PI + RotationEpsilon || radians > MathF.PI - RotationEpsilon)
+ else if (radians < -float.Pi + RotationEpsilon || radians > float.Pi - RotationEpsilon)
{
// Exact case for 180 degree rotation.
c = -1;
s = 0;
}
- else if (radians > -MathF.PI / 2 - RotationEpsilon && radians < -MathF.PI / 2 + RotationEpsilon)
+ else if (radians > -float.Pi / 2 - RotationEpsilon && radians < -float.Pi / 2 + RotationEpsilon)
{
// Exact case for 270 degree rotation.
c = 0;
@@ -284,8 +283,7 @@ public static Impl CreateRotation(float radians, Vector2 centerPoint)
else
{
// Arbitrary rotation.
- c = MathF.Cos(radians);
- s = MathF.Sin(radians);
+ (s, c) = float.SinCos(radians);
}
float x = centerPoint.X * (1 - c) + centerPoint.Y * s;
@@ -297,9 +295,9 @@ public static Impl CreateRotation(float radians, Vector2 centerPoint)
Impl result;
- result.X = new Vector2( c, s);
- result.Y = new Vector2(-s, c);
- result.Z = new Vector2( x, y);
+ result.X = Vector2.Create( c, s);
+ result.Y = Vector2.Create(-s, c);
+ result.Z = Vector2.Create( x, y);
return result;
}
@@ -309,8 +307,8 @@ public static Impl CreateScale(Vector2 scales)
{
Impl result;
- result.X = new Vector2(scales.X, 0);
- result.Y = new Vector2(0, scales.Y);
+ result.X = Vector2.CreateScalar(scales.X);
+ result.Y = Vector2.Create(0, scales.Y);
result.Z = Vector2.Zero;
return result;
@@ -321,8 +319,8 @@ public static Impl CreateScale(float scaleX, float scaleY)
{
Impl result;
- result.X = new Vector2(scaleX, 0);
- result.Y = new Vector2(0, scaleY);
+ result.X = Vector2.CreateScalar(scaleX);
+ result.Y = Vector2.Create(0, scaleY);
result.Z = Vector2.Zero;
return result;
@@ -333,9 +331,9 @@ public static Impl CreateScale(float scaleX, float scaleY, Vector2 centerPoint)
{
Impl result;
- result.X = new Vector2(scaleX, 0);
- result.Y = new Vector2(0, scaleY);
- result.Z = centerPoint * (Vector2.One - new Vector2(scaleX, scaleY));
+ result.X = Vector2.CreateScalar(scaleX);
+ result.Y = Vector2.Create(0, scaleY);
+ result.Z = centerPoint * (Vector2.One - Vector2.Create(scaleX, scaleY));
return result;
}
@@ -345,8 +343,8 @@ public static Impl CreateScale(Vector2 scales, Vector2 centerPoint)
{
Impl result;
- result.X = new Vector2(scales.X, 0);
- result.Y = new Vector2(0, scales.Y);
+ result.X = Vector2.CreateScalar(scales.X);
+ result.Y = Vector2.Create(0, scales.Y);
result.Z = centerPoint * (Vector2.One - scales);
return result;
@@ -357,8 +355,8 @@ public static Impl CreateScale(float scale)
{
Impl result;
- result.X = new Vector2(scale, 0);
- result.Y = new Vector2(0, scale);
+ result.X = Vector2.CreateScalar(scale);
+ result.Y = Vector2.Create(0, scale);
result.Z = Vector2.Zero;
return result;
@@ -369,9 +367,9 @@ public static Impl CreateScale(float scale, Vector2 centerPoint)
{
Impl result;
- result.X = new Vector2(scale, 0);
- result.Y = new Vector2(0, scale);
- result.Z = centerPoint * (Vector2.One - new Vector2(scale));
+ result.X = Vector2.CreateScalar(scale);
+ result.Y = Vector2.Create(0, scale);
+ result.Z = centerPoint * (Vector2.One - Vector2.Create(scale));
return result;
}
@@ -381,8 +379,8 @@ public static Impl CreateSkew(float radiansX, float radiansY)
{
Impl result;
- result.X = new Vector2(1, MathF.Tan(radiansY));
- result.Y = new Vector2(MathF.Tan(radiansX), 1);
+ result.X = Vector2.Create(1, float.Tan(radiansY));
+ result.Y = Vector2.Create(float.Tan(radiansX), 1);
result.Z = Vector2.Zero;
return result;
@@ -391,17 +389,17 @@ public static Impl CreateSkew(float radiansX, float radiansY)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateSkew(float radiansX, float radiansY, Vector2 centerPoint)
{
- float xTan = MathF.Tan(radiansX);
- float yTan = MathF.Tan(radiansY);
+ float xTan = float.Tan(radiansX);
+ float yTan = float.Tan(radiansY);
float tx = -centerPoint.Y * xTan;
float ty = -centerPoint.X * yTan;
Impl result;
- result.X = new Vector2(1, yTan);
- result.Y = new Vector2(xTan, 1);
- result.Z = new Vector2(tx, ty);
+ result.X = Vector2.Create(1, yTan);
+ result.Y = Vector2.Create(xTan, 1);
+ result.Z = Vector2.Create(tx, ty);
return result;
}
@@ -425,7 +423,7 @@ public static Impl CreateTranslation(float positionX, float positionY)
result.X = Vector2.UnitX;
result.Y = Vector2.UnitY;
- result.Z = new Vector2(positionX, positionY);
+ result.Z = Vector2.Create(positionX, positionY);
return result;
}
@@ -435,9 +433,9 @@ public static bool Invert(in Impl matrix, out Impl result)
{
float det = (matrix.X.X * matrix.Y.Y) - (matrix.Y.X * matrix.X.Y);
- if (MathF.Abs(det) < float.Epsilon)
+ if (float.Abs(det) < float.Epsilon)
{
- Vector2 vNaN = new Vector2(float.NaN);
+ Vector2 vNaN = Vector2.Create(float.NaN);
result.X = vNaN;
result.Y = vNaN;
@@ -448,15 +446,15 @@ public static bool Invert(in Impl matrix, out Impl result)
float invDet = 1.0f / det;
- result.X = new Vector2(
+ result.X = Vector2.Create(
+matrix.Y.Y * invDet,
-matrix.X.Y * invDet
);
- result.Y = new Vector2(
+ result.Y = Vector2.Create(
-matrix.Y.X * invDet,
+matrix.X.X * invDet
);
- result.Z = new Vector2(
+ result.Z = Vector2.Create(
(matrix.Y.X * matrix.Z.Y - matrix.Z.X * matrix.Y.Y) * invDet,
(matrix.Z.X * matrix.X.Y - matrix.X.X * matrix.Z.Y) * invDet
);
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs
index 492eda1b452d0..79e96fd05dd5d 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs
@@ -38,7 +38,7 @@ internal struct Impl : IEquatable
public ref Matrix4x4 AsM4x4() => ref Unsafe.As(ref this);
private const float BillboardEpsilon = 1e-4f;
- private const float BillboardMinAngle = 1.0f - (0.1f * (MathF.PI / 180.0f)); // 0.1 degrees
+ private const float BillboardMinAngle = 1.0f - (0.1f * (float.Pi / 180.0f)); // 0.1 degrees
private const float DecomposeEpsilon = 0.0001f;
public Vector4 X;
@@ -52,19 +52,19 @@ public void Init(float m11, float m12, float m13, float m14,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44)
{
- X = new Vector4(m11, m12, m13, m14);
- Y = new Vector4(m21, m22, m23, m24);
- Z = new Vector4(m31, m32, m33, m34);
- W = new Vector4(m41, m42, m43, m44);
+ X = Vector4.Create(m11, m12, m13, m14);
+ Y = Vector4.Create(m21, m22, m23, m24);
+ Z = Vector4.Create(m31, m32, m33, m34);
+ W = Vector4.Create(m41, m42, m43, m44);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Init(in Matrix3x2.Impl value)
{
- X = new Vector4(value.X, 0, 0);
- Y = new Vector4(value.Y, 0, 0);
+ X = Vector4.Create(value.X, 0, 0);
+ Y = Vector4.Create(value.Y, 0, 0);
Z = Vector4.UnitZ;
- W = new Vector4(value.Z, 0, 1);
+ W = Vector4.Create(value.Z, 0, 1);
}
public static Impl Identity
@@ -122,12 +122,12 @@ public readonly bool IsIdentity
public Vector3 Translation
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- readonly get => new Vector3(W.X, W.Y, W.Z);
+ readonly get => W.AsVector3();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
- W = new Vector4(value, W.W);
+ W = Vector4.Create(value, W.W);
}
}
@@ -245,7 +245,7 @@ public static Impl CreateBillboard(in Vector3 objectPosition, in Vector3 cameraP
}
else
{
- axisZ = Vector3.Multiply(axisZ, 1.0f / MathF.Sqrt(norm));
+ axisZ = Vector3.Multiply(axisZ, 1.0f / float.Sqrt(norm));
}
Vector3 axisX = Vector3.Normalize(Vector3.Cross(cameraUpVector, axisZ));
@@ -253,10 +253,10 @@ public static Impl CreateBillboard(in Vector3 objectPosition, in Vector3 cameraP
Impl result;
- result.X = new Vector4(axisX, 0);
- result.Y = new Vector4(axisY, 0);
- result.Z = new Vector4(axisZ, 0);
- result.W = new Vector4(objectPosition, 1);
+ result.X = axisX.AsVector4();
+ result.Y = axisY.AsVector4();
+ result.Z = axisZ.AsVector4();;
+ result.W = Vector4.Create(objectPosition, 1);
return result;
}
@@ -274,7 +274,7 @@ public static Impl CreateConstrainedBillboard(in Vector3 objectPosition, in Vect
}
else
{
- faceDir = Vector3.Multiply(faceDir, (1.0f / MathF.Sqrt(norm)));
+ faceDir = Vector3.Multiply(faceDir, (1.0f / float.Sqrt(norm)));
}
Vector3 axisY = rotateAxis;
@@ -282,16 +282,16 @@ public static Impl CreateConstrainedBillboard(in Vector3 objectPosition, in Vect
// Treat the case when angle between faceDir and rotateAxis is too close to 0.
float dot = Vector3.Dot(axisY, faceDir);
- if (MathF.Abs(dot) > BillboardMinAngle)
+ if (float.Abs(dot) > BillboardMinAngle)
{
faceDir = objectForwardVector;
// Make sure passed values are useful for compute.
dot = Vector3.Dot(axisY, faceDir);
- if (MathF.Abs(dot) > BillboardMinAngle)
+ if (float.Abs(dot) > BillboardMinAngle)
{
- faceDir = (MathF.Abs(axisY.Z) > BillboardMinAngle) ? Vector3.UnitX : new Vector3(0, 0, -1);
+ faceDir = (float.Abs(axisY.Z) > BillboardMinAngle) ? Vector3.UnitX : Vector3.Create(0, 0, -1);
}
}
@@ -300,10 +300,10 @@ public static Impl CreateConstrainedBillboard(in Vector3 objectPosition, in Vect
Impl result;
- result.X = new Vector4(axisX, 0);
- result.Y = new Vector4(axisY, 0);
- result.Z = new Vector4(axisZ, 0);
- result.W = new Vector4(objectPosition, 1);
+ result.X = axisX.AsVector4();
+ result.Y = axisY.AsVector4();
+ result.Z = axisZ.AsVector4();
+ result.W = Vector4.Create(objectPosition, 1);
return result;
}
@@ -341,8 +341,7 @@ public static Impl CreateFromAxisAngle(in Vector3 axis, float angle)
float y = axis.Y;
float z = axis.Z;
- float sa = MathF.Sin(angle);
- float ca = MathF.Cos(angle);
+ (float sa, float ca) = float.SinCos(angle);
float xx = x * x;
float yy = y * y;
@@ -354,19 +353,19 @@ public static Impl CreateFromAxisAngle(in Vector3 axis, float angle)
Impl result;
- result.X = new Vector4(
+ result.X = Vector4.Create(
xx + ca * (1.0f - xx),
xy - ca * xy + sa * z,
xz - ca * xz - sa * y,
0
);
- result.Y = new Vector4(
+ result.Y = Vector4.Create(
xy - ca * xy - sa * z,
yy + ca * (1.0f - yy),
yz - ca * yz + sa * x,
0
);
- result.Z = new Vector4(
+ result.Z = Vector4.Create(
xz - ca * xz + sa * y,
yz - ca * yz - sa * x,
zz + ca * (1.0f - zz),
@@ -393,19 +392,19 @@ public static Impl CreateFromQuaternion(in Quaternion quaternion)
Impl result;
- result.X = new Vector4(
+ result.X = Vector4.Create(
1.0f - 2.0f * (yy + zz),
2.0f * (xy + wz),
2.0f * (xz - wy),
0
);
- result.Y = new Vector4(
+ result.Y = Vector4.Create(
2.0f * (xy - wz),
1.0f - 2.0f * (zz + xx),
2.0f * (yz + wx),
0
);
- result.Z = new Vector4(
+ result.Z = Vector4.Create(
2.0f * (xz + wy),
2.0f * (yz - wx),
1.0f - 2.0f * (yy + xx),
@@ -433,25 +432,25 @@ public static Impl CreateLookTo(in Vector3 cameraPosition, in Vector3 cameraDire
Impl result;
- result.X = new Vector4(
+ result.X = Vector4.Create(
axisX.X,
axisY.X,
axisZ.X,
0
);
- result.Y = new Vector4(
+ result.Y = Vector4.Create(
axisX.Y,
axisY.Y,
axisZ.Y,
0
);
- result.Z = new Vector4(
+ result.Z = Vector4.Create(
axisX.Z,
axisY.Z,
axisZ.Z,
0
);
- result.W = new Vector4(
+ result.W = Vector4.Create(
Vector3.Dot(axisX, negativeCameraPosition),
Vector3.Dot(axisY, negativeCameraPosition),
Vector3.Dot(axisZ, negativeCameraPosition),
@@ -471,25 +470,25 @@ public static Impl CreateLookToLeftHanded(in Vector3 cameraPosition, in Vector3
Impl result;
- result.X = new Vector4(
+ result.X = Vector4.Create(
axisX.X,
axisY.X,
axisZ.X,
0
);
- result.Y = new Vector4(
+ result.Y = Vector4.Create(
axisX.Y,
axisY.Y,
axisZ.Y,
0
);
- result.Z = new Vector4(
+ result.Z = Vector4.Create(
axisX.Z,
axisY.Z,
axisZ.Z,
0
);
- result.W = new Vector4(
+ result.W = Vector4.Create(
Vector3.Dot(axisX, negativeCameraPosition),
Vector3.Dot(axisY, negativeCameraPosition),
Vector3.Dot(axisZ, negativeCameraPosition),
@@ -506,10 +505,10 @@ public static Impl CreateOrthographic(float width, float height, float zNearPlan
Impl result;
- result.X = new Vector4(2.0f / width, 0, 0, 0);
- result.Y = new Vector4(0, 2.0f / height, 0, 0);
- result.Z = new Vector4(0, 0, range, 0);
- result.W = new Vector4(0, 0, range * zNearPlane, 1);
+ result.X = Vector4.Create(2.0f / width, 0, 0, 0);
+ result.Y = Vector4.Create(0, 2.0f / height, 0, 0);
+ result.Z = Vector4.Create(0, 0, range, 0);
+ result.W = Vector4.Create(0, 0, range * zNearPlane, 1);
return result;
}
@@ -521,10 +520,10 @@ public static Impl CreateOrthographicLeftHanded(float width, float height, float
Impl result;
- result.X = new Vector4(2.0f / width, 0, 0, 0);
- result.Y = new Vector4(0, 2.0f / height, 0, 0);
- result.Z = new Vector4(0, 0, range, 0);
- result.W = new Vector4(0, 0, -range * zNearPlane, 1);
+ result.X = Vector4.Create(2.0f / width, 0, 0, 0);
+ result.Y = Vector4.Create(0, 2.0f / height, 0, 0);
+ result.Z = Vector4.Create(0, 0, range, 0);
+ result.W = Vector4.Create(0, 0, -range * zNearPlane, 1);
return result;
}
@@ -538,10 +537,10 @@ public static Impl CreateOrthographicOffCenter(float left, float right, float bo
Impl result;
- result.X = new Vector4(reciprocalWidth + reciprocalWidth, 0, 0, 0);
- result.Y = new Vector4(0, reciprocalHeight + reciprocalHeight, 0, 0);
- result.Z = new Vector4(0, 0, range, 0);
- result.W = new Vector4(
+ result.X = Vector4.Create(reciprocalWidth + reciprocalWidth, 0, 0, 0);
+ result.Y = Vector4.Create(0, reciprocalHeight + reciprocalHeight, 0, 0);
+ result.Z = Vector4.Create(0, 0, range, 0);
+ result.W = Vector4.Create(
-(left + right) * reciprocalWidth,
-(top + bottom) * reciprocalHeight,
range * zNearPlane,
@@ -560,10 +559,10 @@ public static Impl CreateOrthographicOffCenterLeftHanded(float left, float right
Impl result;
- result.X = new Vector4(reciprocalWidth + reciprocalWidth, 0, 0, 0);
- result.Y = new Vector4(0, reciprocalHeight + reciprocalHeight, 0, 0);
- result.Z = new Vector4(0, 0, range, 0);
- result.W = new Vector4(
+ result.X = Vector4.Create(reciprocalWidth + reciprocalWidth, 0, 0, 0);
+ result.Y = Vector4.Create(0, reciprocalHeight + reciprocalHeight, 0, 0);
+ result.Z = Vector4.Create(0, 0, range, 0);
+ result.W = Vector4.Create(
-(left + right) * reciprocalWidth,
-(top + bottom) * reciprocalHeight,
-range * zNearPlane,
@@ -585,10 +584,10 @@ public static Impl CreatePerspective(float width, float height, float nearPlaneD
Impl result;
- result.X = new Vector4(dblNearPlaneDistance / width, 0, 0, 0);
- result.Y = new Vector4(0, dblNearPlaneDistance / height, 0, 0);
- result.Z = new Vector4(0, 0, range, -1.0f);
- result.W = new Vector4(0, 0, range * nearPlaneDistance, 0);
+ result.X = Vector4.Create(dblNearPlaneDistance / width, 0, 0, 0);
+ result.Y = Vector4.Create(0, dblNearPlaneDistance / height, 0, 0);
+ result.Z = Vector4.Create(0, 0, range, -1.0f);
+ result.W = Vector4.Create(0, 0, range * nearPlaneDistance, 0);
return result;
}
@@ -605,10 +604,10 @@ public static Impl CreatePerspectiveLeftHanded(float width, float height, float
Impl result;
- result.X = new Vector4(dblNearPlaneDistance / width, 0, 0, 0);
- result.Y = new Vector4(0, dblNearPlaneDistance / height, 0, 0);
- result.Z = new Vector4(0, 0, range, 1.0f);
- result.W = new Vector4(0, 0, -range * nearPlaneDistance, 0);
+ result.X = Vector4.Create(dblNearPlaneDistance / width, 0, 0, 0);
+ result.Y = Vector4.Create(0, dblNearPlaneDistance / height, 0, 0);
+ result.Z = Vector4.Create(0, 0, range, 1.0f);
+ result.W = Vector4.Create(0, 0, -range * nearPlaneDistance, 0);
return result;
}
@@ -623,16 +622,16 @@ public static Impl CreatePerspectiveFieldOfView(float fieldOfView, float aspectR
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(farPlaneDistance, 0.0f);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(nearPlaneDistance, farPlaneDistance);
- float height = 1.0f / MathF.Tan(fieldOfView * 0.5f);
+ float height = 1.0f / float.Tan(fieldOfView * 0.5f);
float width = height / aspectRatio;
float range = float.IsPositiveInfinity(farPlaneDistance) ? -1.0f : farPlaneDistance / (nearPlaneDistance - farPlaneDistance);
Impl result;
- result.X = new Vector4(width, 0, 0, 0);
- result.Y = new Vector4(0, height, 0, 0);
- result.Z = new Vector4(0, 0, range, -1.0f);
- result.W = new Vector4(0, 0, range * nearPlaneDistance, 0);
+ result.X = Vector4.Create(width, 0, 0, 0);
+ result.Y = Vector4.Create(0, height, 0, 0);
+ result.Z = Vector4.Create(0, 0, range, -1.0f);
+ result.W = Vector4.Create(0, 0, range * nearPlaneDistance, 0);
return result;
}
@@ -647,16 +646,16 @@ public static Impl CreatePerspectiveFieldOfViewLeftHanded(float fieldOfView, flo
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(farPlaneDistance, 0.0f);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(nearPlaneDistance, farPlaneDistance);
- float height = 1.0f / MathF.Tan(fieldOfView * 0.5f);
+ float height = 1.0f / float.Tan(fieldOfView * 0.5f);
float width = height / aspectRatio;
float range = float.IsPositiveInfinity(farPlaneDistance) ? 1.0f : farPlaneDistance / (farPlaneDistance - nearPlaneDistance);
Impl result;
- result.X = new Vector4(width, 0, 0, 0);
- result.Y = new Vector4(0, height, 0, 0);
- result.Z = new Vector4(0, 0, range, 1.0f);
- result.W = new Vector4(0, 0, -range * nearPlaneDistance, 0);
+ result.X = Vector4.Create(width, 0, 0, 0);
+ result.Y = Vector4.Create(0, height, 0, 0);
+ result.Z = Vector4.Create(0, 0, range, 1.0f);
+ result.W = Vector4.Create(0, 0, -range * nearPlaneDistance, 0);
return result;
}
@@ -675,15 +674,15 @@ public static Impl CreatePerspectiveOffCenter(float left, float right, float bot
Impl result;
- result.X = new Vector4(dblNearPlaneDistance * reciprocalWidth, 0, 0, 0);
- result.Y = new Vector4(0, dblNearPlaneDistance * reciprocalHeight, 0, 0);
- result.Z = new Vector4(
+ result.X = Vector4.Create(dblNearPlaneDistance * reciprocalWidth, 0, 0, 0);
+ result.Y = Vector4.Create(0, dblNearPlaneDistance * reciprocalHeight, 0, 0);
+ result.Z = Vector4.Create(
(left + right) * reciprocalWidth,
(top + bottom) * reciprocalHeight,
range,
-1.0f
);
- result.W = new Vector4(0, 0, range * nearPlaneDistance, 0);
+ result.W = Vector4.Create(0, 0, range * nearPlaneDistance, 0);
return result;
}
@@ -702,15 +701,15 @@ public static Impl CreatePerspectiveOffCenterLeftHanded(float left, float right,
Impl result;
- result.X = new Vector4(dblNearPlaneDistance * reciprocalWidth, 0, 0, 0);
- result.Y = new Vector4(0, dblNearPlaneDistance * reciprocalHeight, 0, 0);
- result.Z = new Vector4(
+ result.X = Vector4.Create(dblNearPlaneDistance * reciprocalWidth, 0, 0, 0);
+ result.Y = Vector4.Create(0, dblNearPlaneDistance * reciprocalHeight, 0, 0);
+ result.Z = Vector4.Create(
-(left + right) * reciprocalWidth,
-(top + bottom) * reciprocalHeight,
range,
1.0f
);
- result.W = new Vector4(0, 0, -range * nearPlaneDistance, 0);
+ result.W = Vector4.Create(0, 0, -range * nearPlaneDistance, 0);
return result;
}
@@ -723,10 +722,10 @@ public static Impl CreateReflection(in Plane value)
Impl result;
- result.X = new Vector4(f * p.Normal.X, 0) + Vector4.UnitX;
- result.Y = new Vector4(f * p.Normal.Y, 0) + Vector4.UnitY;
- result.Z = new Vector4(f * p.Normal.Z, 0) + Vector4.UnitZ;
- result.W = new Vector4(f * p.D, 1);
+ result.X = (f * p.Normal.X).AsVector4() + Vector4.UnitX;
+ result.Y = (f * p.Normal.Y).AsVector4() + Vector4.UnitY;
+ result.Z = (f * p.Normal.Z).AsVector4() + Vector4.UnitZ;
+ result.W = Vector4.Create(f * p.D, 1);
return result;
}
@@ -734,8 +733,7 @@ public static Impl CreateReflection(in Plane value)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateRotationX(float radians)
{
- float c = MathF.Cos(radians);
- float s = MathF.Sin(radians);
+ (float s, float c) = float.SinCos(radians);
// [ 1 0 0 0 ]
// [ 0 c s 0 ]
@@ -745,8 +743,8 @@ public static Impl CreateRotationX(float radians)
Impl result;
result.X = Vector4.UnitX;
- result.Y = new Vector4(0, c, s, 0);
- result.Z = new Vector4(0, -s, c, 0);
+ result.Y = Vector4.Create(0, c, s, 0);
+ result.Z = Vector4.Create(0, -s, c, 0);
result.W = Vector4.UnitW;
return result;
@@ -755,8 +753,7 @@ public static Impl CreateRotationX(float radians)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateRotationX(float radians, in Vector3 centerPoint)
{
- float c = MathF.Cos(radians);
- float s = MathF.Sin(radians);
+ (float s, float c) = float.SinCos(radians);
float y = centerPoint.Y * (1 - c) + centerPoint.Z * s;
float z = centerPoint.Z * (1 - c) - centerPoint.Y * s;
@@ -769,9 +766,9 @@ public static Impl CreateRotationX(float radians, in Vector3 centerPoint)
Impl result;
result.X = Vector4.UnitX;
- result.Y = new Vector4(0, c, s, 0);
- result.Z = new Vector4(0, -s, c, 0);
- result.W = new Vector4(0, y, z, 1);
+ result.Y = Vector4.Create(0, c, s, 0);
+ result.Z = Vector4.Create(0, -s, c, 0);
+ result.W = Vector4.Create(0, y, z, 1);
return result;
}
@@ -779,8 +776,7 @@ public static Impl CreateRotationX(float radians, in Vector3 centerPoint)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateRotationY(float radians)
{
- float c = MathF.Cos(radians);
- float s = MathF.Sin(radians);
+ (float s, float c) = float.SinCos(radians);
// [ c 0 -s 0 ]
// [ 0 1 0 0 ]
@@ -789,9 +785,9 @@ public static Impl CreateRotationY(float radians)
Impl result;
- result.X = new Vector4(c, 0, -s, 0);
+ result.X = Vector4.Create(c, 0, -s, 0);
result.Y = Vector4.UnitY;
- result.Z = new Vector4(s, 0, c, 0);
+ result.Z = Vector4.Create(s, 0, c, 0);
result.W = Vector4.UnitW;
return result;
@@ -800,8 +796,7 @@ public static Impl CreateRotationY(float radians)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateRotationY(float radians, in Vector3 centerPoint)
{
- float c = MathF.Cos(radians);
- float s = MathF.Sin(radians);
+ (float s, float c) = float.SinCos(radians);
float x = centerPoint.X * (1 - c) - centerPoint.Z * s;
float z = centerPoint.Z * (1 - c) + centerPoint.X * s;
@@ -813,10 +808,10 @@ public static Impl CreateRotationY(float radians, in Vector3 centerPoint)
Impl result;
- result.X = new Vector4(c, 0, -s, 0);
+ result.X = Vector4.Create(c, 0, -s, 0);
result.Y = Vector4.UnitY;
- result.Z = new Vector4(s, 0, c, 0);
- result.W = new Vector4(x, 0, z, 1);
+ result.Z = Vector4.Create(s, 0, c, 0);
+ result.W = Vector4.Create(x, 0, z, 1);
return result;
}
@@ -824,9 +819,7 @@ public static Impl CreateRotationY(float radians, in Vector3 centerPoint)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateRotationZ(float radians)
{
-
- float c = MathF.Cos(radians);
- float s = MathF.Sin(radians);
+ (float s, float c) = float.SinCos(radians);
// [ c s 0 0 ]
// [ -s c 0 0 ]
@@ -835,8 +828,8 @@ public static Impl CreateRotationZ(float radians)
Impl result;
- result.X = new Vector4( c, s, 0, 0);
- result.Y = new Vector4(-s, c, 0, 0);
+ result.X = Vector4.Create( c, s, 0, 0);
+ result.Y = Vector4.Create(-s, c, 0, 0);
result.Z = Vector4.UnitZ;
result.W = Vector4.UnitW;
@@ -846,8 +839,7 @@ public static Impl CreateRotationZ(float radians)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Impl CreateRotationZ(float radians, in Vector3 centerPoint)
{
- float c = MathF.Cos(radians);
- float s = MathF.Sin(radians);
+ (float s, float c) = float.SinCos(radians);
float x = centerPoint.X * (1 - c) + centerPoint.Y * s;
float y = centerPoint.Y * (1 - c) - centerPoint.X * s;
@@ -859,10 +851,10 @@ public static Impl CreateRotationZ(float radians, in Vector3 centerPoint)
Impl result;
- result.X = new Vector4( c, s, 0, 0);
- result.Y = new Vector4(-s, c, 0, 0);
+ result.X = Vector4.Create( c, s, 0, 0);
+ result.Y = Vector4.Create(-s, c, 0, 0);
result.Z = Vector4.UnitZ;
- result.W = new Vector4(x, y, 0, 1);
+ result.W = Vector4.Create(x, y, 0, 1);
return result;
}
@@ -872,9 +864,9 @@ public static Impl CreateScale(float scaleX, float scaleY, float scaleZ)
{
Impl result;
- result.X = new Vector4(scaleX, 0, 0, 0);
- result.Y = new Vector4(0, scaleY, 0, 0);
- result.Z = new Vector4(0, 0, scaleZ, 0);
+ result.X = Vector4.Create(scaleX, 0, 0, 0);
+ result.Y = Vector4.Create(0, scaleY, 0, 0);
+ result.Z = Vector4.Create(0, 0, scaleZ, 0);
result.W = Vector4.UnitW;
return result;
@@ -885,10 +877,10 @@ public static Impl CreateScale(float scaleX, float scaleY, float scaleZ, in Vect
{
Impl result;
- result.X = new Vector4(scaleX, 0, 0, 0);
- result.Y = new Vector4(0, scaleY, 0, 0);
- result.Z = new Vector4(0, 0, scaleZ, 0);
- result.W = new Vector4(centerPoint * (Vector3.One - new Vector3(scaleX, scaleY, scaleZ)), 1);
+ result.X = Vector4.Create(scaleX, 0, 0, 0);
+ result.Y = Vector4.Create(0, scaleY, 0, 0);
+ result.Z = Vector4.Create(0, 0, scaleZ, 0);
+ result.W = Vector4.Create(centerPoint * (Vector3.One - Vector3.Create(scaleX, scaleY, scaleZ)), 1);
return result;
}
@@ -898,9 +890,9 @@ public static Impl CreateScale(in Vector3 scales)
{
Impl result;
- result.X = new Vector4(scales.X, 0, 0, 0);
- result.Y = new Vector4(0, scales.Y, 0, 0);
- result.Z = new Vector4(0, 0, scales.Z, 0);
+ result.X = Vector4.Create(scales.X, 0, 0, 0);
+ result.Y = Vector4.Create(0, scales.Y, 0, 0);
+ result.Z = Vector4.Create(0, 0, scales.Z, 0);
result.W = Vector4.UnitW;
return result;
@@ -911,10 +903,10 @@ public static Impl CreateScale(in Vector3 scales, in Vector3 centerPoint)
{
Impl result;
- result.X = new Vector4(scales.X, 0, 0, 0);
- result.Y = new Vector4(0, scales.Y, 0, 0);
- result.Z = new Vector4(0, 0, scales.Z, 0);
- result.W = new Vector4(centerPoint * (Vector3.One - scales), 1);
+ result.X = Vector4.Create(scales.X, 0, 0, 0);
+ result.Y = Vector4.Create(0, scales.Y, 0, 0);
+ result.Z = Vector4.Create(0, 0, scales.Z, 0);
+ result.W = Vector4.Create(centerPoint * (Vector3.One - scales), 1);
return result;
}
@@ -924,9 +916,9 @@ public static Impl CreateScale(float scale)
{
Impl result;
- result.X = new Vector4(scale, 0, 0, 0);
- result.Y = new Vector4(0, scale, 0, 0);
- result.Z = new Vector4(0, 0, scale, 0);
+ result.X = Vector4.Create(scale, 0, 0, 0);
+ result.Y = Vector4.Create(0, scale, 0, 0);
+ result.Z = Vector4.Create(0, 0, scale, 0);
result.W = Vector4.UnitW;
return result;
@@ -937,10 +929,10 @@ public static Impl CreateScale(float scale, in Vector3 centerPoint)
{
Impl result;
- result.X = new Vector4(scale, 0, 0, 0);
- result.Y = new Vector4(0, scale, 0, 0);
- result.Z = new Vector4(0, 0, scale, 0);
- result.W = new Vector4(centerPoint * (Vector3.One - new Vector3(scale)), 1);
+ result.X = Vector4.Create(scale, 0, 0, 0);
+ result.Y = Vector4.Create(0, scale, 0, 0);
+ result.Z = Vector4.Create(0, 0, scale, 0);
+ result.W = Vector4.Create(centerPoint * (Vector3.One - Vector3.Create(scale)), 1);
return result;
}
@@ -955,10 +947,10 @@ public static Impl CreateShadow(in Vector3 lightDirection, in Plane plane)
Impl result;
- result.X = new Vector4(lightDirection * normal.X, 0) + new Vector4(dot, 0, 0, 0);
- result.Y = new Vector4(lightDirection * normal.Y, 0) + new Vector4(0, dot, 0, 0);
- result.Z = new Vector4(lightDirection * normal.Z, 0) + new Vector4(0, 0, dot, 0);
- result.W = new Vector4(lightDirection * -p.D, dot);
+ result.X = (lightDirection * normal.X).AsVector4() + Vector4.CreateScalar(dot);
+ result.Y = (lightDirection * normal.Y).AsVector4() + Vector4.Create(0, dot, 0, 0);
+ result.Z = (lightDirection * normal.Z).AsVector4() + Vector4.Create(0, 0, dot, 0);
+ result.W = Vector4.Create(lightDirection * -p.D, dot);
return result;
}
@@ -971,7 +963,7 @@ public static Impl CreateTranslation(in Vector3 position)
result.X = Vector4.UnitX;
result.Y = Vector4.UnitY;
result.Z = Vector4.UnitZ;
- result.W = new Vector4(position, 1);
+ result.W = Vector4.Create(position, 1);
return result;
}
@@ -984,7 +976,7 @@ public static Impl CreateTranslation(float positionX, float positionY, float pos
result.X = Vector4.UnitX;
result.Y = Vector4.UnitY;
result.Z = Vector4.UnitZ;
- result.W = new Vector4(positionX, positionY, positionZ, 1);
+ result.W = Vector4.Create(positionX, positionY, positionZ, 1);
return result;
}
@@ -996,13 +988,13 @@ public static Impl CreateViewport(float x, float y, float width, float height, f
Impl result;
// 4x SIMD fields to get a lot better codegen
- result.W = new Vector4(width, height, 0f, 0f);
- result.W *= new Vector4(0.5f, 0.5f, 0f, 0f);
+ result.W = Vector4.Create(width, height, 0f, 0f);
+ result.W *= Vector4.Create(0.5f, 0.5f, 0f, 0f);
- result.X = new Vector4(result.W.X, 0f, 0f, 0f);
- result.Y = new Vector4(0f, -result.W.Y, 0f, 0f);
- result.Z = new Vector4(0f, 0f, minDepth - maxDepth, 0f);
- result.W += new Vector4(x, y, minDepth, 1f);
+ result.X = Vector4.Create(result.W.X, 0f, 0f, 0f);
+ result.Y = Vector4.Create(0f, -result.W.Y, 0f, 0f);
+ result.Z = Vector4.Create(0f, 0f, minDepth - maxDepth, 0f);
+ result.W += Vector4.Create(x, y, minDepth, 1f);
return result;
}
@@ -1013,13 +1005,13 @@ public static Impl CreateViewportLeftHanded(float x, float y, float width, float
Impl result;
// 4x SIMD fields to get a lot better codegen
- result.W = new Vector4(width, height, 0f, 0f);
- result.W *= new Vector4(0.5f, 0.5f, 0f, 0f);
+ result.W = Vector4.Create(width, height, 0f, 0f);
+ result.W *= Vector4.Create(0.5f, 0.5f, 0f, 0f);
- result.X = new Vector4(result.W.X, 0f, 0f, 0f);
- result.Y = new Vector4(0f, -result.W.Y, 0f, 0f);
- result.Z = new Vector4(0f, 0f, maxDepth - minDepth, 0f);
- result.W += new Vector4(x, y, minDepth, 1f);
+ result.X = Vector4.Create(result.W.X, 0f, 0f, 0f);
+ result.Y = Vector4.Create(0f, -result.W.Y, 0f, 0f);
+ result.Z = Vector4.Create(0f, 0f, maxDepth - minDepth, 0f);
+ result.W += Vector4.Create(x, y, minDepth, 1f);
return result;
}
@@ -1033,10 +1025,10 @@ public static Impl CreateWorld(in Vector3 position, in Vector3 forward, in Vecto
Impl result;
- result.X = new Vector4(axisX, 0);
- result.Y = new Vector4(axisY, 0);
- result.Z = new Vector4(axisZ, 0);
- result.W = new Vector4(position, 1);
+ result.X = axisX.AsVector4();
+ result.Y = axisY.AsVector4();
+ result.Z = axisZ.AsVector4();
+ result.W = Vector4.Create(position, 1);
return result;
}
@@ -1058,22 +1050,19 @@ public static unsafe bool Decompose(in Impl matrix, out Vector3 scale, out Quate
CanonicalBasis canonicalBasis = default;
Vector3* pCanonicalBasis = &canonicalBasis.Row0;
- canonicalBasis.Row0 = new Vector3(1.0f, 0.0f, 0.0f);
- canonicalBasis.Row1 = new Vector3(0.0f, 1.0f, 0.0f);
- canonicalBasis.Row2 = new Vector3(0.0f, 0.0f, 1.0f);
+ canonicalBasis.Row0 = Vector3.UnitX;
+ canonicalBasis.Row1 = Vector3.UnitY;
+ canonicalBasis.Row2 = Vector3.UnitZ;
- translation = new Vector3(
- matrix.W.X,
- matrix.W.Y,
- matrix.W.Z);
+ translation = matrix.W.AsVector3();
pVectorBasis[0] = (Vector3*)&matTemp.X;
pVectorBasis[1] = (Vector3*)&matTemp.Y;
pVectorBasis[2] = (Vector3*)&matTemp.Z;
- *(pVectorBasis[0]) = new Vector3(matrix.X.X, matrix.X.Y, matrix.X.Z);
- *(pVectorBasis[1]) = new Vector3(matrix.Y.X, matrix.Y.Y, matrix.Y.Z);
- *(pVectorBasis[2]) = new Vector3(matrix.Z.X, matrix.Z.Y, matrix.Z.Z);
+ *(pVectorBasis[0]) = matrix.X.AsVector3();
+ *(pVectorBasis[1]) = matrix.Y.AsVector3();
+ *(pVectorBasis[2]) = matrix.Z.AsVector3();
scale.X = pVectorBasis[0]->Length();
scale.Y = pVectorBasis[1]->Length();
@@ -1148,9 +1137,9 @@ public static unsafe bool Decompose(in Impl matrix, out Vector3 scale, out Quate
uint cc;
float fAbsX, fAbsY, fAbsZ;
- fAbsX = MathF.Abs(pVectorBasis[a]->X);
- fAbsY = MathF.Abs(pVectorBasis[a]->Y);
- fAbsZ = MathF.Abs(pVectorBasis[a]->Z);
+ fAbsX = float.Abs(pVectorBasis[a]->X);
+ fAbsY = float.Abs(pVectorBasis[a]->Y);
+ fAbsZ = float.Abs(pVectorBasis[a]->Z);
#region Ranking
if (fAbsX < fAbsY)
@@ -1387,9 +1376,9 @@ static bool SseImpl(in Impl matrix, out Impl result)
float det = Vector4.Dot(C0.AsVector4(), row1.AsVector4());
// Check determinate is not zero
- if (MathF.Abs(det) < float.Epsilon)
+ if (float.Abs(det) < float.Epsilon)
{
- Vector4 vNaN = new Vector4(float.NaN);
+ Vector4 vNaN = Vector4.Create(float.NaN);
result.X = vNaN;
result.Y = vNaN;
@@ -1546,9 +1535,9 @@ static bool SoftwareFallback(in Impl matrix, out Impl result)
float det = a * a11 + b * a12 + c * a13 + d * a14;
- if (MathF.Abs(det) < float.Epsilon)
+ if (float.Abs(det) < float.Epsilon)
{
- Vector4 vNaN = new Vector4(float.NaN);
+ Vector4 vNaN = Vector4.Create(float.NaN);
result.X = vNaN;
result.Y = vNaN;
@@ -1645,25 +1634,25 @@ public static Impl Transform(in Impl value, in Quaternion rotation)
Impl result;
- result.X = new Vector4(
+ result.X = Vector4.Create(
value.X.X * q11 + value.X.Y * q21 + value.X.Z * q31,
value.X.X * q12 + value.X.Y * q22 + value.X.Z * q32,
value.X.X * q13 + value.X.Y * q23 + value.X.Z * q33,
value.X.W
);
- result.Y = new Vector4(
+ result.Y = Vector4.Create(
value.Y.X * q11 + value.Y.Y * q21 + value.Y.Z * q31,
value.Y.X * q12 + value.Y.Y * q22 + value.Y.Z * q32,
value.Y.X * q13 + value.Y.Y * q23 + value.Y.Z * q33,
value.Y.W
);
- result.Z = new Vector4(
+ result.Z = Vector4.Create(
value.Z.X * q11 + value.Z.Y * q21 + value.Z.Z * q31,
value.Z.X * q12 + value.Z.Y * q22 + value.Z.Z * q32,
value.Z.X * q13 + value.Z.Y * q23 + value.Z.Z * q33,
value.Z.W
);
- result.W = new Vector4(
+ result.W = Vector4.Create(
value.W.X * q11 + value.W.Y * q21 + value.W.Z * q31,
value.W.X * q12 + value.W.Y * q22 + value.W.Z * q32,
value.W.X * q13 + value.W.Y * q23 + value.W.Z * q33,
@@ -1717,10 +1706,10 @@ public static Impl Transpose(in Impl matrix)
}
else
{
- result.X = new Vector4(matrix.X.X, matrix.Y.X, matrix.Z.X, matrix.W.X);
- result.Y = new Vector4(matrix.X.Y, matrix.Y.Y, matrix.Z.Y, matrix.W.Y);
- result.Z = new Vector4(matrix.X.Z, matrix.Y.Z, matrix.Z.Z, matrix.W.Z);
- result.W = new Vector4(matrix.X.W, matrix.Y.W, matrix.Z.W, matrix.W.W);
+ result.X = Vector4.Create(matrix.X.X, matrix.Y.X, matrix.Z.X, matrix.W.X);
+ result.Y = Vector4.Create(matrix.X.Y, matrix.Y.Y, matrix.Z.Y, matrix.W.Y);
+ result.Z = Vector4.Create(matrix.X.Z, matrix.Y.Z, matrix.Z.Z, matrix.W.Z);
+ result.W = Vector4.Create(matrix.X.W, matrix.Y.W, matrix.Z.W, matrix.W.W);
}
return result;
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs
index 3834877ae44a8..55404a6008455 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs
@@ -380,7 +380,7 @@ public static Matrix4x4 CreatePerspectiveLeftHanded(float width, float height, f
/// The right-handed perspective projection matrix.
/// is less than or equal to zero.
/// -or-
- /// is greater than or equal to .
+ /// is greater than or equal to .
/// is less than or equal to zero.
/// -or-
/// is less than or equal to zero.
@@ -397,7 +397,7 @@ public static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float as
/// The left-handed perspective projection matrix.
/// is less than or equal to zero.
/// -or-
- /// is greater than or equal to .
+ /// is greater than or equal to .
/// is less than or equal to zero.
/// -or-
/// is less than or equal to zero.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs
new file mode 100644
index 0000000000000..867e4d15222e6
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs
@@ -0,0 +1,25 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics;
+
+namespace System.Numerics
+{
+ public static unsafe partial class Vector
+ {
+ /// Reinterprets a as a new .
+ /// The plane to reinterpret.
+ /// reinterpreted as a new .
+ [Intrinsic]
+ public static Vector4 AsVector4(this Plane value)
+ {
+#if MONO
+ return Unsafe.As(ref value);
+#else
+ return Unsafe.BitCast(value);
+#endif
+ }
+ }
+}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.cs
index 09d19a137f917..55f4522800316 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.cs
@@ -30,7 +30,7 @@ public struct Plane : IEquatable
[Intrinsic]
public Plane(float x, float y, float z, float d)
{
- this = Vector128.Create(x, y, z, d).AsPlane();
+ this = Create(x, y, z, d);
}
/// Creates a object from a specified normal and the distance along the normal from the origin.
@@ -39,7 +39,7 @@ public Plane(float x, float y, float z, float d)
[Intrinsic]
public Plane(Vector3 normal, float d)
{
- this = new Vector4(normal, d).AsPlane();
+ this = Create(normal, d);
}
/// Creates a object from a specified four-dimensional vector.
@@ -50,6 +50,22 @@ public Plane(Vector4 value)
this = value.AsPlane();
}
+ /// Creates a object from the X, Y, and Z components of its normal, and its distance from the origin on that normal.
+ /// The X component of the normal.
+ /// The Y component of the normal.
+ /// The Z component of the normal.
+ /// The distance of the plane along its normal from the origin.
+ /// A new object from the X, Y, and Z components of its normal, and its distance from the origin on that normal.
+ [Intrinsic]
+ internal static Plane Create(float x, float y, float z, float d) => Vector128.Create(x, y, z, d).AsPlane();
+
+ /// Creates a object from a specified normal and the distance along the normal from the origin.
+ /// The plane's normal vector.
+ /// The plane's distance from the origin along its normal vector.\
+ /// A new object from a specified normal and the distance along the normal from the origin.
+ [Intrinsic]
+ internal static Plane Create(Vector3 normal, float d) => Vector4.Create(normal, d).AsPlane();
+
/// Creates a object that contains three specified points.
/// The first point defining the plane.
/// The second point defining the plane.
@@ -70,7 +86,7 @@ public static Plane CreateFromVertices(Vector3 point1, Vector3 point2, Vector3 p
// D = - Dot(N, point1)
float d = -Vector3.Dot(normal, point1);
- return new Plane(normal, d);
+ return Create(normal, d);
}
else
{
@@ -89,16 +105,17 @@ public static Plane CreateFromVertices(Vector3 point1, Vector3 point2, Vector3 p
// Normalize(N)
float ls = nx * nx + ny * ny + nz * nz;
- float invNorm = 1.0f / MathF.Sqrt(ls);
+ float invNorm = 1.0f / float.Sqrt(ls);
- Vector3 normal = new Vector3(
+ Vector3 normal = Vector3.Create(
nx * invNorm,
ny * invNorm,
nz * invNorm);
- return new Plane(
+ return Create(
normal,
- -(normal.X * point1.X + normal.Y * point1.Y + normal.Z * point1.Z));
+ -(normal.X * point1.X + normal.Y * point1.Y + normal.Z * point1.Z)
+ );
}
}
@@ -130,13 +147,13 @@ public static Plane Normalize(Plane value)
{
float normalLengthSquared = value.Normal.LengthSquared();
- if (MathF.Abs(normalLengthSquared - 1.0f) < NormalizeEpsilon)
+ if (float.Abs(normalLengthSquared - 1.0f) < NormalizeEpsilon)
{
// It already normalized, so we don't need to farther process.
return value;
}
- return (value.AsVector128() / MathF.Sqrt(normalLengthSquared)).AsPlane();
+ return (value.AsVector128() / float.Sqrt(normalLengthSquared)).AsPlane();
}
/// Transforms a normalized plane by a 4x4 matrix.
@@ -151,11 +168,12 @@ public static Plane Transform(Plane plane, Matrix4x4 matrix)
float x = plane.Normal.X, y = plane.Normal.Y, z = plane.Normal.Z, w = plane.D;
- return new Plane(
+ return Create(
x * m.M11 + y * m.M12 + z * m.M13 + w * m.M14,
x * m.M21 + y * m.M22 + z * m.M23 + w * m.M24,
x * m.M31 + y * m.M32 + z * m.M33 + w * m.M34,
- x * m.M41 + y * m.M42 + z * m.M43 + w * m.M44);
+ x * m.M41 + y * m.M42 + z * m.M43 + w * m.M44
+ );
}
/// Transforms a normalized plane by a Quaternion rotation.
@@ -195,11 +213,12 @@ public static Plane Transform(Plane plane, Quaternion rotation)
float x = plane.Normal.X, y = plane.Normal.Y, z = plane.Normal.Z;
- return new Plane(
+ return Create(
x * m11 + y * m21 + z * m31,
x * m12 + y * m22 + z * m32,
x * m13 + y * m23 + z * m33,
- plane.D);
+ plane.D
+ );
}
/// Returns a value that indicates whether two planes are equal.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs
index 42ac2e3d0dfc3..b42487e3f6303 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs
@@ -9,43 +9,17 @@ namespace System.Numerics
{
public static unsafe partial class Vector
{
- /// Gets the element at the specified index.
- /// The quaternion to get the element from.
- /// The index of the element to get.
- /// The value of the element at .
- /// was less than zero or greater than the number of elements.
+ /// Reinterprets a as a new .
+ /// The quaternion to reinterpret.
+ /// reinterpreted as a new .
[Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static float GetElement(this Quaternion quaternion, int index)
+ public static Vector4 AsVector4(this Quaternion value)
{
- return quaternion.AsVector128().GetElement(index);
- }
-
- /// Creates a new with the element at the specified index set to the specified value and the remaining elements set to the same value as that in the given quaternion.
- /// The quaternion to get the remaining elements from.
- /// The index of the element to set.
- /// The value to set the element to.
- /// A with the value of the element at set to and the remaining elements set to the same value as that in .
- /// was less than zero or greater than the number of elements.
- [Intrinsic]
- internal static Quaternion WithElement(this Quaternion quaternion, int index, float value)
- {
- return quaternion.AsVector128().WithElement(index, value).AsQuaternion();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static float GetElementUnsafe(in this Quaternion quaternion, int index)
- {
- Debug.Assert((index >= 0) && (index < Quaternion.Count));
- ref float address = ref Unsafe.AsRef(in quaternion.X);
- return Unsafe.Add(ref address, index);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void SetElementUnsafe(ref this Quaternion quaternion, int index, float value)
- {
- Debug.Assert((index >= 0) && (index < Quaternion.Count));
- Unsafe.Add(ref quaternion.X, index) = value;
+#if MONO
+ return Unsafe.As(ref value);
+#else
+ return Unsafe.BitCast(value);
+#endif
}
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.cs
index 4ec7f536ed43f..b14a70e68106b 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.cs
@@ -38,7 +38,7 @@ public struct Quaternion : IEquatable
[Intrinsic]
public Quaternion(float x, float y, float z, float w)
{
- this = Vector128.Create(x, y, z, w).AsQuaternion();
+ this = Create(x, y, z, w);
}
/// Creates a quaternion from the specified vector and rotation parts.
@@ -47,7 +47,7 @@ public Quaternion(float x, float y, float z, float w)
[Intrinsic]
public Quaternion(Vector3 vectorPart, float scalarPart)
{
- this = new Vector4(vectorPart, scalarPart).AsQuaternion();
+ this = Create(vectorPart, scalarPart);
}
/// Gets a quaternion that represents a zero.
@@ -63,7 +63,7 @@ public static Quaternion Zero
public static Quaternion Identity
{
[Intrinsic]
- get => new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
+ get => Create(0.0f, 0.0f, 0.0f, 1.0f);
}
/// Gets or sets the element at the specified index.
@@ -73,9 +73,13 @@ public static Quaternion Identity
public float this[int index]
{
[Intrinsic]
- readonly get => this.GetElement(index);
+ readonly get => this.AsVector128().GetElement(index);
- set => this = this.WithElement(index, value);
+ [Intrinsic]
+ set
+ {
+ this = this.AsVector128().WithElement(index, value).AsQuaternion();
+ }
}
/// Gets a value that indicates whether the current instance is the identity quaternion.
@@ -161,10 +165,10 @@ public float this[int index]
{
if (Vector128.IsHardwareAccelerated)
{
- var left = value1.AsVector128();
- var right = value2.AsVector128();
+ Vector128 left = value1.AsVector128();
+ Vector128 right = value2.AsVector128();
- var result = right * left.GetElementUnsafe(3);
+ Vector128 result = right * left.GetElementUnsafe(3);
result += (Vector128.Shuffle(right, Vector128.Create(3, 2, 1, 0)) * left.GetElementUnsafe(0)) * Vector128.Create(+1.0f, -1.0f, +1.0f, -1.0f);
result += (Vector128.Shuffle(right, Vector128.Create(2, 3, 0, 1)) * left.GetElementUnsafe(1)) * Vector128.Create(+1.0f, +1.0f, -1.0f, -1.0f);
result += (Vector128.Shuffle(right, Vector128.Create(1, 0, 3, 2)) * left.GetElementUnsafe(2)) * Vector128.Create(-1.0f, +1.0f, +1.0f, -1.0f);
@@ -275,6 +279,22 @@ public static Quaternion Concatenate(Quaternion value1, Quaternion value2)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Conjugate(Quaternion value) => (value.AsVector128() * Vector128.Create(-1.0f, -1.0f, -1.0f, 1.0f)).AsQuaternion();
+ /// Creates a quaternion from the specified components.
+ /// The value to assign to the X component of the quaternion.
+ /// The value to assign to the Y component of the quaternion.
+ /// The value to assign to the Z component of the quaternion.
+ /// The value to assign to the W component of the quaternion.
+ /// A new quaternion created from the specified components.>
+ [Intrinsic]
+ internal static Quaternion Create(float x, float y, float z, float w) => Vector128.Create(x, y, z, w).AsQuaternion();
+
+ /// Creates a quaternion from the specified vector and rotation parts.
+ /// The vector part of the quaternion.
+ /// The rotation part of the quaternion.
+ /// A new quaternion created from the specified vector and rotation parts.
+ [Intrinsic]
+ internal static Quaternion Create(Vector3 vectorPart, float scalarPart) => Vector4.Create(vectorPart, scalarPart).AsQuaternion();
+
/// Creates a quaternion from a unit vector and an angle to rotate around the vector.
/// The unit vector to rotate around.
/// The angle, in radians, to rotate around the vector.
@@ -284,9 +304,7 @@ public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)
{
Quaternion ans;
- float halfAngle = angle * 0.5f;
- float s = MathF.Sin(halfAngle);
- float c = MathF.Cos(halfAngle);
+ (float s, float c) = float.SinCos(angle * 0.5f);
ans.X = axis.X * s;
ans.Y = axis.Y * s;
@@ -307,7 +325,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix)
if (trace > 0.0f)
{
- float s = MathF.Sqrt(trace + 1.0f);
+ float s = float.Sqrt(trace + 1.0f);
q.W = s * 0.5f;
s = 0.5f / s;
q.X = (matrix.M23 - matrix.M32) * s;
@@ -318,7 +336,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix)
{
if (matrix.M11 >= matrix.M22 && matrix.M11 >= matrix.M33)
{
- float s = MathF.Sqrt(1.0f + matrix.M11 - matrix.M22 - matrix.M33);
+ float s = float.Sqrt(1.0f + matrix.M11 - matrix.M22 - matrix.M33);
float invS = 0.5f / s;
q.X = 0.5f * s;
q.Y = (matrix.M12 + matrix.M21) * invS;
@@ -327,7 +345,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix)
}
else if (matrix.M22 > matrix.M33)
{
- float s = MathF.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33);
+ float s = float.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33);
float invS = 0.5f / s;
q.X = (matrix.M21 + matrix.M12) * invS;
q.Y = 0.5f * s;
@@ -336,7 +354,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix)
}
else
{
- float s = MathF.Sqrt(1.0f + matrix.M33 - matrix.M11 - matrix.M22);
+ float s = float.Sqrt(1.0f + matrix.M33 - matrix.M11 - matrix.M22);
float invS = 0.5f / s;
q.X = (matrix.M31 + matrix.M13) * invS;
q.Y = (matrix.M32 + matrix.M23) * invS;
@@ -357,19 +375,9 @@ public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float ro
{
// Roll first, about axis the object is facing, then
// pitch upward, then yaw to face into the new heading
- float sr, cr, sp, cp, sy, cy;
-
- float halfRoll = roll * 0.5f;
- sr = MathF.Sin(halfRoll);
- cr = MathF.Cos(halfRoll);
-
- float halfPitch = pitch * 0.5f;
- sp = MathF.Sin(halfPitch);
- cp = MathF.Cos(halfPitch);
-
- float halfYaw = yaw * 0.5f;
- sy = MathF.Sin(halfYaw);
- cy = MathF.Cos(halfYaw);
+ (float sr, float cr) = float.SinCos(roll * 0.5f);
+ (float sp, float cp) = float.SinCos(pitch * 0.5f);
+ (float sy, float cy) = float.SinCos(yaw * 0.5f);
Quaternion result;
@@ -441,7 +449,7 @@ public static Quaternion Lerp(Quaternion quaternion1, Quaternion quaternion2, fl
// Normalize it.
float ls = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
- float invNorm = 1.0f / MathF.Sqrt(ls);
+ float invNorm = 1.0f / float.Sqrt(ls);
r.X *= invNorm;
r.Y *= invNorm;
@@ -507,13 +515,13 @@ public static Quaternion Slerp(Quaternion quaternion1, Quaternion quaternion2, f
}
else
{
- float omega = MathF.Acos(cosOmega);
- float invSinOmega = 1 / MathF.Sin(omega);
+ float omega = float.Acos(cosOmega);
+ float invSinOmega = 1 / float.Sin(omega);
- s1 = MathF.Sin((1.0f - t) * omega) * invSinOmega;
+ s1 = float.Sin((1.0f - t) * omega) * invSinOmega;
s2 = (flip)
- ? -MathF.Sin(t * omega) * invSinOmega
- : MathF.Sin(t * omega) * invSinOmega;
+ ? -float.Sin(t * omega) * invSinOmega
+ : float.Sin(t * omega) * invSinOmega;
}
Quaternion ans;
@@ -553,7 +561,7 @@ public static Quaternion Slerp(Quaternion quaternion1, Quaternion quaternion2, f
/// Calculates the length of the quaternion.
/// The computed length of the quaternion.
[Intrinsic]
- public readonly float Length() => MathF.Sqrt(LengthSquared());
+ public readonly float Length() => float.Sqrt(LengthSquared());
/// Calculates the squared length of the quaternion.
/// The length squared of the quaternion.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs
index 536fd43e8cac7..0e8e2b6bf2bf6 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs
@@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
@@ -209,7 +210,7 @@ public static Vector As(this Vector vector)
/// Computes the ceiling of each element in a vector.
/// The vector that will have its ceiling computed.
/// A vector whose elements are the ceiling of the elements in .
- ///
+ ///
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector Ceiling(Vector value)
@@ -228,7 +229,7 @@ public static Vector Ceiling(Vector value)
/// Computes the ceiling of each element in a vector.
/// The vector that will have its ceiling computed.
/// A vector whose elements are the ceiling of the elements in .
- ///
+ ///
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector Ceiling(Vector value)
@@ -486,6 +487,72 @@ public static Vector ConvertToUInt64Native(Vector value)
return result;
}
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The type of the elements in the vector.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ /// The type of () is not supported.
+ [Intrinsic]
+ public static Vector Create(T value)
+ {
+ Unsafe.SkipInit(out Vector result);
+
+ for (int index = 0; index < Vector.Count; index++)
+ {
+ result.SetElementUnsafe(index, value);
+ }
+
+ return result;
+ }
+
+ /// Creates a new from a given readonly span.
+ /// The type of the elements in the vector.
+ /// The readonly span from which the vector is created.
+ /// A new with its elements set to the first elements from .
+ /// The length of is less than .
+ /// The type of () is not supported.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector Create(ReadOnlySpan values)
+ {
+ if (values.Length < Vector.Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values);
+ }
+ return Unsafe.ReadUnaligned>(ref Unsafe.As(ref MemoryMarshal.GetReference(values)));
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero.
+ /// The type of the elements in the vector.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ /// The type of () is not supported.
+ [Intrinsic]
+ internal static unsafe Vector CreateScalar(T value)
+ {
+ Vector result = Vector.Zero;
+ result.SetElementUnsafe(0, value);
+ return result;
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The type of the elements in the vector.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ /// The type of () is not supported.
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static Vector CreateScalarUnsafe(T value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ ThrowHelper.ThrowForUnsupportedNumericsVectorBaseType();
+ Unsafe.SkipInit(out Vector result);
+
+ result.SetElementUnsafe(0, value);
+ return result;
+ }
+
/// Creates a new instance where the elements begin at a specified value and which are spaced apart according to another specified value.
/// The type of the elements in the vector.
/// The value that element 0 will be initialized to.
@@ -493,7 +560,7 @@ public static Vector ConvertToUInt64Native(Vector value)
/// A new instance with the first element initialized to and each subsequent element initialized to the the value of the previous element plus .
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector CreateSequence(T start, T step) => (Vector.Indices * step) + new Vector(start);
+ public static Vector CreateSequence(T start, T step) => (Vector.Indices * step) + Create(start);
/// Divides two vectors to compute their quotient.
/// The vector that will be divided by .
@@ -598,7 +665,7 @@ public static bool EqualsAny(Vector left, Vector right)
/// Computes the floor of each element in a vector.
/// The vector that will have its floor computed.
/// A vector whose elements are the floor of the elements in .
- ///
+ ///
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector Floor(Vector value)
@@ -617,7 +684,7 @@ public static Vector Floor(Vector value)
/// Computes the floor of each element in a vector.
/// The vector that will have its floor computed.
/// A vector whose elements are the floor of the elements in .
- ///
+ ///
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector Floor(Vector value)
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.Extensions.cs
index 5b57163ecad5f..21e3defd777a4 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.Extensions.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.Extensions.cs
@@ -3,60 +3,22 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics;
namespace System.Numerics
{
public static unsafe partial class Vector
{
- /// Gets the element at the specified index.
- /// The vector to get the element from.
- /// The index of the element to get.
- /// The value of the element at .
- /// was less than zero or greater than the number of elements.
+ /// Reinterprets a to a new with the new elements zeroed.
+ /// The vector to reinterpret.
+ /// reinterpreted to a new with the new elements zeroed.
[Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static float GetElement(this Vector2 vector, int index)
- {
- if ((uint)(index) >= (uint)(Vector2.Count))
- {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
- }
+ public static Vector4 AsVector4(this Vector2 value) => value.AsVector128().AsVector4();
- return vector.GetElementUnsafe(index);
- }
-
- /// Creates a new with the element at the specified index set to the specified value and the remaining elements set to the same value as that in the given vector.
- /// The vector to get the remaining elements from.
- /// The index of the element to set.
- /// The value to set the element to.
- /// A with the value of the element at set to and the remaining elements set to the same value as that in .
- /// was less than zero or greater than the number of elements.
+ /// Reinterprets a to a new with the new elements undefined.
+ /// The vector to reinterpret.
+ /// reinterpreted to a new with the new elements undefined.
[Intrinsic]
- internal static Vector2 WithElement(this Vector2 vector, int index, float value)
- {
- if ((uint)(index) >= (uint)(Vector2.Count))
- {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
- }
-
- Vector2 result = vector;
- result.SetElementUnsafe(index, value);
- return result;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static float GetElementUnsafe(in this Vector2 vector, int index)
- {
- Debug.Assert((index >= 0) && (index < Vector2.Count));
- ref float address = ref Unsafe.AsRef(in vector.X);
- return Unsafe.Add(ref address, index);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void SetElementUnsafe(ref this Vector2 vector, int index, float value)
- {
- Debug.Assert((index >= 0) && (index < Vector2.Count));
- Unsafe.Add(ref vector.X, index) = value;
- }
+ public static Vector4 AsVector4Unsafe(this Vector2 value) => value.AsVector128Unsafe().AsVector4();
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs
index 931cbf5eca86b..7eb79bf3524a7 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs
@@ -28,8 +28,9 @@ public partial struct Vector2 : IEquatable, IFormattable
/// Creates a new object whose two elements have the same value.
/// The value to assign to both elements.
[Intrinsic]
- public Vector2(float value) : this(value, value)
+ public Vector2(float value)
{
+ this = Create(value);
}
/// Creates a vector whose elements have the specified values.
@@ -38,20 +39,15 @@ public Vector2(float value) : this(value, value)
[Intrinsic]
public Vector2(float x, float y)
{
- X = x;
- Y = y;
+ this = Create(x, y);
}
/// Constructs a vector from the given . The span must contain at least 2 elements.
/// The span of elements to assign to the vector.
+ [Intrinsic]
public Vector2(ReadOnlySpan values)
{
- if (values.Length < 2)
- {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values);
- }
-
- this = Unsafe.ReadUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(values)));
+ this = Create(values);
}
/// Returns a vector whose 2 elements are equal to zero.
@@ -67,7 +63,7 @@ public static Vector2 Zero
public static Vector2 One
{
[Intrinsic]
- get => new Vector2(1.0f);
+ get => Create(1.0f);
}
/// Gets the vector (1,0).
@@ -75,7 +71,7 @@ public static Vector2 One
public static Vector2 UnitX
{
[Intrinsic]
- get => new Vector2(1.0f, 0.0f);
+ get => CreateScalar(1.0f);
}
/// Gets the vector (0,1).
@@ -83,7 +79,7 @@ public static Vector2 UnitX
public static Vector2 UnitY
{
[Intrinsic]
- get => new Vector2(0.0f, 1.0f);
+ get => Create(0.0f, 1.0f);
}
/// Gets or sets the element at the specified index.
@@ -93,9 +89,24 @@ public static Vector2 UnitY
public float this[int index]
{
[Intrinsic]
- readonly get => this.GetElement(index);
+ readonly get
+ {
+ if ((uint)index >= Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
+ }
+ return this.AsVector128Unsafe().GetElement(index);
+ }
- set => this = this.WithElement(index, value);
+ [Intrinsic]
+ set
+ {
+ if ((uint)index >= Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
+ }
+ this = this.AsVector128Unsafe().WithElement(index, value).AsVector2();
+ }
}
/// Adds two vectors together.
@@ -105,13 +116,7 @@ public float this[int index]
/// The method defines the addition operation for objects.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 operator +(Vector2 left, Vector2 right)
- {
- return new Vector2(
- left.X + right.X,
- left.Y + right.Y
- );
- }
+ public static Vector2 operator +(Vector2 left, Vector2 right) => (left.AsVector128Unsafe() + right.AsVector128Unsafe()).AsVector2();
/// Divides the first vector by the second.
/// The first vector.
@@ -120,13 +125,7 @@ public float this[int index]
/// The method defines the division operation for objects.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 operator /(Vector2 left, Vector2 right)
- {
- return new Vector2(
- left.X / right.X,
- left.Y / right.Y
- );
- }
+ public static Vector2 operator /(Vector2 left, Vector2 right) => (left.AsVector128Unsafe() / right.AsVector128Unsafe()).AsVector2();
/// Divides the specified vector by a specified scalar value.
/// The vector.
@@ -134,7 +133,7 @@ public float this[int index]
/// The result of the division.
/// The method defines the division operation for objects.
[Intrinsic]
- public static Vector2 operator /(Vector2 value1, float value2) => value1 / new Vector2(value2);
+ public static Vector2 operator /(Vector2 value1, float value2) => (value1.AsVector128Unsafe() / value2).AsVector2();
/// Returns a value that indicates whether each pair of elements in two specified vectors is equal.
/// The first vector to compare.
@@ -143,11 +142,7 @@ public float this[int index]
/// Two objects are equal if each value in is equal to the corresponding value in .
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool operator ==(Vector2 left, Vector2 right)
- {
- return (left.X == right.X)
- && (left.Y == right.Y);
- }
+ public static bool operator ==(Vector2 left, Vector2 right) => left.AsVector128() == right.AsVector128();
/// Returns a value that indicates whether two specified vectors are not equal.
/// The first vector to compare.
@@ -163,13 +158,7 @@ public float this[int index]
/// The method defines the multiplication operation for objects.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 operator *(Vector2 left, Vector2 right)
- {
- return new Vector2(
- left.X * right.X,
- left.Y * right.Y
- );
- }
+ public static Vector2 operator *(Vector2 left, Vector2 right) => (left.AsVector128Unsafe() * right.AsVector128Unsafe()).AsVector2();
/// Multiplies the specified vector by the specified scalar value.
/// The vector.
@@ -177,7 +166,7 @@ public float this[int index]
/// The scaled vector.
/// The method defines the multiplication operation for objects.
[Intrinsic]
- public static Vector2 operator *(Vector2 left, float right) => left * new Vector2(right);
+ public static Vector2 operator *(Vector2 left, float right) => (left.AsVector128Unsafe() * right).AsVector2();
/// Multiplies the scalar value by the specified vector.
/// The vector.
@@ -194,33 +183,21 @@ public float this[int index]
/// The method defines the subtraction operation for objects.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 operator -(Vector2 left, Vector2 right)
- {
- return new Vector2(
- left.X - right.X,
- left.Y - right.Y
- );
- }
+ public static Vector2 operator -(Vector2 left, Vector2 right) => (left.AsVector128Unsafe() - right.AsVector128Unsafe()).AsVector2();
/// Negates the specified vector.
/// The vector to negate.
/// The negated vector.
/// The method defines the unary negation operation for objects.
[Intrinsic]
- public static Vector2 operator -(Vector2 value) => Zero - value;
+ public static Vector2 operator -(Vector2 value) => (-value.AsVector128Unsafe()).AsVector2();
/// Returns a vector whose elements are the absolute values of each of the specified vector's elements.
/// A vector.
/// The absolute value vector.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 Abs(Vector2 value)
- {
- return new Vector2(
- MathF.Abs(value.X),
- MathF.Abs(value.Y)
- );
- }
+ public static Vector2 Abs(Vector2 value) => Vector128.Abs(value.AsVector128Unsafe()).AsVector2();
/// Adds two vectors together.
/// The first vector to add.
@@ -241,12 +218,49 @@ public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max)
return Min(Max(value1, min), max);
}
+ /// Creates a new object whose two elements have the same value.
+ /// The value to assign to all two elements.
+ /// A new whose two elements have the same value.
+ [Intrinsic]
+ public static Vector2 Create(float value) => Vector128.Create(value).AsVector2();
+
+ /// Creates a vector whose elements have the specified values.
+ /// The value to assign to the field.
+ /// The value to assign to the field.
+ /// A new whose elements have the specified values.
+ [Intrinsic]
+ public static Vector2 Create(float x, float y) => Vector128.Create(x, y, 0, 0).AsVector2();
+
+ /// Constructs a vector from the given . The span must contain at least 2 elements.
+ /// The span of elements to assign to the vector.
+ [Intrinsic]
+ public static Vector2 Create(ReadOnlySpan values)
+ {
+ if (values.Length < Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values);
+ }
+ return Unsafe.ReadUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(values)));
+ }
+
+ /// Creates a vector with initialized to the specified value and the remaining elements initialized to zero.
+ /// The value to assign to the field.
+ /// A new with initialized and the remaining elements initialized to zero.
+ [Intrinsic]
+ internal static Vector2 CreateScalar(float x) => Vector128.CreateScalar(x).AsVector2();
+
+ /// Creates a vector with initialized to the specified value and the remaining elements left uninitialized.
+ /// The value to assign to the field.
+ /// A new with initialized and the remaining elements left uninitialized.
+ [Intrinsic]
+ internal static Vector2 CreateScalarUnsafe(float x) => Vector128.CreateScalarUnsafe(x).AsVector2();
+
/// Computes the Euclidean distance between the two given points.
/// The first point.
/// The second point.
/// The distance.
[Intrinsic]
- public static float Distance(Vector2 value1, Vector2 value2) => MathF.Sqrt(DistanceSquared(value1, value2));
+ public static float Distance(Vector2 value1, Vector2 value2) => float.Sqrt(DistanceSquared(value1, value2));
/// Returns the Euclidean distance squared between two specified points.
/// The first point.
@@ -275,22 +289,12 @@ public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max)
/// The dot product.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float Dot(Vector2 value1, Vector2 value2)
- {
- return (value1.X * value2.X)
- + (value1.Y * value2.Y);
- }
+ public static float Dot(Vector2 value1, Vector2 value2) => Vector128.Dot(value1.AsVector128(), value2.AsVector128());
///
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 FusedMultiplyAdd(Vector2 left, Vector2 right, Vector2 addend)
- {
- return new Vector2(
- float.FusedMultiplyAdd(left.X, right.X, addend.X),
- float.FusedMultiplyAdd(left.Y, right.Y, addend.Y)
- );
- }
+ public static Vector2 FusedMultiplyAdd(Vector2 left, Vector2 right, Vector2 addend) => Vector128.FusedMultiplyAdd(left.AsVector128Unsafe(), right.AsVector128Unsafe(), addend.AsVector128Unsafe()).AsVector2();
/// Performs a linear interpolation between two vectors based on the given weighting.
/// The first vector.
@@ -310,13 +314,7 @@ public static Vector2 FusedMultiplyAdd(Vector2 left, Vector2 right, Vector2 adde
/// The maximized vector.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 Max(Vector2 value1, Vector2 value2)
- {
- return new Vector2(
- (value1.X > value2.X) ? value1.X : value2.X,
- (value1.Y > value2.Y) ? value1.Y : value2.Y
- );
- }
+ public static Vector2 Max(Vector2 value1, Vector2 value2) => Vector128.Max(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2();
/// Returns a vector whose elements are the minimum of each of the pairs of elements in two specified vectors.
/// The first vector.
@@ -324,13 +322,7 @@ public static Vector2 Max(Vector2 value1, Vector2 value2)
/// The minimized vector.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 Min(Vector2 value1, Vector2 value2)
- {
- return new Vector2(
- (value1.X < value2.X) ? value1.X : value2.X,
- (value1.Y < value2.Y) ? value1.Y : value2.Y
- );
- }
+ public static Vector2 Min(Vector2 value1, Vector2 value2) => Vector128.Min(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2();
/// Returns a new vector whose values are the product of each pair of elements in two specified vectors.
/// The first vector.
@@ -356,13 +348,7 @@ public static Vector2 Min(Vector2 value1, Vector2 value2)
///
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 MultiplyAddEstimate(Vector2 left, Vector2 right, Vector2 addend)
- {
- return new Vector2(
- float.MultiplyAddEstimate(left.X, right.X, addend.X),
- float.MultiplyAddEstimate(left.Y, right.Y, addend.Y)
- );
- }
+ public static Vector2 MultiplyAddEstimate(Vector2 left, Vector2 right, Vector2 addend) => Vector128.MultiplyAddEstimate(left.AsVector128Unsafe(), right.AsVector128Unsafe(), addend.AsVector128Unsafe()).AsVector2();
/// Negates a specified vector.
/// The vector to negate.
@@ -388,13 +374,7 @@ public static Vector2 MultiplyAddEstimate(Vector2 left, Vector2 right, Vector2 a
/// The square root vector.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector2 SquareRoot(Vector2 value)
- {
- return new Vector2(
- MathF.Sqrt(value.X),
- MathF.Sqrt(value.Y)
- );
- }
+ public static Vector2 SquareRoot(Vector2 value) => Vector128.Sqrt(value.AsVector128Unsafe()).AsVector2();
/// Subtracts the second vector from the first.
/// The first vector.
@@ -444,7 +424,7 @@ public static Vector2 Transform(Vector2 value, Quaternion rotation)
float yy2 = rotation.Y * y2;
float zz2 = rotation.Z * z2;
- return new Vector2(
+ return Create(
value.X * (1.0f - yy2 - zz2) + value.Y * (xy2 - wz2),
value.X * (xy2 + wz2) + value.Y * (1.0f - xx2 - zz2)
);
@@ -569,28 +549,7 @@ public readonly bool TryCopyTo(Span destination)
/// if the two vectors are equal; otherwise, .
/// Two vectors are equal if their and elements are equal.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public readonly bool Equals(Vector2 other)
- {
- // This function needs to account for floating-point equality around NaN
- // and so must behave equivalently to the underlying float/double.Equals
-
- if (Vector64.IsHardwareAccelerated)
- {
- return Vector64.LoadUnsafe(ref Unsafe.AsRef(in X)).Equals(Vector64.LoadUnsafe(ref other.X));
- }
- else if (Vector128.IsHardwareAccelerated)
- {
- return this.AsVector128().Equals(other.AsVector128());
- }
-
- return SoftwareFallback(in this, other);
-
- static bool SoftwareFallback(in Vector2 self, Vector2 other)
- {
- return self.X.Equals(other.X)
- && self.Y.Equals(other.Y);
- }
- }
+ public readonly bool Equals(Vector2 other) => this.AsVector128().Equals(other.AsVector128());
/// Returns the hash code for this instance.
/// The hash code.
@@ -600,7 +559,7 @@ static bool SoftwareFallback(in Vector2 self, Vector2 other)
/// The vector's length.
///
[Intrinsic]
- public readonly float Length() => MathF.Sqrt(LengthSquared());
+ public readonly float Length() => float.Sqrt(LengthSquared());
/// Returns the length of the vector squared.
/// The vector's length squared.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.Extensions.cs
index 2eb006eeda745..ba7457ba8310a 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.Extensions.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.Extensions.cs
@@ -3,60 +3,22 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics;
namespace System.Numerics
{
public static unsafe partial class Vector
{
- /// Gets the element at the specified index.
- /// The vector to get the element from.
- /// The index of the element to get.
- /// The value of the element at .
- /// was less than zero or greater than the number of elements.
+ /// Converts a to a new with the new elements zeroed.
+ /// The vector to convert.
+ /// converted to a new with the new elements zeroed.
[Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static float GetElement(this Vector3 vector, int index)
- {
- if ((uint)(index) >= (uint)(Vector3.Count))
- {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
- }
+ public static Vector4 AsVector4(this Vector3 value) => value.AsVector128().AsVector4();
- return vector.GetElementUnsafe(index);
- }
-
- /// Creates a new with the element at the specified index set to the specified value and the remaining elements set to the same value as that in the given vector.
- /// The vector to get the remaining elements from.
- /// The index of the element to set.
- /// The value to set the element to.
- /// A with the value of the element at set to and the remaining elements set to the same value as that in .
- /// was less than zero or greater than the number of elements.
+ /// Converts a to a new with the new elements undefined.
+ /// The vector to convert.
+ /// converted to a new with the new elements undefined.
[Intrinsic]
- internal static Vector3 WithElement(this Vector3 vector, int index, float value)
- {
- if ((uint)(index) >= (uint)(Vector3.Count))
- {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
- }
-
- Vector3 result = vector;
- result.SetElementUnsafe(index, value);
- return result;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static float GetElementUnsafe(in this Vector3 vector, int index)
- {
- Debug.Assert((index >= 0) && (index < Vector3.Count));
- ref float address = ref Unsafe.AsRef(in vector.X);
- return Unsafe.Add(ref address, index);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void SetElementUnsafe(ref this Vector3 vector, int index, float value)
- {
- Debug.Assert((index >= 0) && (index < Vector3.Count));
- Unsafe.Add(ref vector.X, index) = value;
- }
+ public static Vector4 AsVector4Unsafe(this Vector3 value) => value.AsVector128Unsafe().AsVector4();
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs
index 7dc4994040eaa..29efe6d702831 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs
@@ -31,16 +31,18 @@ public partial struct Vector3 : IEquatable, IFormattable
/// Creates a new object whose three elements have the same value.
/// The value to assign to all three elements.
[Intrinsic]
- public Vector3(float value) : this(value, value, value)
+ public Vector3(float value)
{
+ this = Create(value);
}
/// Creates a new object from the specified object and the specified value.
/// The vector with two elements.
/// The additional value to assign to the field.
[Intrinsic]
- public Vector3(Vector2 value, float z) : this(value.X, value.Y, z)
+ public Vector3(Vector2 value, float z)
{
+ this = Create(value, z);
}
/// Creates a vector whose elements have the specified values.
@@ -50,21 +52,15 @@ public Vector3(Vector2 value, float z) : this(value.X, value.Y, z)
[Intrinsic]
public Vector3(float x, float y, float z)
{
- X = x;
- Y = y;
- Z = z;
+ this = Create(x, y, z);
}
/// Constructs a vector from the given . The span must contain at least 3 elements.
/// The span of elements to assign to the vector.
+ [Intrinsic]
public Vector3(ReadOnlySpan values)
{
- if (values.Length < 3)
- {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values);
- }
-
- this = Unsafe.ReadUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(values)));
+ this = Create(values);
}
/// Gets a vector whose 3 elements are equal to zero.
@@ -80,7 +76,7 @@ public static Vector3 Zero
public static Vector3 One
{
[Intrinsic]
- get => new Vector3(1.0f);
+ get => Create(1.0f);
}
/// Gets the vector (1,0,0).
@@ -88,7 +84,7 @@ public static Vector3 One
public static Vector3 UnitX
{
[Intrinsic]
- get => new Vector3(1.0f, 0.0f, 0.0f);
+ get => CreateScalar(1.0f);
}
/// Gets the vector (0,1,0).
@@ -96,7 +92,7 @@ public static Vector3 UnitX
public static Vector3 UnitY
{
[Intrinsic]
- get => new Vector3(0.0f, 1.0f, 0.0f);
+ get => Create(0.0f, 1.0f, 0.0f);
}
/// Gets the vector (0,0,1).
@@ -104,7 +100,7 @@ public static Vector3 UnitY
public static Vector3 UnitZ
{
[Intrinsic]
- get => new Vector3(0.0f, 0.0f, 1.0f);
+ get => Create(0.0f, 0.0f, 1.0f);
}
/// Gets or sets the element at the specified index.
@@ -114,9 +110,24 @@ public static Vector3 UnitZ
public float this[int index]
{
[Intrinsic]
- readonly get => this.GetElement(index);
+ readonly get
+ {
+ if ((uint)index >= Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
+ }
+ return this.AsVector128Unsafe().GetElement(index);
+ }
- set => this = this.WithElement(index, value);
+ [Intrinsic]
+ set
+ {
+ if ((uint)index >= Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
+ }
+ this = this.AsVector128Unsafe().WithElement(index, value).AsVector3();
+ }
}
/// Adds two vectors together.
@@ -126,14 +137,7 @@ public float this[int index]
/// The method defines the addition operation for objects.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 operator +(Vector3 left, Vector3 right)
- {
- return new Vector3(
- left.X + right.X,
- left.Y + right.Y,
- left.Z + right.Z
- );
- }
+ public static Vector3 operator +(Vector3 left, Vector3 right) => (left.AsVector128Unsafe() + right.AsVector128Unsafe()).AsVector3();
/// Divides the first vector by the second.
/// The first vector.
@@ -142,14 +146,7 @@ public float this[int index]
/// The method defines the division operation for objects.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 operator /(Vector3 left, Vector3 right)
- {
- return new Vector3(
- left.X / right.X,
- left.Y / right.Y,
- left.Z / right.Z
- );
- }
+ public static Vector3 operator /(Vector3 left, Vector3 right) => (left.AsVector128Unsafe() / right.AsVector128Unsafe()).AsVector3();
/// Divides the specified vector by a specified scalar value.
/// The vector.
@@ -157,7 +154,7 @@ public float this[int index]
/// The result of the division.
/// The method defines the division operation for objects.
[Intrinsic]
- public static Vector3 operator /(Vector3 value1, float value2) => value1 / new Vector3(value2);
+ public static Vector3 operator /(Vector3 value1, float value2) => (value1.AsVector128Unsafe() / value2).AsVector3();
/// Returns a value that indicates whether each pair of elements in two specified vectors is equal.
/// The first vector to compare.
@@ -166,12 +163,7 @@ public float this[int index]
/// Two objects are equal if each element in is equal to the corresponding element in .
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool operator ==(Vector3 left, Vector3 right)
- {
- return (left.X == right.X)
- && (left.Y == right.Y)
- && (left.Z == right.Z);
- }
+ public static bool operator ==(Vector3 left, Vector3 right) => left.AsVector128() == right.AsVector128();
/// Returns a value that indicates whether two specified vectors are not equal.
/// The first vector to compare.
@@ -187,14 +179,7 @@ public float this[int index]
/// The method defines the multiplication operation for objects.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 operator *(Vector3 left, Vector3 right)
- {
- return new Vector3(
- left.X * right.X,
- left.Y * right.Y,
- left.Z * right.Z
- );
- }
+ public static Vector3 operator *(Vector3 left, Vector3 right) => (left.AsVector128Unsafe() * right.AsVector128Unsafe()).AsVector3();
/// Multiplies the specified vector by the specified scalar value.
/// The vector.
@@ -202,7 +187,7 @@ public float this[int index]
/// The scaled vector.
/// The method defines the multiplication operation for objects.
[Intrinsic]
- public static Vector3 operator *(Vector3 left, float right) => left * new Vector3(right);
+ public static Vector3 operator *(Vector3 left, float right) => (left.AsVector128Unsafe() * right).AsVector3();
/// Multiplies the scalar value by the specified vector.
/// The vector.
@@ -219,35 +204,21 @@ public float this[int index]
/// The method defines the subtraction operation for objects.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 operator -(Vector3 left, Vector3 right)
- {
- return new Vector3(
- left.X - right.X,
- left.Y - right.Y,
- left.Z - right.Z
- );
- }
+ public static Vector3 operator -(Vector3 left, Vector3 right) => (left.AsVector128Unsafe() - right.AsVector128Unsafe()).AsVector3();
/// Negates the specified vector.
/// The vector to negate.
/// The negated vector.
/// The method defines the unary negation operation for objects.
[Intrinsic]
- public static Vector3 operator -(Vector3 value) => Zero - value;
+ public static Vector3 operator -(Vector3 value) => (-value.AsVector128Unsafe()).AsVector3();
/// Returns a vector whose elements are the absolute values of each of the specified vector's elements.
/// A vector.
/// The absolute value vector.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 Abs(Vector3 value)
- {
- return new Vector3(
- MathF.Abs(value.X),
- MathF.Abs(value.Y),
- MathF.Abs(value.Z)
- );
- }
+ public static Vector3 Abs(Vector3 value) => Vector128.Abs(value.AsVector128Unsafe()).AsVector3();
/// Adds two vectors together.
/// The first vector to add.
@@ -268,6 +239,56 @@ public static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max)
return Min(Max(value1, min), max);
}
+ /// Creates a new object whose three elements have the same value.
+ /// The value to assign to all three elements.
+ /// A new whose three elements have the same value.
+ [Intrinsic]
+ public static Vector3 Create(float value) => Vector128.Create(value).AsVector3();
+
+ /// Creates a new object from the specified object and a Z and a W component.
+ /// The vector to use for the X and Y components.
+ /// The Z component.
+ /// A new from the specified object and a Z and a W component.
+ [Intrinsic]
+ public static Vector3 Create(Vector2 vector, float z)
+ {
+ return vector.AsVector128Unsafe()
+ .WithElement(2, z)
+ .AsVector3();
+ }
+
+ /// Creates a vector whose elements have the specified values.
+ /// The value to assign to the field.
+ /// The value to assign to the field.
+ /// The value to assign to the field.
+ /// A new whose elements have the specified values.
+ [Intrinsic]
+ public static Vector3 Create(float x, float y, float z) => Vector128.Create(x, y, z, 0).AsVector3();
+
+ /// Constructs a vector from the given . The span must contain at least 3 elements.
+ /// The span of elements to assign to the vector.
+ [Intrinsic]
+ public static Vector3 Create(ReadOnlySpan values)
+ {
+ if (values.Length < Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values);
+ }
+ return Unsafe.ReadUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(values)));
+ }
+
+ /// Creates a vector with initialized to the specified value and the remaining elements initialized to zero.
+ /// The value to assign to the field.
+ /// A new with initialized and the remaining elements initialized to zero.
+ [Intrinsic]
+ internal static Vector3 CreateScalar(float x) => Vector128.CreateScalar(x).AsVector3();
+
+ /// Creates a vector with initialized to the specified value and the remaining elements left uninitialized.
+ /// The value to assign to the field.
+ /// A new with initialized and the remaining elements left uninitialized.
+ [Intrinsic]
+ internal static Vector3 CreateScalarUnsafe(float x) => Vector128.CreateScalarUnsafe(x).AsVector3();
+
/// Computes the cross product of two vectors.
/// The first vector.
/// The second vector.
@@ -275,7 +296,7 @@ public static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Cross(Vector3 vector1, Vector3 vector2)
{
- return new Vector3(
+ return Create(
(vector1.Y * vector2.Z) - (vector1.Z * vector2.Y),
(vector1.Z * vector2.X) - (vector1.X * vector2.Z),
(vector1.X * vector2.Y) - (vector1.Y * vector2.X)
@@ -287,7 +308,7 @@ public static Vector3 Cross(Vector3 vector1, Vector3 vector2)
/// The second point.
/// The distance.
[Intrinsic]
- public static float Distance(Vector3 value1, Vector3 value2) => MathF.Sqrt(DistanceSquared(value1, value2));
+ public static float Distance(Vector3 value1, Vector3 value2) => float.Sqrt(DistanceSquared(value1, value2));
/// Returns the Euclidean distance squared between two specified points.
/// The first point.
@@ -316,24 +337,12 @@ public static Vector3 Cross(Vector3 vector1, Vector3 vector2)
/// The dot product.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float Dot(Vector3 vector1, Vector3 vector2)
- {
- return (vector1.X * vector2.X)
- + (vector1.Y * vector2.Y)
- + (vector1.Z * vector2.Z);
- }
+ public static float Dot(Vector3 vector1, Vector3 vector2) => Vector128.Dot(vector1.AsVector128(), vector2.AsVector128());
///
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 FusedMultiplyAdd(Vector3 left, Vector3 right, Vector3 addend)
- {
- return new Vector3(
- float.FusedMultiplyAdd(left.X, right.X, addend.X),
- float.FusedMultiplyAdd(left.Y, right.Y, addend.Y),
- float.FusedMultiplyAdd(left.Z, right.Z, addend.Z)
- );
- }
+ public static Vector3 FusedMultiplyAdd(Vector3 left, Vector3 right, Vector3 addend) => Vector128.FusedMultiplyAdd(left.AsVector128Unsafe(), right.AsVector128Unsafe(), addend.AsVector128Unsafe()).AsVector3();
/// Performs a linear interpolation between two vectors based on the given weighting.
/// The first vector.
@@ -350,14 +359,7 @@ public static Vector3 FusedMultiplyAdd(Vector3 left, Vector3 right, Vector3 adde
/// The maximized vector.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 Max(Vector3 value1, Vector3 value2)
- {
- return new Vector3(
- (value1.X > value2.X) ? value1.X : value2.X,
- (value1.Y > value2.Y) ? value1.Y : value2.Y,
- (value1.Z > value2.Z) ? value1.Z : value2.Z
- );
- }
+ public static Vector3 Max(Vector3 value1, Vector3 value2) => Vector128.Max(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3();
/// Returns a vector whose elements are the minimum of each of the pairs of elements in two specified vectors.
/// The first vector.
@@ -365,14 +367,7 @@ public static Vector3 Max(Vector3 value1, Vector3 value2)
/// The minimized vector.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 Min(Vector3 value1, Vector3 value2)
- {
- return new Vector3(
- (value1.X < value2.X) ? value1.X : value2.X,
- (value1.Y < value2.Y) ? value1.Y : value2.Y,
- (value1.Z < value2.Z) ? value1.Z : value2.Z
- );
- }
+ public static Vector3 Min(Vector3 value1, Vector3 value2) => Vector128.Min(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3();
/// Returns a new vector whose values are the product of each pair of elements in two specified vectors.
/// The first vector.
@@ -398,14 +393,7 @@ public static Vector3 Min(Vector3 value1, Vector3 value2)
///
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 MultiplyAddEstimate(Vector3 left, Vector3 right, Vector3 addend)
- {
- return new Vector3(
- float.MultiplyAddEstimate(left.X, right.X, addend.X),
- float.MultiplyAddEstimate(left.Y, right.Y, addend.Y),
- float.MultiplyAddEstimate(left.Z, right.Z, addend.Z)
- );
- }
+ public static Vector3 MultiplyAddEstimate(Vector3 left, Vector3 right, Vector3 addend) => Vector128.MultiplyAddEstimate(left.AsVector128Unsafe(), right.AsVector128Unsafe(), addend.AsVector128Unsafe()).AsVector3();
/// Negates a specified vector.
/// The vector to negate.
@@ -431,14 +419,7 @@ public static Vector3 MultiplyAddEstimate(Vector3 left, Vector3 right, Vector3 a
/// The square root vector.
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector3 SquareRoot(Vector3 value)
- {
- return new Vector3(
- MathF.Sqrt(value.X),
- MathF.Sqrt(value.Y),
- MathF.Sqrt(value.Z)
- );
- }
+ public static Vector3 SquareRoot(Vector3 value) => Vector128.Sqrt(value.AsVector128Unsafe()).AsVector3();
/// Subtracts the second vector from the first.
/// The first vector.
@@ -475,7 +456,7 @@ public static Vector3 Transform(Vector3 value, Quaternion rotation)
float yz2 = rotation.Y * z2;
float zz2 = rotation.Z * z2;
- return new Vector3(
+ return Create(
value.X * (1.0f - yy2 - zz2) + value.Y * (xy2 - wz2) + value.Z * (xz2 + wy2),
value.X * (xy2 + wz2) + value.Y * (1.0f - xx2 - zz2) + value.Z * (yz2 - wx2),
value.X * (xz2 - wy2) + value.Y * (yz2 + wx2) + value.Z * (1.0f - xx2 - yy2)
@@ -587,25 +568,7 @@ public readonly bool TryCopyTo(Span destination)
/// if the two vectors are equal; otherwise, .
/// Two vectors are equal if their , , and elements are equal.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public readonly bool Equals(Vector3 other)
- {
- // This function needs to account for floating-point equality around NaN
- // and so must behave equivalently to the underlying float/double.Equals
-
- if (Vector128.IsHardwareAccelerated)
- {
- return this.AsVector128().Equals(other.AsVector128());
- }
-
- return SoftwareFallback(in this, other);
-
- static bool SoftwareFallback(in Vector3 self, Vector3 other)
- {
- return self.X.Equals(other.X)
- && self.Y.Equals(other.Y)
- && self.Z.Equals(other.Z);
- }
- }
+ public readonly bool Equals(Vector3 other) => this.AsVector128().Equals(other.AsVector128());
/// Returns the hash code for this instance.
/// The hash code.
@@ -615,7 +578,7 @@ static bool SoftwareFallback(in Vector3 self, Vector3 other)
/// The vector's length.
///
[Intrinsic]
- public readonly float Length() => MathF.Sqrt(LengthSquared());
+ public readonly float Length() => float.Sqrt(LengthSquared());
/// Returns the length of the vector squared.
/// The vector's length squared.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs
index 5e276425a0e53..8e243636d96e4 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs
@@ -12,7 +12,8 @@ public static unsafe partial class Vector
/// Reinterprets a as a new .
/// The vector to reinterpret.
/// reinterpreted as a new .
- internal static Plane AsPlane(this Vector4 value)
+ [Intrinsic]
+ public static Plane AsPlane(this Vector4 value)
{
#if MONO
return Unsafe.As(ref value);
@@ -24,7 +25,8 @@ internal static Plane AsPlane(this Vector4 value)
/// Reinterprets a as a new .
/// The vector to reinterpret.
/// reinterpreted as a new .
- internal static Quaternion AsQuaternion(this Vector4 value)
+ [Intrinsic]
+ public static Quaternion AsQuaternion(this Vector4 value)
{
#if MONO
return Unsafe.As(ref value);
@@ -33,37 +35,16 @@ internal static Quaternion AsQuaternion(this Vector4 value)
#endif
}
- /// Gets the element at the specified index.
- /// The vector to get the element from.
- /// The index of the element to get.
- /// The value of the element at .
- /// was less than zero or greater than the number of elements.
+ /// Reinterprets a as a new .
+ /// The vector to reinterpret.
+ /// reinterpreted as a new .
[Intrinsic]
- internal static float GetElement(this Vector4 vector, int index) => vector.AsVector128().GetElement(index);
+ public static Vector2 AsVector2(this Vector4 value) => value.AsVector128().AsVector2();
- /// Creates a new with the element at the specified index set to the specified value and the remaining elements set to the same value as that in the given vector.
- /// The vector to get the remaining elements from.
- /// The index of the element to set.
- /// The value to set the element to.
- /// A with the value of the element at set to and the remaining elements set to the same value as that in .
- /// was less than zero or greater than the number of elements.
+ /// Reinterprets a as a new .
+ /// The vector to reinterpret.
+ /// reinterpreted as a new .
[Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static Vector4 WithElement(this Vector4 vector, int index, float value) => vector.AsVector128().WithElement(index, value).AsVector4();
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static float GetElementUnsafe(in this Vector4 vector, int index)
- {
- Debug.Assert((index >= 0) && (index < Vector4.Count));
- ref float address = ref Unsafe.AsRef(in vector.X);
- return Unsafe.Add(ref address, index);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void SetElementUnsafe(ref this Vector4 vector, int index, float value)
- {
- Debug.Assert((index >= 0) && (index < Vector4.Count));
- Unsafe.Add(ref vector.X, index) = value;
- }
+ public static Vector3 AsVector3(this Vector4 value) => value.AsVector128().AsVector3();
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs
index f6893396cc4fc..65ae809ba6bc3 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs
@@ -37,7 +37,7 @@ public partial struct Vector4 : IEquatable, IFormattable
[Intrinsic]
public Vector4(float value)
{
- this = Vector128.Create(value).AsVector4();
+ this = Create(value);
}
/// Creates a new object from the specified object and a Z and a W component.
@@ -47,10 +47,7 @@ public Vector4(float value)
[Intrinsic]
public Vector4(Vector2 value, float z, float w)
{
- this = value.AsVector128()
- .WithElement(2, z)
- .WithElement(3, w)
- .AsVector4();
+ this = Create(value, z, w);
}
/// Constructs a new object from the specified object and a W component.
@@ -59,9 +56,7 @@ public Vector4(Vector2 value, float z, float w)
[Intrinsic]
public Vector4(Vector3 value, float w)
{
- this = value.AsVector128()
- .WithElement(3, w)
- .AsVector4();
+ this = Create(value, w);
}
/// Creates a vector whose elements have the specified values.
@@ -72,14 +67,15 @@ public Vector4(Vector3 value, float w)
[Intrinsic]
public Vector4(float x, float y, float z, float w)
{
- this = Vector128.Create(x, y, z, w).AsVector4();
+ this = Create(x, y, z, w);
}
/// Constructs a vector from the given . The span must contain at least 4 elements.
/// The span of elements to assign to the vector.
+ [Intrinsic]
public Vector4(ReadOnlySpan values)
{
- this = Vector128.Create(values).AsVector4();
+ this = Create(values);
}
/// Gets a vector whose 4 elements are equal to zero.
@@ -96,7 +92,7 @@ public static Vector4 Zero
public static Vector4 One
{
[Intrinsic]
- get => new Vector4(1);
+ get => Create(1);
}
/// Gets the vector (1,0,0,0).
@@ -104,7 +100,7 @@ public static Vector4 One
public static Vector4 UnitX
{
[Intrinsic]
- get => new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
+ get => CreateScalar(1.0f);
}
/// Gets the vector (0,1,0,0).
@@ -112,7 +108,7 @@ public static Vector4 UnitX
public static Vector4 UnitY
{
[Intrinsic]
- get => new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
+ get => Create(0.0f, 1.0f, 0.0f, 0.0f);
}
/// Gets the vector (0,0,1,0).
@@ -120,7 +116,7 @@ public static Vector4 UnitY
public static Vector4 UnitZ
{
[Intrinsic]
- get => new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
+ get => Create(0.0f, 0.0f, 1.0f, 0.0f);
}
/// Gets the vector (0,0,0,1).
@@ -128,7 +124,7 @@ public static Vector4 UnitZ
public static Vector4 UnitW
{
[Intrinsic]
- get => new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
+ get => Create(0.0f, 0.0f, 0.0f, 1.0f);
}
/// Gets or sets the element at the specified index.
@@ -138,9 +134,13 @@ public static Vector4 UnitW
public float this[int index]
{
[Intrinsic]
- readonly get => this.GetElement(index);
+ readonly get => this.AsVector128().GetElement(index);
- set => this = this.WithElement(index, value);
+ [Intrinsic]
+ set
+ {
+ this = this.AsVector128().WithElement(index, value).AsVector4();
+ }
}
/// Adds two vectors together.
@@ -167,7 +167,7 @@ public float this[int index]
/// The result of the division.
/// The method defines the division operation for objects.
[Intrinsic]
- public static Vector4 operator /(Vector4 value1, float value2) => value1 / new Vector4(value2);
+ public static Vector4 operator /(Vector4 value1, float value2) => (value1.AsVector128() / value2).AsVector4();
/// Returns a value that indicates whether each pair of elements in two specified vectors is equal.
/// The first vector to compare.
@@ -200,7 +200,7 @@ public float this[int index]
/// The scaled vector.
/// The method defines the multiplication operation for objects.
[Intrinsic]
- public static Vector4 operator *(Vector4 left, float right) => left * new Vector4(right);
+ public static Vector4 operator *(Vector4 left, float right) => (left.AsVector128() * right).AsVector4();
/// Multiplies the scalar value by the specified vector.
/// The vector.
@@ -253,12 +253,70 @@ public static Vector4 Clamp(Vector4 value1, Vector4 min, Vector4 max)
return Min(Max(value1, min), max);
}
+ /// Creates a new object whose four elements have the same value.
+ /// The value to assign to all four elements.
+ /// A new whose four elements have the same value.
+ [Intrinsic]
+ public static Vector4 Create(float value) => Vector128.Create(value).AsVector4();
+
+ /// Creates a new object from the specified object and a Z and a W component.
+ /// The vector to use for the X and Y components.
+ /// The Z component.
+ /// The W component.
+ /// A new from the specified object and a Z and a W component.
+ [Intrinsic]
+ public static Vector4 Create(Vector2 vector, float z, float w)
+ {
+ return vector.AsVector128Unsafe()
+ .WithElement(2, z)
+ .WithElement(3, w)
+ .AsVector4();
+ }
+
+ /// Constructs a new object from the specified object and a W component.
+ /// The vector to use for the X, Y, and Z components.
+ /// The W component.
+ /// A new from the specified object and a W component.
+ [Intrinsic]
+ public static Vector4 Create(Vector3 vector, float w)
+ {
+ return vector.AsVector128Unsafe()
+ .WithElement(3, w)
+ .AsVector4();
+ }
+
+ /// Creates a vector whose elements have the specified values.
+ /// The value to assign to the field.
+ /// The value to assign to the field.
+ /// The value to assign to the field.
+ /// The value to assign to the field.
+ /// A new whose elements have the specified values.
+ [Intrinsic]
+ public static Vector4 Create(float x, float y, float z, float w) => Vector128.Create(x, y, z, w).AsVector4();
+
+ /// Constructs a vector from the given . The span must contain at least 4 elements.
+ /// The span of elements to assign to the vector.
+ [Intrinsic]
+ public static Vector4 Create(ReadOnlySpan values) => Vector128.Create(values).AsVector4();
+
+ /// Creates a vector with initialized to the specified value and the remaining elements initialized to zero.
+ /// The value to assign to the field.
+ /// A new with initialized and the remaining elements initialized to zero.
+ [Intrinsic]
+ internal static Vector4 CreateScalar(float x) => Vector128.CreateScalar(x).AsVector4();
+
+ /// Creates a vector with initialized to the specified value and the remaining elements left uninitialized.
+ /// The value to assign to the field.
+ /// A new with initialized and the remaining elements left uninitialized.
+ [Intrinsic]
+ internal static Vector4 CreateScalarUnsafe(float x) => Vector128.CreateScalarUnsafe(x).AsVector4();
+
/// Computes the Euclidean distance between the two given points.
/// The first point.
/// The second point.
/// The distance.
[Intrinsic]
- public static float Distance(Vector4 value1, Vector4 value2) => MathF.Sqrt(DistanceSquared(value1, value2));
+ public static float Distance(Vector4 value1, Vector4 value2) => float.Sqrt(DistanceSquared(value1, value2));
/// Returns the Euclidean distance squared between two specified points.
/// The first point.
@@ -412,7 +470,7 @@ public static Vector4 Transform(Vector2 value, Quaternion rotation)
float yz2 = rotation.Y * z2;
float zz2 = rotation.Z * z2;
- return new Vector4(
+ return Create(
value.X * (1.0f - yy2 - zz2) + value.Y * (xy2 - wz2),
value.X * (xy2 + wz2) + value.Y * (1.0f - xx2 - zz2),
value.X * (xz2 - wy2) + value.Y * (yz2 + wx2),
@@ -459,7 +517,7 @@ public static Vector4 Transform(Vector3 value, Quaternion rotation)
float yz2 = rotation.Y * z2;
float zz2 = rotation.Z * z2;
- return new Vector4(
+ return Create(
value.X * (1.0f - yy2 - zz2) + value.Y * (xy2 - wz2) + value.Z * (xz2 + wy2),
value.X * (xy2 + wz2) + value.Y * (1.0f - xx2 - zz2) + value.Z * (yz2 - wx2),
value.X * (xz2 - wy2) + value.Y * (yz2 + wx2) + value.Z * (1.0f - xx2 - yy2),
@@ -506,7 +564,7 @@ public static Vector4 Transform(Vector4 value, Quaternion rotation)
float yz2 = rotation.Y * z2;
float zz2 = rotation.Z * z2;
- return new Vector4(
+ return Create(
value.X * (1.0f - yy2 - zz2) + value.Y * (xy2 - wz2) + value.Z * (xz2 + wy2),
value.X * (xy2 + wz2) + value.Y * (1.0f - xx2 - zz2) + value.Z * (yz2 - wx2),
value.X * (xz2 - wy2) + value.Y * (yz2 + wx2) + value.Z * (1.0f - xx2 - yy2),
@@ -564,7 +622,7 @@ public static Vector4 Transform(Vector4 value, Quaternion rotation)
/// The vector's length.
///
[Intrinsic]
- public readonly float Length() => MathF.Sqrt(LengthSquared());
+ public readonly float Length() => float.Sqrt(LengthSquared());
/// Returns the length of the vector squared.
/// The vector's length squared.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs
index 4009387a4f796..1c47d03b513cd 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs
@@ -133,7 +133,7 @@ public Vector(Span values) : this((ReadOnlySpan)values)
public static Vector AllBitsSet
{
[Intrinsic]
- get => new Vector(Scalar.AllBitsSet);
+ get => Vector.Create(Scalar.AllBitsSet);
}
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T')
@@ -195,7 +195,7 @@ public static bool IsSupported
public static Vector One
{
[Intrinsic]
- get => new Vector(Scalar.One);
+ get => Vector.Create(Scalar.One);
}
/// Gets a new with all elements initialized to zero.
@@ -506,7 +506,7 @@ public T this[int index]
/// The scalar to multiply with .
/// The product of and .
[Intrinsic]
- public static Vector operator *(Vector value, T factor) => value * new Vector(factor);
+ public static Vector operator *(Vector value, T factor) => value * Vector.Create(factor);
/// Multiplies a vector by a scalar to compute their product.
/// The scalar to multiply with .
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs
index ea2446090399d..c92fa6a706b73 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs
@@ -173,6 +173,7 @@ public static Vector128 As(this Vector128 vector)
/// Reinterprets a as a new .
/// The vector to reinterpret.
/// reinterpreted as a new .
+ [Intrinsic]
internal static Plane AsPlane(this Vector128 value)
{
#if MONO
@@ -185,6 +186,7 @@ internal static Plane AsPlane(this Vector128 value)
/// Reinterprets a as a new .
/// The vector to reinterpret.
/// reinterpreted as a new .
+ [Intrinsic]
internal static Quaternion AsQuaternion(this Vector128 value)
{
#if MONO
@@ -264,17 +266,17 @@ internal static Vector128 AsVector128(this Quaternion value)
#endif
}
- /// Reinterprets a as a new .
+ /// Reinterprets a as a new with the new elements zeroed.
/// The vector to reinterpret.
- /// reinterpreted as a new .
+ /// reinterpreted as a new with the new elements zeroed.
[Intrinsic]
- public static Vector128 AsVector128(this Vector2 value) => new Vector4(value.X, value.Y, 0.0f, 0.0f).AsVector128();
+ public static Vector128 AsVector128(this Vector2 value) => Vector4.Create(value, 0, 0).AsVector128();
- /// Reinterprets a as a new .
+ /// Reinterprets a as a new with the new elements zeroed.
/// The vector to reinterpret.
- /// reinterpreted as a new .
+ /// reinterpreted as a new with the new elements zeroed.
[Intrinsic]
- public static Vector128 AsVector128(this Vector3 value) => new Vector4(value.X, value.Y, value.Z, 0.0f).AsVector128();
+ public static Vector128 AsVector128(this Vector3 value) => Vector4.Create(value, 0).AsVector128();
/// Reinterprets a as a new .
/// The vector to reinterpret.
@@ -305,6 +307,34 @@ public static Vector128 AsVector128(this Vector value)
return Unsafe.ReadUnaligned>(ref address);
}
+ /// Reinterprets a as a new , leaving the new elements undefined.
+ /// The vector to reinterpret.
+ /// reinterpreted as a new .
+ [Intrinsic]
+ public static Vector128 AsVector128Unsafe(this Vector2 value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ Unsafe.SkipInit(out Vector128 result);
+ Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value);
+ return result;
+ }
+
+ /// Reinterprets a as a new , leaving the new elements undefined.
+ /// The vector to reinterpret.
+ /// reinterpreted as a new .
+ [Intrinsic]
+ public static Vector128 AsVector128Unsafe(this Vector3 value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ Unsafe.SkipInit(out Vector128 result);
+ Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value);
+ return result;
+ }
+
/// Reinterprets a as a new .
/// The vector to reinterpret.
/// reinterpreted as a new .
@@ -1109,6 +1139,14 @@ public static unsafe Vector128 Create(ulong e0, ulong e1)
);
}
+ /// Creates a new instance with the lower and upper 64-bits initialized to a specified value.
+ /// The type of the elements in the vector.
+ /// The value that the lower and upper 64-bits will be initialized to.
+ /// A new with the lower and upper 64-bits initialized to .
+ /// The type of () is not supported.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128 Create(Vector64 value) => Create(value, value);
+
/// Creates a new instance from two instances.
/// The type of the elements in the vector.
/// The value that the lower 64-bits will be initialized to.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs
index 4779812149be0..73d021ffc4447 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs
@@ -1046,6 +1046,22 @@ public static Vector256 Create(ulong e0, ulong e1, ulong e2, ulong e3)
);
}
+ /// Creates a new instance with all 64-bit parts initialized to a specified value.
+ /// The type of the elements in the vector.
+ /// The value that the 64-bit parts will be initialized to.
+ /// A new with the 64-bit parts initialized to .
+ /// The type of () is not supported.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256 Create(Vector64 value) => Create(Vector128.Create(value, value));
+
+ /// Creates a new instance with the lower and upper 128-bits initialized to a specified value.
+ /// The type of the elements in the vector.
+ /// The value that the lower and upper 128-bits will be initialized to.
+ /// A new with the lower and upper 128-bits initialized to .
+ /// The type of () is not supported.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256 Create(Vector128 value) => Create(value, value);
+
/// Creates a new instance from two instances.
/// The type of the elements in the vector.
/// The value that the lower 128-bits will be initialized to.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs
index 4e534e8ac3947..7a80c3c393783 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs
@@ -1108,6 +1108,30 @@ public static Vector512 Create(ulong e0, ulong e1, ulong e2, ulong e3, ul
);
}
+ /// Creates a new instance with all 64-bit parts initialized to a specified value.
+ /// The type of the elements in the vector.
+ /// The value that the 64-bit parts will be initialized to.
+ /// A new with the 64-bit parts initialized to .
+ /// The type of () is not supported.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector512 Create(Vector64 value) => Create(Vector128.Create(value, value));
+
+ /// Creates a new instance with all 128-bit parts initialized to a specified value.
+ /// The type of the elements in the vector.
+ /// The value that the 128-bit parts will be initialized to.
+ /// A new with the 128-bit parts initialized to .
+ /// The type of () is not supported.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector512 Create(Vector128 value) => Create(Vector256.Create(value, value));
+
+ /// Creates a new instance with the lower and upper 256-bits initialized to a specified value.
+ /// The type of the elements in the vector.
+ /// The value that the lower and upper 256-bits will be initialized to.
+ /// A new with the lower and upper 256-bits initialized to .
+ /// The type of () is not supported.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector512 Create(Vector256 value) => Create(value, value);
+
/// Creates a new instance from two instances.
/// The type of the elements in the vector.
/// The value that the lower 256-bits will be initialized to.
diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs
index deccdddb8fece..42e0fcc2a65e7 100644
--- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs
@@ -17,7 +17,7 @@ internal static class IndexOfAnyAsciiSearcher
{
public struct AsciiState(Vector128 bitmap, BitVector256 lookup)
{
- public Vector256 Bitmap = Vector256.Create(bitmap, bitmap);
+ public Vector256 Bitmap = Vector256.Create(bitmap);
public BitVector256 Lookup = lookup;
public readonly AsciiState CreateInverse() =>
@@ -26,8 +26,8 @@ public readonly AsciiState CreateInverse() =>
public struct AnyByteState(Vector128 bitmap0, Vector128 bitmap1, BitVector256 lookup)
{
- public Vector256 Bitmap0 = Vector256.Create(bitmap0, bitmap0);
- public Vector256 Bitmap1 = Vector256.Create(bitmap1, bitmap1);
+ public Vector256 Bitmap0 = Vector256.Create(bitmap0);
+ public Vector256 Bitmap1 = Vector256.Create(bitmap1);
public BitVector256 Lookup = lookup;
}
@@ -146,7 +146,7 @@ private static unsafe bool TryIndexOfAny(ref short searchSpace, int se
{
// Only initializing the bitmap here is okay as we can only get here if the search space is long enough
// and we support vectorization, so the IndexOfAnyVectorized implementation will never touch state.Lookup.
- state.Bitmap = Vector256.Create(state.Bitmap._lower, state.Bitmap._lower);
+ state.Bitmap = Vector256.Create(state.Bitmap.GetLower());
index = (Ssse3.IsSupported || PackedSimd.IsSupported) && needleContainsZero
? IndexOfAny(ref searchSpace, searchSpaceLength, ref state)
@@ -173,7 +173,7 @@ private static unsafe bool TryLastIndexOfAny(ref short searchSpace, in
{
// Only initializing the bitmap here is okay as we can only get here if the search space is long enough
// and we support vectorization, so the LastIndexOfAnyVectorized implementation will never touch state.Lookup.
- state.Bitmap = Vector256.Create(state.Bitmap._lower, state.Bitmap._lower);
+ state.Bitmap = Vector256.Create(state.Bitmap.GetLower());
index = (Ssse3.IsSupported || PackedSimd.IsSupported) && needleContainsZero
? LastIndexOfAny(ref searchSpace, searchSpaceLength, ref state)
diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs
index 3c93ad6cd46d4..3211c0c320f83 100644
--- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs
@@ -411,7 +411,7 @@ private static int IndexOfAnyVectorizedAvx512(ref char searchS
if (searchSpaceLength > 32)
{
- Vector512 charMap512 = Vector512.Create(charMap256, charMap256);
+ Vector512 charMap512 = Vector512.Create(charMap256);
if (searchSpaceLength > 64)
{
@@ -499,8 +499,8 @@ private static int IndexOfAnyVectorized(ref char searchSpace,
if (Avx2.IsSupported && searchSpaceLength >= 32)
#pragma warning restore IntrinsicsInSystemPrivateCoreLibAttributeNotSpecificEnough
{
- Vector256 charMapLower256 = Vector256.Create(charMapLower, charMapLower);
- Vector256 charMapUpper256 = Vector256.Create(charMapUpper, charMapUpper);
+ Vector256 charMapLower256 = Vector256.Create(charMapLower);
+ Vector256 charMapUpper256 = Vector256.Create(charMapUpper);
ref char lastStartVectorAvx2 = ref Unsafe.Subtract(ref searchSpaceEnd, 32);
@@ -586,7 +586,7 @@ private static int LastIndexOfAnyVectorizedAvx512(ref char sea
if (searchSpaceLength > 32)
{
- Vector512 charMap512 = Vector512.Create(charMap256, charMap256);
+ Vector512 charMap512 = Vector512.Create(charMap256);
if (searchSpaceLength > 64)
{
@@ -676,8 +676,8 @@ private static int LastIndexOfAnyVectorized(ref char searchSpa
if (Avx2.IsSupported && searchSpaceLength >= 32)
#pragma warning restore IntrinsicsInSystemPrivateCoreLibAttributeNotSpecificEnough
{
- Vector256 charMapLower256 = Vector256.Create(charMapLower, charMapLower);
- Vector256 charMapUpper256 = Vector256.Create(charMapUpper, charMapUpper);
+ Vector256 charMapLower256 = Vector256.Create(charMapLower);
+ Vector256 charMapUpper256 = Vector256.Create(charMapUpper);
ref char lastStartVectorAvx2 = ref Unsafe.Add(ref searchSpace, 32);
diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/TeddyBucketizer.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/TeddyBucketizer.cs
index c277e6a8f72af..666889e4383e2 100644
--- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/TeddyBucketizer.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/TeddyBucketizer.cs
@@ -35,7 +35,7 @@ public static (Vector512 Low, Vector512 High) GenerateNonBucketizedF
high.SetElementUnsafe(highNibble, (byte)(high.GetElementUnsafe(highNibble) | bit));
}
- return (DuplicateTo512(low), DuplicateTo512(high));
+ return (Vector512.Create(low), Vector512.Create(high));
}
// We can have up to 8 buckets, and their positions are encoded by 1 bit each.
@@ -69,14 +69,7 @@ public static (Vector512 Low, Vector512 High) GenerateBucketizedFing
}
}
- return (DuplicateTo512(low), DuplicateTo512(high));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static Vector512 DuplicateTo512(Vector128 vector)
- {
- Vector256 vector256 = Vector256.Create(vector, vector);
- return Vector512.Create(vector256, vector256);
+ return (Vector512.Create(low), Vector512.Create(high));
}
public static string[][] Bucketize(ReadOnlySpan values, int bucketCount, int n)
diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs
index 9ef07d114da67..ced611ec012a9 100644
--- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs
@@ -65,7 +65,7 @@ public static unsafe void Fill(ref T refData, nuint numElements, T value)
}
else if (Vector.Count == 32)
{
- vector = Vector256.Create(vec128, vec128).AsVector();
+ vector = Vector256.Create(vec128).AsVector();
}
else
{
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 a8be59ed29889..44e3fe8e05fe4 100644
--- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs
+++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs
@@ -34,6 +34,8 @@ public static partial class Vector128
public static System.Runtime.Intrinsics.Vector128 AsVector128(this System.Numerics.Vector2 value) { throw null; }
public static System.Runtime.Intrinsics.Vector128 AsVector128(this System.Numerics.Vector3 value) { throw null; }
public static System.Runtime.Intrinsics.Vector128 AsVector128(this System.Numerics.Vector4 value) { throw null; }
+ public static System.Runtime.Intrinsics.Vector128 AsVector128Unsafe(this System.Numerics.Vector2 value) { throw null; }
+ public static System.Runtime.Intrinsics.Vector128 AsVector128Unsafe(this System.Numerics.Vector3 value) { throw null; }
public static System.Runtime.Intrinsics.Vector128 AsVector128(this System.Numerics.Vector value) { throw null; }
public static System.Numerics.Vector2 AsVector2(this System.Runtime.Intrinsics.Vector128 value) { throw null; }
public static System.Numerics.Vector3 AsVector3(this System.Runtime.Intrinsics.Vector128 value) { throw null; }
@@ -152,6 +154,7 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector,
public static System.Runtime.Intrinsics.Vector128 CreateScalarUnsafe(T value) { throw null; }
public static System.Runtime.Intrinsics.Vector128