-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add API call for Arm64 Sve.LoadVectorNonFaulting #97695
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
/*****************************************************************************/ | ||
#ifndef HARDWARE_INTRINSIC | ||
#error Define HARDWARE_INTRINSIC before including this file | ||
#endif | ||
/*****************************************************************************/ | ||
|
||
// clang-format off | ||
|
||
#ifdef FEATURE_HW_INTRINSICS | ||
// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** | ||
// ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags | ||
// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} | ||
// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** | ||
// SVE Intrinsics | ||
|
||
// Sve | ||
HARDWARE_INTRINSIC(Sve, LoadVectorNonFaulting, -1, 2, true, {INS_sve_ldnf1b, INS_sve_ldnf1b, INS_sve_ldnf1h, INS_sve_ldnf1h, INS_sve_ldnf1w, INS_sve_ldnf1w, INS_sve_ldnf1d, INS_sve_ldnf1d, INS_sve_ldnf1w, INS_sve_ldnf1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_Predicated) | ||
|
||
#endif // FEATURE_HW_INTRINSIC | ||
|
||
#undef HARDWARE_INTRINSIC | ||
|
||
// clang-format on |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// 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.Runtime.CompilerServices; | ||
using System.Runtime.Intrinsics; | ||
using System.Numerics; | ||
|
||
namespace System.Runtime.Intrinsics.Arm | ||
{ | ||
/// <summary> | ||
/// This class provides access to the ARM SVE hardware instructions via intrinsics | ||
/// </summary> | ||
[Intrinsic] | ||
[CLSCompliant(false)] | ||
public abstract class Sve : AdvSimd | ||
{ | ||
internal Sve() { } | ||
|
||
public static new bool IsSupported { get => IsSupported; } | ||
|
||
[Intrinsic] | ||
public new abstract class Arm64 : AdvSimd.Arm64 | ||
{ | ||
internal Arm64() { } | ||
|
||
public static new bool IsSupported { get => IsSupported; } | ||
} | ||
|
||
|
||
/// LoadVectorNonFaulting : Unextended load, non-faulting | ||
|
||
/// <summary> | ||
/// svint8_t svldnf1[_s8](svbool_t pg, const int8_t *base) | ||
/// LDNF1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<sbyte> LoadVectorNonFaulting(Vector<sbyte> mask, sbyte* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svint16_t svldnf1[_s16](svbool_t pg, const int16_t *base) | ||
/// LDNF1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<short> LoadVectorNonFaulting(Vector<short> mask, short* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svint32_t svldnf1[_s32](svbool_t pg, const int32_t *base) | ||
/// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<int> LoadVectorNonFaulting(Vector<int> mask, int* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svint64_t svldnf1[_s64](svbool_t pg, const int64_t *base) | ||
/// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<long> LoadVectorNonFaulting(Vector<long> mask, long* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svuint8_t svldnf1[_u8](svbool_t pg, const uint8_t *base) | ||
/// LDNF1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<byte> LoadVectorNonFaulting(Vector<byte> mask, byte* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svuint16_t svldnf1[_u16](svbool_t pg, const uint16_t *base) | ||
/// LDNF1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<ushort> LoadVectorNonFaulting(Vector<ushort> mask, ushort* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svuint32_t svldnf1[_u32](svbool_t pg, const uint32_t *base) | ||
/// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<uint> LoadVectorNonFaulting(Vector<uint> mask, uint* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svuint64_t svldnf1[_u64](svbool_t pg, const uint64_t *base) | ||
/// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<ulong> LoadVectorNonFaulting(Vector<ulong> mask, ulong* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svfloat32_t svldnf1[_f32](svbool_t pg, const float32_t *base) | ||
/// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<float> LoadVectorNonFaulting(Vector<float> mask, float* address) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// svfloat64_t svldnf1[_f64](svbool_t pg, const float64_t *base) | ||
/// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] | ||
/// </summary> | ||
public static unsafe Vector<double> LoadVectorNonFaulting(Vector<double> mask, double* address) { throw new PlatformNotSupportedException(); } | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,94 @@ | ||||
// 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.Runtime.CompilerServices; | ||||
using System.Runtime.Intrinsics; | ||||
using System.Numerics; | ||||
|
||||
namespace System.Runtime.Intrinsics.Arm | ||||
{ | ||||
/// <summary> | ||||
/// This class provides access to the ARM SVE hardware instructions via intrinsics | ||||
/// </summary> | ||||
[Intrinsic] | ||||
[CLSCompliant(false)] | ||||
public abstract class Sve : AdvSimd | ||||
{ | ||||
internal Sve() { } | ||||
|
||||
public static new bool IsSupported { get => IsSupported; } | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we will have to make sure to return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you know where that check would be added? not sure if that would be in the API or the part that checks if SVE is supported in the OS. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fanyang-mono - do you know? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One way of doing it is to add a new element to this array It will be something like "Sve", MONO_CPU_ARM64_SVE, unsupported, sizeof (unsupported) Additionally, you need to define the enum runtime/src/mono/mono/mini/mini.h Line 2929 in 52e1ad3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
aren't these the entries of things that are supported? so probably no SVE entry is needed in that array? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When you specify There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! I can also see some examples of unsupported in |
||||
|
||||
[Intrinsic] | ||||
public new abstract class Arm64 : AdvSimd.Arm64 | ||||
{ | ||||
internal Arm64() { } | ||||
|
||||
public static new bool IsSupported { get => IsSupported; } | ||||
} | ||||
|
||||
/// LoadVectorNonFaulting : Unextended load, non-faulting | ||||
|
||||
/// <summary> | ||||
/// svint8_t svldnf1[_s8](svbool_t pg, const int8_t *base) | ||||
/// LDNF1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<sbyte> LoadVectorNonFaulting(Vector<sbyte> mask, sbyte* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svint16_t svldnf1[_s16](svbool_t pg, const int16_t *base) | ||||
/// LDNF1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<short> LoadVectorNonFaulting(Vector<short> mask, short* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svint32_t svldnf1[_s32](svbool_t pg, const int32_t *base) | ||||
/// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<int> LoadVectorNonFaulting(Vector<int> mask, int* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svint64_t svldnf1[_s64](svbool_t pg, const int64_t *base) | ||||
/// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<long> LoadVectorNonFaulting(Vector<long> mask, long* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svuint8_t svldnf1[_u8](svbool_t pg, const uint8_t *base) | ||||
/// LDNF1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<byte> LoadVectorNonFaulting(Vector<byte> mask, byte* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svuint16_t svldnf1[_u16](svbool_t pg, const uint16_t *base) | ||||
/// LDNF1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<ushort> LoadVectorNonFaulting(Vector<ushort> mask, ushort* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svuint32_t svldnf1[_u32](svbool_t pg, const uint32_t *base) | ||||
/// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<uint> LoadVectorNonFaulting(Vector<uint> mask, uint* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svuint64_t svldnf1[_u64](svbool_t pg, const uint64_t *base) | ||||
/// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<ulong> LoadVectorNonFaulting(Vector<ulong> mask, ulong* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svfloat32_t svldnf1[_f32](svbool_t pg, const float32_t *base) | ||||
/// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<float> LoadVectorNonFaulting(Vector<float> mask, float* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
/// <summary> | ||||
/// svfloat64_t svldnf1[_f64](svbool_t pg, const float64_t *base) | ||||
/// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] | ||||
/// </summary> | ||||
public static unsafe Vector<double> LoadVectorNonFaulting(Vector<double> mask, double* address) => LoadVectorNonFaulting(mask, address); | ||||
|
||||
|
||||
} | ||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't look right. The caller should make sure to call appropriate
emitIns*
method.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, but there are lots of places this is done elsewhere:
Which means it can all use the existing table generation code. Plus, we get a handy shortcut for elsewhere where we don't need an immediate offset. This ideally needs some codegen test cases.
The alternative would be to use
HW_Flag_SpecialCodeGen
and then add a case ingenHWIntrinsic()
. That's more code and possibly slower in the long run? I suspect we'll get a lot of things added ingenHWIntrinsic()
by the end of SVE so it'd be nice to keep it short.