Skip to content

Commit

Permalink
Arm64/Sve: Implement Compute*BitAddresses APIs (#103040)
Browse files Browse the repository at this point in the history
* Add Compute*Addresses() APIs

* Map API to instruction

* Map API to instruction

* Add test coverage

* add validation

* fix test

* review feedback

* fix some more tests
  • Loading branch information
kunalspathak authored Jun 5, 2024
1 parent 7107ff6 commit 454d6e9
Show file tree
Hide file tree
Showing 7 changed files with 693 additions and 6 deletions.
12 changes: 12 additions & 0 deletions src/coreclr/jit/hwintrinsiccodegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1966,7 +1966,19 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt);
break;
}
case NI_Sve_Compute8BitAddresses:
case NI_Sve_Compute16BitAddresses:
case NI_Sve_Compute32BitAddresses:
case NI_Sve_Compute64BitAddresses:
{
static_assert_no_msg(AreContiguous(NI_Sve_Compute8BitAddresses, NI_Sve_Compute16BitAddresses,
NI_Sve_Compute32BitAddresses, NI_Sve_Compute64BitAddresses));

GetEmitter()->emitInsSve_R_R_R_I(ins, EA_SCALABLE, targetReg, op1Reg, op2Reg,
(intrin.id - NI_Sve_Compute8BitAddresses), opt,
INS_SCALABLE_OPTS_LSL_N);
break;
}
default:
unreached();
}
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/hwintrinsiclistarm64sve.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ HARDWARE_INTRINSIC(Sve, AndAcross,
HARDWARE_INTRINSIC(Sve, BitwiseClear, -1, -1, false, {INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, BooleanNot, -1, -1, false, {INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, Compact, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation)
HARDWARE_INTRINSIC(Sve, Compute8BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, Compute16BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, Compute32BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, Compute64BitAddresses, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adr, INS_invalid, INS_sve_adr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve, ConditionalSelect, -1, 3, true, {INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_SupportsContainment)
HARDWARE_INTRINSIC(Sve, Count16BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cnth, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed)
HARDWARE_INTRINSIC(Sve, Count32BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,112 @@ internal Arm64() { }
/// </summary>
public static unsafe Vector<ulong> BooleanNot(Vector<ulong> value) { throw new PlatformNotSupportedException(); }

/// Compute vector addresses for 16-bit data

/// <summary>
/// svuint32_t svadrh[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #1]
/// </summary>
public static unsafe Vector<uint> Compute16BitAddresses(Vector<uint> bases, Vector<int> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint32_t svadrh[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #1]
/// </summary>
public static unsafe Vector<uint> Compute16BitAddresses(Vector<uint> bases, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svadrh[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #1]
/// </summary>
public static unsafe Vector<ulong> Compute16BitAddresses(Vector<ulong> bases, Vector<long> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svadrh[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #1]
/// </summary>
public static unsafe Vector<ulong> Compute16BitAddresses(Vector<ulong> bases, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }


/// Compute vector addresses for 32-bit data

/// <summary>
/// svuint32_t svadrw[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #2]
/// </summary>
public static unsafe Vector<uint> Compute32BitAddresses(Vector<uint> bases, Vector<int> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint32_t svadrw[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #2]
/// </summary>
public static unsafe Vector<uint> Compute32BitAddresses(Vector<uint> bases, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svadrw[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #2]
/// </summary>
public static unsafe Vector<ulong> Compute32BitAddresses(Vector<ulong> bases, Vector<long> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svadrw[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #2]
/// </summary>
public static unsafe Vector<ulong> Compute32BitAddresses(Vector<ulong> bases, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }


/// Compute vector addresses for 64-bit data

/// <summary>
/// svuint32_t svadrd[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #3]
/// </summary>
public static unsafe Vector<uint> Compute64BitAddresses(Vector<uint> bases, Vector<int> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint32_t svadrd[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #3]
/// </summary>
public static unsafe Vector<uint> Compute64BitAddresses(Vector<uint> bases, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svadrd[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #3]
/// </summary>
public static unsafe Vector<ulong> Compute64BitAddresses(Vector<ulong> bases, Vector<long> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svadrd[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #3]
/// </summary>
public static unsafe Vector<ulong> Compute64BitAddresses(Vector<ulong> bases, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }


/// Compute vector addresses for 8-bit data

/// <summary>
/// svuint32_t svadrb[_u32base]_[s32]offset(svuint32_t bases, svint32_t offsets)
/// ADR Zresult.S, [Zbases.S, Zoffsets.S]
/// </summary>
public static unsafe Vector<uint> Compute8BitAddresses(Vector<uint> bases, Vector<int> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint32_t svadrb[_u32base]_[u32]offset(svuint32_t bases, svuint32_t offsets)
/// ADR Zresult.S, [Zbases.S, Zoffsets.S]
/// </summary>
public static unsafe Vector<uint> Compute8BitAddresses(Vector<uint> bases, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svadrb[_u64base]_[s64]offset(svuint64_t bases, svint64_t offsets)
/// ADR Zresult.D, [Zbases.D, Zoffsets.D]
/// </summary>
public static unsafe Vector<ulong> Compute8BitAddresses(Vector<ulong> bases, Vector<long> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svadrb[_u64base]_[u64]offset(svuint64_t bases, svuint64_t offsets)
/// ADR Zresult.D, [Zbases.D, Zoffsets.D]
/// </summary>
public static unsafe Vector<ulong> Compute8BitAddresses(Vector<ulong> bases, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }

/// Shuffle active elements of vector to the right and fill with zero

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,112 @@ internal Arm64() { }
/// </summary>
public static unsafe Vector<ulong> BooleanNot(Vector<ulong> value) => BooleanNot(value);

/// Compute vector addresses for 16-bit data

/// <summary>
/// svuint32_t svadrh[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #1]
/// </summary>
public static unsafe Vector<uint> Compute16BitAddresses(Vector<uint> bases, Vector<int> indices) => Compute16BitAddresses(bases, indices);

/// <summary>
/// svuint32_t svadrh[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #1]
/// </summary>
public static unsafe Vector<uint> Compute16BitAddresses(Vector<uint> bases, Vector<uint> indices) => Compute16BitAddresses(bases, indices);

/// <summary>
/// svuint64_t svadrh[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #1]
/// </summary>
public static unsafe Vector<ulong> Compute16BitAddresses(Vector<ulong> bases, Vector<long> indices) => Compute16BitAddresses(bases, indices);

/// <summary>
/// svuint64_t svadrh[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #1]
/// </summary>
public static unsafe Vector<ulong> Compute16BitAddresses(Vector<ulong> bases, Vector<ulong> indices) => Compute16BitAddresses(bases, indices);


/// Compute vector addresses for 32-bit data

/// <summary>
/// svuint32_t svadrw[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #2]
/// </summary>
public static unsafe Vector<uint> Compute32BitAddresses(Vector<uint> bases, Vector<int> indices) => Compute32BitAddresses(bases, indices);

/// <summary>
/// svuint32_t svadrw[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #2]
/// </summary>
public static unsafe Vector<uint> Compute32BitAddresses(Vector<uint> bases, Vector<uint> indices) => Compute32BitAddresses(bases, indices);

/// <summary>
/// svuint64_t svadrw[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #2]
/// </summary>
public static unsafe Vector<ulong> Compute32BitAddresses(Vector<ulong> bases, Vector<long> indices) => Compute32BitAddresses(bases, indices);

/// <summary>
/// svuint64_t svadrw[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #2]
/// </summary>
public static unsafe Vector<ulong> Compute32BitAddresses(Vector<ulong> bases, Vector<ulong> indices) => Compute32BitAddresses(bases, indices);


/// Compute vector addresses for 64-bit data

/// <summary>
/// svuint32_t svadrd[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #3]
/// </summary>
public static unsafe Vector<uint> Compute64BitAddresses(Vector<uint> bases, Vector<int> indices) => Compute64BitAddresses(bases, indices);

/// <summary>
/// svuint32_t svadrd[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #3]
/// </summary>
public static unsafe Vector<uint> Compute64BitAddresses(Vector<uint> bases, Vector<uint> indices) => Compute64BitAddresses(bases, indices);

/// <summary>
/// svuint64_t svadrd[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #3]
/// </summary>
public static unsafe Vector<ulong> Compute64BitAddresses(Vector<ulong> bases, Vector<long> indices) => Compute64BitAddresses(bases, indices);

/// <summary>
/// svuint64_t svadrd[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #3]
/// </summary>
public static unsafe Vector<ulong> Compute64BitAddresses(Vector<ulong> bases, Vector<ulong> indices) => Compute64BitAddresses(bases, indices);


/// Compute vector addresses for 8-bit data

/// <summary>
/// svuint32_t svadrb[_u32base]_[s32]offset(svuint32_t bases, svint32_t offsets)
/// ADR Zresult.S, [Zbases.S, Zoffsets.S]
/// </summary>
public static unsafe Vector<uint> Compute8BitAddresses(Vector<uint> bases, Vector<int> indices) => Compute8BitAddresses(bases, indices);

/// <summary>
/// svuint32_t svadrb[_u32base]_[u32]offset(svuint32_t bases, svuint32_t offsets)
/// ADR Zresult.S, [Zbases.S, Zoffsets.S]
/// </summary>
public static unsafe Vector<uint> Compute8BitAddresses(Vector<uint> bases, Vector<uint> indices) => Compute8BitAddresses(bases, indices);

/// <summary>
/// svuint64_t svadrb[_u64base]_[s64]offset(svuint64_t bases, svint64_t offsets)
/// ADR Zresult.D, [Zbases.D, Zoffsets.D]
/// </summary>
public static unsafe Vector<ulong> Compute8BitAddresses(Vector<ulong> bases, Vector<long> indices) => Compute8BitAddresses(bases, indices);

/// <summary>
/// svuint64_t svadrb[_u64base]_[u64]offset(svuint64_t bases, svuint64_t offsets)
/// ADR Zresult.D, [Zbases.D, Zoffsets.D]
/// </summary>
public static unsafe Vector<ulong> Compute8BitAddresses(Vector<ulong> bases, Vector<ulong> indices) => Compute8BitAddresses(bases, indices);

/// Shuffle active elements of vector to the right and fill with zero

Expand Down
Loading

0 comments on commit 454d6e9

Please sign in to comment.