Skip to content

Commit 454d6e9

Browse files
authored
Arm64/Sve: Implement Compute*BitAddresses APIs (#103040)
* 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
1 parent 7107ff6 commit 454d6e9

File tree

7 files changed

+693
-6
lines changed

7 files changed

+693
-6
lines changed

src/coreclr/jit/hwintrinsiccodegenarm64.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1966,7 +1966,19 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
19661966
GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt);
19671967
break;
19681968
}
1969+
case NI_Sve_Compute8BitAddresses:
1970+
case NI_Sve_Compute16BitAddresses:
1971+
case NI_Sve_Compute32BitAddresses:
1972+
case NI_Sve_Compute64BitAddresses:
1973+
{
1974+
static_assert_no_msg(AreContiguous(NI_Sve_Compute8BitAddresses, NI_Sve_Compute16BitAddresses,
1975+
NI_Sve_Compute32BitAddresses, NI_Sve_Compute64BitAddresses));
19691976

1977+
GetEmitter()->emitInsSve_R_R_R_I(ins, EA_SCALABLE, targetReg, op1Reg, op2Reg,
1978+
(intrin.id - NI_Sve_Compute8BitAddresses), opt,
1979+
INS_SCALABLE_OPTS_LSL_N);
1980+
break;
1981+
}
19701982
default:
19711983
unreached();
19721984
}

src/coreclr/jit/hwintrinsiclistarm64sve.h

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ HARDWARE_INTRINSIC(Sve, AndAcross,
2727
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)
2828
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)
2929
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)
30+
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)
31+
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)
32+
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)
33+
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)
3034
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)
3135
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)
3236
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)

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs

+106
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,112 @@ internal Arm64() { }
640640
/// </summary>
641641
public static unsafe Vector<ulong> BooleanNot(Vector<ulong> value) { throw new PlatformNotSupportedException(); }
642642

643+
/// Compute vector addresses for 16-bit data
644+
645+
/// <summary>
646+
/// svuint32_t svadrh[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
647+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #1]
648+
/// </summary>
649+
public static unsafe Vector<uint> Compute16BitAddresses(Vector<uint> bases, Vector<int> indices) { throw new PlatformNotSupportedException(); }
650+
651+
/// <summary>
652+
/// svuint32_t svadrh[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
653+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #1]
654+
/// </summary>
655+
public static unsafe Vector<uint> Compute16BitAddresses(Vector<uint> bases, Vector<uint> indices) { throw new PlatformNotSupportedException(); }
656+
657+
/// <summary>
658+
/// svuint64_t svadrh[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
659+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #1]
660+
/// </summary>
661+
public static unsafe Vector<ulong> Compute16BitAddresses(Vector<ulong> bases, Vector<long> indices) { throw new PlatformNotSupportedException(); }
662+
663+
/// <summary>
664+
/// svuint64_t svadrh[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
665+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #1]
666+
/// </summary>
667+
public static unsafe Vector<ulong> Compute16BitAddresses(Vector<ulong> bases, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }
668+
669+
670+
/// Compute vector addresses for 32-bit data
671+
672+
/// <summary>
673+
/// svuint32_t svadrw[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
674+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #2]
675+
/// </summary>
676+
public static unsafe Vector<uint> Compute32BitAddresses(Vector<uint> bases, Vector<int> indices) { throw new PlatformNotSupportedException(); }
677+
678+
/// <summary>
679+
/// svuint32_t svadrw[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
680+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #2]
681+
/// </summary>
682+
public static unsafe Vector<uint> Compute32BitAddresses(Vector<uint> bases, Vector<uint> indices) { throw new PlatformNotSupportedException(); }
683+
684+
/// <summary>
685+
/// svuint64_t svadrw[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
686+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #2]
687+
/// </summary>
688+
public static unsafe Vector<ulong> Compute32BitAddresses(Vector<ulong> bases, Vector<long> indices) { throw new PlatformNotSupportedException(); }
689+
690+
/// <summary>
691+
/// svuint64_t svadrw[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
692+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #2]
693+
/// </summary>
694+
public static unsafe Vector<ulong> Compute32BitAddresses(Vector<ulong> bases, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }
695+
696+
697+
/// Compute vector addresses for 64-bit data
698+
699+
/// <summary>
700+
/// svuint32_t svadrd[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
701+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #3]
702+
/// </summary>
703+
public static unsafe Vector<uint> Compute64BitAddresses(Vector<uint> bases, Vector<int> indices) { throw new PlatformNotSupportedException(); }
704+
705+
/// <summary>
706+
/// svuint32_t svadrd[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
707+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #3]
708+
/// </summary>
709+
public static unsafe Vector<uint> Compute64BitAddresses(Vector<uint> bases, Vector<uint> indices) { throw new PlatformNotSupportedException(); }
710+
711+
/// <summary>
712+
/// svuint64_t svadrd[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
713+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #3]
714+
/// </summary>
715+
public static unsafe Vector<ulong> Compute64BitAddresses(Vector<ulong> bases, Vector<long> indices) { throw new PlatformNotSupportedException(); }
716+
717+
/// <summary>
718+
/// svuint64_t svadrd[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
719+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #3]
720+
/// </summary>
721+
public static unsafe Vector<ulong> Compute64BitAddresses(Vector<ulong> bases, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }
722+
723+
724+
/// Compute vector addresses for 8-bit data
725+
726+
/// <summary>
727+
/// svuint32_t svadrb[_u32base]_[s32]offset(svuint32_t bases, svint32_t offsets)
728+
/// ADR Zresult.S, [Zbases.S, Zoffsets.S]
729+
/// </summary>
730+
public static unsafe Vector<uint> Compute8BitAddresses(Vector<uint> bases, Vector<int> indices) { throw new PlatformNotSupportedException(); }
731+
732+
/// <summary>
733+
/// svuint32_t svadrb[_u32base]_[u32]offset(svuint32_t bases, svuint32_t offsets)
734+
/// ADR Zresult.S, [Zbases.S, Zoffsets.S]
735+
/// </summary>
736+
public static unsafe Vector<uint> Compute8BitAddresses(Vector<uint> bases, Vector<uint> indices) { throw new PlatformNotSupportedException(); }
737+
738+
/// <summary>
739+
/// svuint64_t svadrb[_u64base]_[s64]offset(svuint64_t bases, svint64_t offsets)
740+
/// ADR Zresult.D, [Zbases.D, Zoffsets.D]
741+
/// </summary>
742+
public static unsafe Vector<ulong> Compute8BitAddresses(Vector<ulong> bases, Vector<long> indices) { throw new PlatformNotSupportedException(); }
743+
744+
/// <summary>
745+
/// svuint64_t svadrb[_u64base]_[u64]offset(svuint64_t bases, svuint64_t offsets)
746+
/// ADR Zresult.D, [Zbases.D, Zoffsets.D]
747+
/// </summary>
748+
public static unsafe Vector<ulong> Compute8BitAddresses(Vector<ulong> bases, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }
643749

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

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs

+106
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,112 @@ internal Arm64() { }
669669
/// </summary>
670670
public static unsafe Vector<ulong> BooleanNot(Vector<ulong> value) => BooleanNot(value);
671671

672+
/// Compute vector addresses for 16-bit data
673+
674+
/// <summary>
675+
/// svuint32_t svadrh[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
676+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #1]
677+
/// </summary>
678+
public static unsafe Vector<uint> Compute16BitAddresses(Vector<uint> bases, Vector<int> indices) => Compute16BitAddresses(bases, indices);
679+
680+
/// <summary>
681+
/// svuint32_t svadrh[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
682+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #1]
683+
/// </summary>
684+
public static unsafe Vector<uint> Compute16BitAddresses(Vector<uint> bases, Vector<uint> indices) => Compute16BitAddresses(bases, indices);
685+
686+
/// <summary>
687+
/// svuint64_t svadrh[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
688+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #1]
689+
/// </summary>
690+
public static unsafe Vector<ulong> Compute16BitAddresses(Vector<ulong> bases, Vector<long> indices) => Compute16BitAddresses(bases, indices);
691+
692+
/// <summary>
693+
/// svuint64_t svadrh[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
694+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #1]
695+
/// </summary>
696+
public static unsafe Vector<ulong> Compute16BitAddresses(Vector<ulong> bases, Vector<ulong> indices) => Compute16BitAddresses(bases, indices);
697+
698+
699+
/// Compute vector addresses for 32-bit data
700+
701+
/// <summary>
702+
/// svuint32_t svadrw[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
703+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #2]
704+
/// </summary>
705+
public static unsafe Vector<uint> Compute32BitAddresses(Vector<uint> bases, Vector<int> indices) => Compute32BitAddresses(bases, indices);
706+
707+
/// <summary>
708+
/// svuint32_t svadrw[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
709+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #2]
710+
/// </summary>
711+
public static unsafe Vector<uint> Compute32BitAddresses(Vector<uint> bases, Vector<uint> indices) => Compute32BitAddresses(bases, indices);
712+
713+
/// <summary>
714+
/// svuint64_t svadrw[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
715+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #2]
716+
/// </summary>
717+
public static unsafe Vector<ulong> Compute32BitAddresses(Vector<ulong> bases, Vector<long> indices) => Compute32BitAddresses(bases, indices);
718+
719+
/// <summary>
720+
/// svuint64_t svadrw[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
721+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #2]
722+
/// </summary>
723+
public static unsafe Vector<ulong> Compute32BitAddresses(Vector<ulong> bases, Vector<ulong> indices) => Compute32BitAddresses(bases, indices);
724+
725+
726+
/// Compute vector addresses for 64-bit data
727+
728+
/// <summary>
729+
/// svuint32_t svadrd[_u32base]_[s32]index(svuint32_t bases, svint32_t indices)
730+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #3]
731+
/// </summary>
732+
public static unsafe Vector<uint> Compute64BitAddresses(Vector<uint> bases, Vector<int> indices) => Compute64BitAddresses(bases, indices);
733+
734+
/// <summary>
735+
/// svuint32_t svadrd[_u32base]_[u32]index(svuint32_t bases, svuint32_t indices)
736+
/// ADR Zresult.S, [Zbases.S, Zindices.S, LSL #3]
737+
/// </summary>
738+
public static unsafe Vector<uint> Compute64BitAddresses(Vector<uint> bases, Vector<uint> indices) => Compute64BitAddresses(bases, indices);
739+
740+
/// <summary>
741+
/// svuint64_t svadrd[_u64base]_[s64]index(svuint64_t bases, svint64_t indices)
742+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #3]
743+
/// </summary>
744+
public static unsafe Vector<ulong> Compute64BitAddresses(Vector<ulong> bases, Vector<long> indices) => Compute64BitAddresses(bases, indices);
745+
746+
/// <summary>
747+
/// svuint64_t svadrd[_u64base]_[u64]index(svuint64_t bases, svuint64_t indices)
748+
/// ADR Zresult.D, [Zbases.D, Zindices.D, LSL #3]
749+
/// </summary>
750+
public static unsafe Vector<ulong> Compute64BitAddresses(Vector<ulong> bases, Vector<ulong> indices) => Compute64BitAddresses(bases, indices);
751+
752+
753+
/// Compute vector addresses for 8-bit data
754+
755+
/// <summary>
756+
/// svuint32_t svadrb[_u32base]_[s32]offset(svuint32_t bases, svint32_t offsets)
757+
/// ADR Zresult.S, [Zbases.S, Zoffsets.S]
758+
/// </summary>
759+
public static unsafe Vector<uint> Compute8BitAddresses(Vector<uint> bases, Vector<int> indices) => Compute8BitAddresses(bases, indices);
760+
761+
/// <summary>
762+
/// svuint32_t svadrb[_u32base]_[u32]offset(svuint32_t bases, svuint32_t offsets)
763+
/// ADR Zresult.S, [Zbases.S, Zoffsets.S]
764+
/// </summary>
765+
public static unsafe Vector<uint> Compute8BitAddresses(Vector<uint> bases, Vector<uint> indices) => Compute8BitAddresses(bases, indices);
766+
767+
/// <summary>
768+
/// svuint64_t svadrb[_u64base]_[s64]offset(svuint64_t bases, svint64_t offsets)
769+
/// ADR Zresult.D, [Zbases.D, Zoffsets.D]
770+
/// </summary>
771+
public static unsafe Vector<ulong> Compute8BitAddresses(Vector<ulong> bases, Vector<long> indices) => Compute8BitAddresses(bases, indices);
772+
773+
/// <summary>
774+
/// svuint64_t svadrb[_u64base]_[u64]offset(svuint64_t bases, svuint64_t offsets)
775+
/// ADR Zresult.D, [Zbases.D, Zoffsets.D]
776+
/// </summary>
777+
public static unsafe Vector<ulong> Compute8BitAddresses(Vector<ulong> bases, Vector<ulong> indices) => Compute8BitAddresses(bases, indices);
672778

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

0 commit comments

Comments
 (0)