Skip to content
Merged
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
28 changes: 28 additions & 0 deletions src/coreclr/jit/hwintrinsicarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3377,6 +3377,34 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}

case NI_Sve2_VectorTableLookup:
{
assert(sig->numArgs == 2);
assert(retType != TYP_VOID);

CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;
var_types argType1 = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass)));
var_types argType2 = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));

var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType);
CorInfoType op1BaseJitType = getBaseJitTypeOfSIMDType(argClass);

op2 = impPopStack().val;
op1 = impPopStack().val;

if (op1->TypeIs(TYP_STRUCT))
{
info.compNeedsConsecutiveRegisters = true;
unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(argClass);
op1 = gtConvertTableOpToFieldList(op1, fieldCount);
}
retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize);
retNode->AsHWIntrinsic()->SetAuxiliaryJitType(op1BaseJitType);
break;
}

default:
{
return nullptr;
Expand Down
24 changes: 24 additions & 0 deletions src/coreclr/jit/hwintrinsiccodegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1722,6 +1722,30 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
break;
}

case NI_Sve2_VectorTableLookup:
{
assert(intrin.op1->OperIsFieldList());
GenTreeFieldList* fieldList = intrin.op1->AsFieldList();
GenTree* firstField = fieldList->Uses().GetHead()->GetNode();
op1Reg = firstField->GetRegNum();
#ifdef DEBUG
unsigned regCount = 0;
regNumber argReg = op1Reg;
for (GenTreeFieldList::Use& use : fieldList->Uses())
{
regCount++;

GenTree* argNode = use.GetNode();
assert(argReg == argNode->GetRegNum());
argReg = getNextSIMDRegWithWraparound(argReg);
}
assert(regCount == 2);
#endif
GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt,
INS_SCALABLE_OPTS_WITH_VECTOR_PAIR);
break;
}

case NI_Sve_StoreAndZipx2:
case NI_Sve_StoreAndZipx3:
case NI_Sve_StoreAndZipx4:
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/hwintrinsiclistarm64sve.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingEven,
HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingOdd, -1, 3, {INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingSaturateEven, -1, 2, {INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand)
HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingSaturateOdd, -1, 3, {INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(Sve2, VectorTableLookup, -1, 2, {INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_NeedsConsecutiveRegisters|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Sve2, VectorTableLookupExtension, -1, 3, {INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(Sve2, Xor, -1, 3, {INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(Sve2, XorRotateRight, -1, 3, {INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand)
#define LAST_NI_Sve2 NI_Sve2_XorRotateRight
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/lsraarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2400,6 +2400,7 @@ GenTree* LinearScan::getConsecutiveRegistersOperand(const HWIntrinsic intrin, bo
{
case NI_AdvSimd_Arm64_VectorTableLookup:
case NI_AdvSimd_VectorTableLookup:
case NI_Sve2_VectorTableLookup:
consecutiveOp = intrin.op1;
assert(consecutiveOp != nullptr);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,132 @@ internal Arm64() { }
public static Vector<uint> ShiftRightLogicalRoundedNarrowingSaturateOdd(Vector<uint> even, Vector<ulong> value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); }


// Bit vector table lookups

/// <summary>
/// svuint8_t svtbl2[_u8](svuint8x2_t data, svuint8_t indices)
/// TBL Zd.B, { Zn1.B, Zn2.B }, Zm.B
/// </summary>
public static unsafe Vector<byte> VectorTableLookup((Vector<byte> data1, Vector<byte> data2) table, Vector<byte> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint16_t svtbl2[_u16](svuint16x2_t data, svuint16_t indices)
/// TBL Zd.H, { Zn1.H, Zn2.H }, Zm.H
/// </summary>
public static unsafe Vector<ushort> VectorTableLookup((Vector<ushort> data1, Vector<ushort> data2) table, Vector<ushort> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint32_t svtbl2[_u32](svuint32x2_t data, svuint32_t indices)
/// TBL Zd.S, { Zn1.S, Zn2.S }, Zm.S
/// </summary>
public static unsafe Vector<uint> VectorTableLookup((Vector<uint> data1, Vector<uint> data2) table, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svtbl2[_u64](svuint64x2_t data, svuint64_t indices)
/// TBL Zd.D, { Zn1.D, Zn2.D }, Zm.D
/// </summary>
public static unsafe Vector<ulong> VectorTableLookup((Vector<ulong> data1, Vector<ulong> data2) table, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svfloat32_t svtbl2[_f32](svfloat32x2_t data, svuint32_t indices)
/// TBL Zd.S, { Zn1.S, Zn2.S }, Zm.S
/// </summary>
public static unsafe Vector<float> VectorTableLookup((Vector<float> data1, Vector<float> data2) table, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svfloat64_t svtbl2[_f64](svfloat64x2_t data, svuint64_t indices)
/// TBL Zd.D, { Zn1.D, Zn2.D }, Zm.D
/// </summary>
public static unsafe Vector<double> VectorTableLookup((Vector<double> data1, Vector<double> data2) table, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svint8_t svtbl2[_s8](svint8x2_t data, svuint8_t indices)
/// TBL Zd.B, { Zn1.B, Zn2.B }, Zm.B
/// </summary>
public static unsafe Vector<sbyte> VectorTableLookup((Vector<sbyte> data1, Vector<sbyte> data2) table, Vector<byte> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svint16_t svtbl2[_s16](svint16x2_t data, svuint16_t indices)
/// TBL Zd.H, { Zn1.H, Zn2.H }, Zm.H
/// </summary>
public static unsafe Vector<short> VectorTableLookup((Vector<short> data1, Vector<short> data2) table, Vector<ushort> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svint32_t svtbl2[_s32](svint32x2_t data, svuint32_t indices)
/// TBL Zd.S, { Zn1.S, Zn2.S }, Zm.S
/// </summary>
public static unsafe Vector<int> VectorTableLookup((Vector<int> data1, Vector<int> data2) table, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svint64_t svtbl2[_s64](svint64x2_t data, svuint64_t indices)
/// TBL Zd.D, { Zn1.D, Zn2.D }, Zm.D
/// </summary>
public static unsafe Vector<long> VectorTableLookup((Vector<long> data1, Vector<long> data2) table, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }


// Bit vector table lookup extensions

/// <summary>
/// svuint8_t svtbx[_u8](svuint8_t fallback, svuint8_t data, svuint8_t indices)
/// TBX Zd.B, Zn.B, Zm.B
/// </summary>
public static unsafe Vector<byte> VectorTableLookupExtension(Vector<byte> defaultValues, Vector<byte> data, Vector<byte> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint16_t svtbx[_u16](svuint16_t fallback, svuint16_t data, svuint16_t indices)
/// TBX Zd.H, Zn.H, Zm.H
/// </summary>
public static unsafe Vector<ushort> VectorTableLookupExtension(Vector<ushort> defaultValues, Vector<ushort> data, Vector<ushort> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint32_t svtbx[_u32](svuint32_t fallback, svuint32_t data, svuint32_t indices)
/// TBX Zd.S, Zn.S, Zm.S
/// </summary>
public static unsafe Vector<uint> VectorTableLookupExtension(Vector<uint> defaultValues, Vector<uint> data, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svuint64_t svtbx[_u64](svuint64_t fallback, svuint64_t data, svuint64_t indices)
/// TBX Zd.D, Zn.D, Zm.D
/// </summary>
public static unsafe Vector<ulong> VectorTableLookupExtension(Vector<ulong> defaultValues, Vector<ulong> data, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svfloat32_t svtbx[_f32](svfloat32_t fallback, svfloat32_t data, svuint32_t indices)
/// TBX Zd.S, Zn.S, Zm.S
/// </summary>
public static unsafe Vector<float> VectorTableLookupExtension(Vector<float> defaultValues, Vector<float> data, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svfloat64_t svtbx[_f64](svfloat64_t fallback, svfloat64_t data, svuint64_t indices)
/// TBX Zd.D, Zn.D, Zm.D
/// </summary>
public static unsafe Vector<double> VectorTableLookupExtension(Vector<double> defaultValues, Vector<double> data, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svint8_t svtbx[_s8](svint8_t fallback, svint8_t data, svuint8_t indices)
/// TBX Zd.B, Zn.B, Zm.B
/// </summary>
public static unsafe Vector<sbyte> VectorTableLookupExtension(Vector<sbyte> defaultValues, Vector<sbyte> data, Vector<byte> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svint16_t svtbx[_s16](svint16_t fallback, svint16_t data, svuint16_t indices)
/// TBX Zd.H, Zn.H, Zm.H
/// </summary>
public static unsafe Vector<short> VectorTableLookupExtension(Vector<short> defaultValues, Vector<short> data, Vector<ushort> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svint32_t svtbx[_s32](svint32_t fallback, svint32_t data, svuint32_t indices)
/// TBX Zd.S, Zn.S, Zm.S
/// </summary>
public static unsafe Vector<int> VectorTableLookupExtension(Vector<int> defaultValues, Vector<int> data, Vector<uint> indices) { throw new PlatformNotSupportedException(); }

/// <summary>
/// svint64_t svtbx[_s64](svint64_t fallback, svint64_t data, svuint64_t indices)
/// TBX Zd.D, Zn.D, Zm.D
/// </summary>
public static unsafe Vector<long> VectorTableLookupExtension(Vector<long> defaultValues, Vector<long> data, Vector<ulong> indices) { throw new PlatformNotSupportedException(); }


// Bitwise exclusive OR of three vectors

/// <summary>
Expand Down
Loading
Loading