Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3176,6 +3176,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,

switch (simdBaseJitType)
{
case CORINFO_TYPE_CHAR:
case CORINFO_TYPE_BYTE:
case CORINFO_TYPE_UBYTE:
case CORINFO_TYPE_SHORT:
Expand All @@ -3184,10 +3185,10 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
case CORINFO_TYPE_UINT:
case CORINFO_TYPE_LONG:
case CORINFO_TYPE_ULONG:
case CORINFO_TYPE_FLOAT:
case CORINFO_TYPE_DOUBLE:
case CORINFO_TYPE_NATIVEINT:
case CORINFO_TYPE_NATIVEUINT:
case CORINFO_TYPE_FLOAT:
case CORINFO_TYPE_DOUBLE:
{
return gtNewIconNode(true);
}
Expand Down Expand Up @@ -3217,6 +3218,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,

switch (simdBaseJitType)
{
case CORINFO_TYPE_CHAR:
case CORINFO_TYPE_BYTE:
case CORINFO_TYPE_UBYTE:
case CORINFO_TYPE_SHORT:
Expand All @@ -3225,10 +3227,10 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
case CORINFO_TYPE_UINT:
case CORINFO_TYPE_LONG:
case CORINFO_TYPE_ULONG:
case CORINFO_TYPE_FLOAT:
case CORINFO_TYPE_DOUBLE:
case CORINFO_TYPE_NATIVEINT:
case CORINFO_TYPE_NATIVEUINT:
case CORINFO_TYPE_FLOAT:
case CORINFO_TYPE_DOUBLE:
{
var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType);
unsigned elementSize = genTypeSize(simdBaseType);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/tools/Common/TypeSystem/Common/TypeDesc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ public bool IsPrimitiveNumeric
{
switch (GetTypeFlags(TypeFlags.CategoryMask))
{
case TypeFlags.Char:
case TypeFlags.SByte:
case TypeFlags.Byte:
case TypeFlags.Int16:
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4102,6 +4102,9 @@ CorInfoType CEEInfo::getTypeForPrimitiveNumericClass(
CorElementType ty = th.GetSignatureCorElementType();
switch (ty)
{
case ELEMENT_TYPE_CHAR:
result = CORINFO_TYPE_CHAR;
break;
case ELEMENT_TYPE_I1:
result = CORINFO_TYPE_BYTE;
break;
Expand Down
230 changes: 117 additions & 113 deletions src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -484,8 +484,6 @@ private void TestArrayIndexBasedConstructorLessElements<T>() where T : struct
public void ConstructorWithUnsupportedTypes_Guid() => TestConstructorWithUnsupportedTypes<Guid>();
[Fact]
public void ConstructorWithUnsupportedTypes_DateTime() => TestConstructorWithUnsupportedTypes<DateTime>();
[Fact]
public void ConstructorWithUnsupportedTypes_Char() => TestConstructorWithUnsupportedTypes<Char>();

private void TestConstructorWithUnsupportedTypes<T>() where T : struct
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,6 @@ public void AsToTest()
[Fact]
public void IsNotSupportedBoolean() => TestIsNotSupported<bool>();

[Fact]
public void IsNotSupportedChar() => TestIsNotSupported<char>();

[Fact]
public void IsNotSupportedHalf() => TestIsNotSupported<Half>();

Expand Down
122 changes: 46 additions & 76 deletions src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,7 @@ public static Vector<T> NegativeOne
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<T> Abs<T>(Vector<T> value)
{
if ((typeof(T) == typeof(byte))
|| (typeof(T) == typeof(ushort))
|| (typeof(T) == typeof(uint))
|| (typeof(T) == typeof(ulong))
|| (typeof(T) == typeof(nuint)))
if (Scalar<T>.IsUnsigned)
{
return value;
}
Expand Down Expand Up @@ -239,6 +235,14 @@ public static Vector<TTo> As<TFrom, TTo>(this Vector<TFrom> vector)
[Intrinsic]
public static Vector<byte> AsVectorByte<T>(Vector<T> value) => value.As<T, byte>();

/// <summary>Reinterprets a <see cref="Vector{T}" /> as a new <see langword="Vector&lt;Char&gt;" />.</summary>
/// <typeparam name="T">The type of the input vector.</typeparam>
/// <param name="value">The vector to reinterpret.</param>
/// <returns><paramref name="value" /> reinterpreted as a new <see langword="Vector&lt;Char&gt;" />.</returns>
/// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
[Intrinsic]
public static Vector<char> AsVectorChar<T>(Vector<T> value) => value.As<T, char>();

/// <summary>Reinterprets a <see cref="Vector{T}" /> as a new <see langword="Vector&lt;Double&gt;" />.</summary>
/// <typeparam name="T">The type of the input vector.</typeparam>
/// <param name="value">The vector to reinterpret.</param>
Expand Down Expand Up @@ -355,20 +359,7 @@ public static Vector<TTo> As<TFrom, TTo>(this Vector<TFrom> vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Vector<T> Ceiling<T>(Vector<T> vector)
{
if ((typeof(T) == typeof(byte))
|| (typeof(T) == typeof(short))
|| (typeof(T) == typeof(int))
|| (typeof(T) == typeof(long))
|| (typeof(T) == typeof(nint))
|| (typeof(T) == typeof(nuint))
|| (typeof(T) == typeof(sbyte))
|| (typeof(T) == typeof(ushort))
|| (typeof(T) == typeof(uint))
|| (typeof(T) == typeof(ulong)))
{
return vector;
}
else
if (Scalar<T>.IsFloatingPoint)
{
Unsafe.SkipInit(out Vector<T> result);

Expand All @@ -380,6 +371,10 @@ internal static Vector<T> Ceiling<T>(Vector<T> vector)

return result;
}
else
{
return vector;
}
}

/// <summary>Computes the ceiling of each element in a vector.</summary>
Expand Down Expand Up @@ -737,11 +732,7 @@ public static Vector<float> Cos(Vector<float> vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<T> CopySign<T>(Vector<T> value, Vector<T> sign)
{
if ((typeof(T) == typeof(byte))
|| (typeof(T) == typeof(ushort))
|| (typeof(T) == typeof(uint))
|| (typeof(T) == typeof(ulong))
|| (typeof(T) == typeof(nuint)))
if (Scalar<T>.IsUnsigned)
{
return value;
}
Expand Down Expand Up @@ -1072,20 +1063,7 @@ public static Vector<float> Exp(Vector<float> vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Vector<T> Floor<T>(Vector<T> vector)
{
if ((typeof(T) == typeof(byte))
|| (typeof(T) == typeof(short))
|| (typeof(T) == typeof(int))
|| (typeof(T) == typeof(long))
|| (typeof(T) == typeof(nint))
|| (typeof(T) == typeof(nuint))
|| (typeof(T) == typeof(sbyte))
|| (typeof(T) == typeof(ushort))
|| (typeof(T) == typeof(uint))
|| (typeof(T) == typeof(ulong)))
{
return vector;
}
else
if (Scalar<T>.IsFloatingPoint)
{
Unsafe.SkipInit(out Vector<T> result);

Expand All @@ -1097,6 +1075,10 @@ internal static Vector<T> Floor<T>(Vector<T> vector)

return result;
}
else
{
return vector;
}
}

/// <summary>Computes the floor of each element in a vector.</summary>
Expand Down Expand Up @@ -1534,11 +1516,7 @@ public static Vector<T> IsNaN<T>(Vector<T> vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<T> IsNegative<T>(Vector<T> vector)
{
if ((typeof(T) == typeof(byte))
|| (typeof(T) == typeof(ushort))
|| (typeof(T) == typeof(uint))
|| (typeof(T) == typeof(ulong))
|| (typeof(T) == typeof(nuint)))
if (Scalar<T>.IsUnsigned)
{
return Vector<T>.Zero;
}
Expand Down Expand Up @@ -1609,11 +1587,7 @@ public static Vector<T> IsOddInteger<T>(Vector<T> vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<T> IsPositive<T>(Vector<T> vector)
{
if ((typeof(T) == typeof(byte))
|| (typeof(T) == typeof(ushort))
|| (typeof(T) == typeof(uint))
|| (typeof(T) == typeof(ulong))
|| (typeof(T) == typeof(nuint)))
if (Scalar<T>.IsUnsigned)
{
return Vector<T>.AllBitsSet;
}
Expand Down Expand Up @@ -2611,20 +2585,7 @@ public static Vector<float> RadiansToDegrees(Vector<float> radians)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Vector<T> Round<T>(Vector<T> vector)
{
if ((typeof(T) == typeof(byte))
|| (typeof(T) == typeof(short))
|| (typeof(T) == typeof(int))
|| (typeof(T) == typeof(long))
|| (typeof(T) == typeof(nint))
|| (typeof(T) == typeof(nuint))
|| (typeof(T) == typeof(sbyte))
|| (typeof(T) == typeof(ushort))
|| (typeof(T) == typeof(uint))
|| (typeof(T) == typeof(ulong)))
{
return vector;
}
else
if (Scalar<T>.IsFloatingPoint)
{
Unsafe.SkipInit(out Vector<T> result);

Expand All @@ -2636,6 +2597,10 @@ internal static Vector<T> Round<T>(Vector<T> vector)

return result;
}
else
{
return vector;
}
}

/// <inheritdoc cref="Vector128.Round(Vector128{double})" />
Expand All @@ -2661,6 +2626,13 @@ internal static Vector<T> Round<T>(Vector<T> vector)
[Intrinsic]
public static Vector<byte> ShiftLeft(Vector<byte> value, int shiftCount) => value << shiftCount;

/// <summary>Shifts each element of a vector left by the specified amount.</summary>
/// <param name="value">The vector whose elements are to be shifted.</param>
/// <param name="shiftCount">The number of bits by which to shift each element.</param>
/// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
[Intrinsic]
public static Vector<char> ShiftLeft(Vector<char> value, int shiftCount) => value << shiftCount;

/// <summary>Shifts each element of a vector left by the specified amount.</summary>
/// <param name="value">The vector whose elements are to be shifted.</param>
/// <param name="shiftCount">The number of bits by which to shift each element.</param>
Expand Down Expand Up @@ -2808,6 +2780,13 @@ internal static Vector<ulong> ShiftLeft(Vector<ulong> vector, Vector<ulong> shif
[Intrinsic]
public static Vector<byte> ShiftRightLogical(Vector<byte> value, int shiftCount) => value >>> shiftCount;

/// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
/// <param name="value">The vector whose elements are to be shifted.</param>
/// <param name="shiftCount">The number of bits by which to shift each element.</param>
/// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
[Intrinsic]
public static Vector<char> ShiftRightLogical(Vector<char> value, int shiftCount) => value >>> shiftCount;

/// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
/// <param name="value">The vector whose elements are to be shifted.</param>
/// <param name="shiftCount">The number of bits by which to shift each element.</param>
Expand Down Expand Up @@ -3110,20 +3089,7 @@ public static T ToScalar<T>(this Vector<T> vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Vector<T> Truncate<T>(Vector<T> vector)
{
if ((typeof(T) == typeof(byte))
|| (typeof(T) == typeof(short))
|| (typeof(T) == typeof(int))
|| (typeof(T) == typeof(long))
|| (typeof(T) == typeof(nint))
|| (typeof(T) == typeof(nuint))
|| (typeof(T) == typeof(sbyte))
|| (typeof(T) == typeof(ushort))
|| (typeof(T) == typeof(uint))
|| (typeof(T) == typeof(ulong)))
{
return vector;
}
else
if (Scalar<T>.IsFloatingPoint)
{
Unsafe.SkipInit(out Vector<T> result);

Expand All @@ -3135,6 +3101,10 @@ internal static Vector<T> Truncate<T>(Vector<T> vector)

return result;
}
else
{
return vector;
}
}

/// <inheritdoc cref="Vector128.Truncate(Vector128{double})" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;

namespace System.Numerics
{
Expand All @@ -25,6 +26,16 @@ public byte[] ByteView
}
}

public char[] CharView
{
get
{
var items = new char[Vector<char>.Count];
Unsafe.WriteUnaligned(ref Unsafe.As<char, byte>(ref items[0]), _value);
return items;
}
}

public double[] DoubleView
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,7 @@ public static bool IsSupported
{
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (typeof(T) == typeof(byte)) ||
(typeof(T) == typeof(double)) ||
(typeof(T) == typeof(short)) ||
(typeof(T) == typeof(int)) ||
(typeof(T) == typeof(long)) ||
(typeof(T) == typeof(nint)) ||
(typeof(T) == typeof(nuint)) ||
(typeof(T) == typeof(sbyte)) ||
(typeof(T) == typeof(float)) ||
(typeof(T) == typeof(ushort)) ||
(typeof(T) == typeof(uint)) ||
(typeof(T) == typeof(ulong));
get => Scalar<T>.IsSupported;
}

/// <summary>Gets a new <see cref="Vector{T}" /> with all elements initialized to one.</summary>
Expand Down Expand Up @@ -368,6 +357,13 @@ public T this[int index]
[Intrinsic]
public static explicit operator Vector<byte>(Vector<T> value) => value.As<T, byte>();

/// <summary>Reinterprets a <see cref="Vector{T}" /> as a new <see langword="Vector&lt;Char&gt;" />.</summary>
/// <param name="value">The vector to reinterpret.</param>
/// <returns><paramref name="value" /> reinterpreted as a new <see langword="Vector&lt;Char&gt;" />.</returns>
/// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
[Intrinsic]
public static explicit operator Vector<char>(Vector<T> value) => value.As<T, char>();

/// <summary>Reinterprets a <see cref="Vector{T}" /> as a new <see langword="Vector&lt;Double&gt;" />.</summary>
/// <param name="value">The vector to reinterpret.</param>
/// <returns><paramref name="value" /> reinterpreted as a new <see langword="Vector&lt;Double&gt;" />.</returns>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// 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.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
Expand Down
Loading
Loading