Skip to content
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

Arm64: Implement VectorTableLookup/VectorTableLookupExtension intrinsinsic + Consecutive registers support #80297

Merged
merged 136 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
136 commits
Select commit Hold shift + click to select a range
c92fbdf
Add VectorTableLookup 2/3/4 in hwinstrinsiclistarm64.h
kunalspathak Dec 10, 2022
bee0f8c
Add VectorTableLookup
kunalspathak Dec 10, 2022
426f68a
fixes to libraries
kunalspathak Dec 10, 2022
83eb54c
Prototype of simple tbl
kunalspathak Dec 14, 2022
d06c4a2
Some progress
kunalspathak Dec 15, 2022
99adc17
Some more updates
kunalspathak Dec 25, 2022
7b10969
working model
kunalspathak Jan 4, 2023
87f66f7
Vector64<byte> support
kunalspathak Jan 5, 2023
98e7bd2
Add VectorTableLookup_3
kunalspathak Jan 5, 2023
786e350
Add VectorTableLookup_4
kunalspathak Jan 5, 2023
e0a82b3
cleanup
kunalspathak Jan 5, 2023
47848b0
Remove regCount from LclVarDsc
kunalspathak Jan 5, 2023
25a738d
Some more cleanup
kunalspathak Jan 5, 2023
e492829
setNextConsecutiveRegisterAssignment
kunalspathak Jan 5, 2023
385abf1
Some more cleanup
kunalspathak Jan 6, 2023
2f4a4e3
TARGET_ARM64
kunalspathak Jan 6, 2023
8d3744b
Use getNextConsecutiveRefPositions instead of nextConsecutiveRefPosit…
kunalspathak Jan 6, 2023
8d66d45
jit format
kunalspathak Jan 6, 2023
85d90f5
Move getNextConsecutiveRefPosition
kunalspathak Jan 6, 2023
0a0faed
SA1141: Use tuple syntax
kunalspathak Jan 6, 2023
036a273
Remove the unwanted field list code
kunalspathak Jan 9, 2023
791563a
revert the flag that was mistakenly changed
kunalspathak Jan 9, 2023
db6036b
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Jan 9, 2023
fdc94ed
Add test cases
kunalspathak Jan 12, 2023
cf84fda
FIELD_LIST
kunalspathak Jan 21, 2023
06a78d4
Use FIELD_LIST approach
kunalspathak Jan 24, 2023
2afe249
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Jan 24, 2023
a086ab7
jit format and fix arm build
kunalspathak Jan 24, 2023
450a08d
fix assert failure
kunalspathak Jan 24, 2023
5bb9302
Add summary docs
kunalspathak Jan 25, 2023
8027c5a
Make APIs public again
kunalspathak Jan 25, 2023
6b1ba8a
cleanup
kunalspathak Jan 25, 2023
723477b
Handle case for reg mod 32
kunalspathak Jan 25, 2023
c6e77e4
Remove references from ref until API is approved
kunalspathak Jan 25, 2023
5696a6e
Use generic getFreeCandidates()
kunalspathak Jan 25, 2023
a9e1a7a
Add entries in ExtraAPis
kunalspathak Jan 25, 2023
2617b77
Set CLSCompliant=false
kunalspathak Jan 25, 2023
2d4fd5c
Move in inner class
kunalspathak Jan 25, 2023
6a21205
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Jan 26, 2023
c6d338f
Remove CLSCompliant flag
kunalspathak Jan 26, 2023
db4f846
Add a suppression file for System.Runtime.Intrinsics on the new APIs …
tannergooding Jan 26, 2023
bce8c5a
Review feedback
kunalspathak Feb 1, 2023
3d15fcb
Add workaround for building tests
kunalspathak Feb 1, 2023
75f142b
review feedback
kunalspathak Feb 1, 2023
e4cbad9
TP: remove needsConsecutive parameter from BuildUse()
kunalspathak Feb 1, 2023
96de024
TP: Remove pseudo intrinsic entries
kunalspathak Feb 1, 2023
11b345a
More fixes
kunalspathak Feb 2, 2023
4526b41
Add the missing csproj
kunalspathak Feb 2, 2023
46f0abd
Fix test cases
kunalspathak Feb 3, 2023
6ef7c68
Add fake lib for AdvSimd.Arm64* as well
kunalspathak Feb 3, 2023
b0b6a5e
Remove the workaround
kunalspathak Feb 4, 2023
0197b73
Use template to control if consecutive registers is needed or not
kunalspathak Feb 4, 2023
2734023
jit format
kunalspathak Feb 4, 2023
1cb22d0
fix the workaround
kunalspathak Feb 4, 2023
6e30b3a
Revert "fix the workaround"
kunalspathak Feb 4, 2023
721823b
Revert "Remove the workaround"
kunalspathak Feb 4, 2023
5b9fac5
Add VectorTableLookupExtensions in libraries
kunalspathak Feb 6, 2023
cb29aee
Add support for VectorTableLookupExtension
kunalspathak Feb 8, 2023
53b07b5
WIP: available regs
kunalspathak Feb 8, 2023
302d3ba
WIP: Remove test hacks
kunalspathak Feb 8, 2023
5e828f1
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Feb 8, 2023
fc93cc2
Update getFreeCandidates() for consecutive registers
kunalspathak Feb 10, 2023
78e87cd
Add missing resetRegState()
kunalspathak Feb 10, 2023
60d383e
Do not assume the current assigned register for consecutiveRegisters …
kunalspathak Feb 10, 2023
05f9fc6
Handle case for copyReg
kunalspathak Feb 10, 2023
b52059e
Update setNextConsecutiveRegister() with UPPER_VECTOR_RESTORE
kunalspathak Feb 10, 2023
0721ad4
Update code around copyReg
kunalspathak Feb 10, 2023
8a5c696
Create the VectorTableLookup fake CoreLib as a reference assembly
lambdageek Feb 14, 2023
e64527b
Rename VectorTableLookup to VectorTableLookup.RefOnly
kunalspathak Feb 14, 2023
22270c5
Start consecutive refpositions with RefTypeUse and never with RefType…
kunalspathak Feb 16, 2023
f3884fd
Add test cases for VectorTableLookupExtension
kunalspathak Feb 16, 2023
f2a1f19
Pass the missing defaultValues
kunalspathak Feb 20, 2023
985fe25
Use platform neutral BitScanForward
kunalspathak Feb 20, 2023
ab043fd
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Feb 21, 2023
13601eb
jit format
kunalspathak Feb 21, 2023
7bf9105
Remove the fake testlib workaround
kunalspathak Feb 26, 2023
40aa7c7
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Feb 26, 2023
1f95637
Fix mono failures
kunalspathak Feb 26, 2023
e7bb069
Fix x64 TP regression
kunalspathak Feb 26, 2023
6ebb12a
Fix test cases
kunalspathak Feb 27, 2023
2d75291
fix some more tp regression
kunalspathak Feb 27, 2023
68cd4d7
Fix test build
kunalspathak Feb 27, 2023
7b83053
misc. changes
kunalspathak Feb 28, 2023
903c3de
Fix the bug where we were not freeing copyReg causing an assert in tier0
kunalspathak Mar 1, 2023
a8ec819
Refactor little bit to reduce checks for VectorTableLookup
kunalspathak Mar 1, 2023
961e9c2
Add template parameter for allocateReg/copyReg/select
kunalspathak Mar 2, 2023
b9d0f15
Comments
kunalspathak Mar 2, 2023
cbe999f
Fix mono failures
kunalspathak Mar 2, 2023
6665536
Added some more comments
kunalspathak Mar 7, 2023
2b9f49e
Call allocateReg/assignCopyReg/select methods only for refpositions t…
kunalspathak Mar 17, 2023
5fec6e1
Add heuristics to pick best possible set of registers which will need…
kunalspathak Mar 19, 2023
5371c30
setNextConsecutiveRegisterAssignment() no longer checks for areNextCo…
kunalspathak Mar 19, 2023
4875925
Rename getFreeCandidates() -> getConsecutiveCandidates()
kunalspathak Mar 19, 2023
597e6de
fix parameters to areNextConsecutiveRegistersFree()
kunalspathak Mar 19, 2023
4a1171d
Rename and update canAssignNextConsecutiveRegisters()
kunalspathak Mar 19, 2023
1f124a4
Add the missing setNextConsecutiveRegisterAssignment() calls
kunalspathak Mar 19, 2023
9686773
Fix a condition for upperVector
kunalspathak Mar 21, 2023
55071f6
Update spill heurisitic to handle cases for jitstressregs
kunalspathak Mar 21, 2023
757c682
Misc. remove popcount() check from getConsecutiveRegisters()
kunalspathak Mar 21, 2023
79e0bd5
jit format
kunalspathak Mar 21, 2023
a44cf60
Fix a bug in canAssignNextConsecutiveRegisters()
kunalspathak Mar 22, 2023
5fefae6
Add filterConsecutiveCandidates() and perform free/busy candidates scan
kunalspathak Mar 22, 2023
2a5e52c
Consume the new free/busy consecutive candidates method
kunalspathak Mar 22, 2023
a17b44f
Handle case where 'copyReg == assignedReg'
kunalspathak Mar 22, 2023
3c390d8
Misc. cleanup
kunalspathak Mar 22, 2023
a9995e6
Include LsraExtraFPSetForConsecutive for stress regs
kunalspathak Mar 22, 2023
ae2e633
handle case where 'assignedInterval == nullptr' for try_SPILL_COST()
kunalspathak Mar 22, 2023
02f8ad2
fix build error
kunalspathak Mar 22, 2023
984c6ee
Call consecutiveCandidates() only for first refposition
kunalspathak Mar 22, 2023
8fe130a
Only perform special handling for non-uppervectorrestore
kunalspathak Mar 22, 2023
7f8e77f
jit format
kunalspathak Mar 22, 2023
090bf26
Add impVectorTableLookup/impVectorTableLookupExtension
kunalspathak Mar 22, 2023
c91bc77
Add the missing break
kunalspathak Mar 22, 2023
1591deb
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Mar 22, 2023
0c4d71f
Update assert
kunalspathak Mar 22, 2023
0c56514
Move definitions in GenTree, fix assert
kunalspathak Mar 22, 2023
35a7550
fix arm issue
kunalspathak Mar 23, 2023
ff587ac
Remove common functions
kunalspathak Mar 23, 2023
dab2121
Rename info.needsConsecutiveRegisters to info.compNeedsConsecutiveReg…
kunalspathak Mar 23, 2023
e94cfcf
Use needsConsecutiveRegisters template parameter for all configurations
kunalspathak Mar 23, 2023
ab007d0
Handle case of round-robin in getConsecutiveRegisters()
kunalspathak Mar 23, 2023
5d6cc2d
Disable tests for Mono
kunalspathak Mar 24, 2023
24e6158
Initialize outArray in test
kunalspathak Mar 26, 2023
4026aa6
Add IsSupported checks for VectorLookup/VectorLookupExtension
kunalspathak Mar 30, 2023
53c91f0
Fix the test cases for RunReflectionScenario_UnsafeRead()
kunalspathak Mar 30, 2023
7d168b2
Review feedback
kunalspathak Mar 30, 2023
7cffe7a
wip
kunalspathak Mar 30, 2023
dd10bbe
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Mar 30, 2023
b4ea77e
Merge branch 'tbl_tbx_temp' into tbl_tbx
kunalspathak Mar 30, 2023
0dc4ea6
fix a typo in test case
kunalspathak Mar 30, 2023
6d9e136
Add filterConsecutiveCandidatesForSpill() to select range that needs …
kunalspathak Mar 30, 2023
f247b3c
Add mono support.
vargaz Mar 31, 2023
e8d3ee5
Delay free the registers for VectorTableLookupExtension
kunalspathak Apr 1, 2023
524d983
Merge commit 'f247b3c6408c60b751999ca30710005d2db9a044' into tbl_tbx
kunalspathak Apr 1, 2023
289110d
Merge remote-tracking branch 'origin/main' into tbl_tbx
kunalspathak Apr 3, 2023
d778833
fix mono build error
kunalspathak Apr 3, 2023
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
8 changes: 8 additions & 0 deletions src/coreclr/jit/codegenlinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1624,6 +1624,14 @@ void CodeGen::genConsumeRegs(GenTree* tree)
genConsumeRegs(tree->gtGetOp1());
genConsumeRegs(tree->gtGetOp2());
}
else if (tree->OperIsFieldList())
{
for (GenTreeFieldList::Use& use : tree->AsFieldList()->Uses())
{
GenTree* fieldNode = use.GetNode();
genConsumeRegs(fieldNode);
}
}
#endif
else if (tree->OperIsLocalRead())
{
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6718,6 +6718,10 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
compBasicBlockID = 0;
#endif

#ifdef TARGET_ARM64
info.compNeedsConsecutiveRegisters = false;
#endif

/* Initialize emitter */

if (!compIsForInlining())
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2809,6 +2809,10 @@ class Compiler
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_SIG_INFO* sig,
CorInfoType simdBaseJitType);

#ifdef TARGET_ARM64
GenTreeFieldList* gtConvertTableOpToFieldList(GenTree* op, unsigned fieldCount);
#endif
#endif // FEATURE_HW_INTRINSICS

GenTree* gtNewMustThrowException(unsigned helper, var_types type, CORINFO_CLASS_HANDLE clsHnd);
Expand Down Expand Up @@ -10061,6 +10065,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Number of class profile probes in this method
unsigned compHandleHistogramProbeCount;

#ifdef TARGET_ARM64
bool compNeedsConsecutiveRegisters;
#endif

} info;

ReturnTypeDesc compRetTypeDesc; // ABI return type descriptor for the method
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/fginline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1447,6 +1447,10 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)

lvaGenericsContextInUse |= InlineeCompiler->lvaGenericsContextInUse;

#ifdef TARGET_ARM64
info.compNeedsConsecutiveRegisters |= InlineeCompiler->info.compNeedsConsecutiveRegisters;
#endif

// If the inlinee compiler encounters switch tables, disable hot/cold splitting in the root compiler.
// TODO-CQ: Implement hot/cold splitting of methods with switch tables.
if (InlineeCompiler->fgHasSwitch && opts.compProcedureSplitting)
Expand Down
33 changes: 33 additions & 0 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23016,6 +23016,7 @@ GenTree* Compiler::gtNewSimdShuffleNode(var_types type,
op2->AsVecCon()->gtSimdVal = vecCns;

return gtNewSimdHWIntrinsicNode(type, op1, op2, lookupIntrinsic, simdBaseJitType, simdSize, isSimdAsHWIntrinsic);

#else
#error Unsupported platform
#endif // !TARGET_XARCH && !TARGET_ARM64
Expand Down Expand Up @@ -23885,6 +23886,38 @@ GenTree* Compiler::gtNewSimdWithElementNode(var_types type,
return gtNewSimdHWIntrinsicNode(type, op1, op2, op3, hwIntrinsicID, simdBaseJitType, simdSize, isSimdAsHWIntrinsic);
}

#ifdef TARGET_ARM64
//------------------------------------------------------------------------
// gtConvertTableOpToFieldList: Convert a operand that represents table of rows into
// field list, where each field represents a row in the table.
//
// Arguments:
// op -- Operand to convert.
// fieldCount -- Number of fields or rows present.
//
// Return Value:
// The GenTreeFieldList node.
//
GenTreeFieldList* Compiler::gtConvertTableOpToFieldList(GenTree* op, unsigned fieldCount)
kunalspathak marked this conversation as resolved.
Show resolved Hide resolved
{
LclVarDsc* opVarDsc = lvaGetDesc(op->AsLclVar());
unsigned lclNum = lvaGetLclNum(opVarDsc);
unsigned fieldSize = opVarDsc->lvSize() / fieldCount;
var_types fieldType = TYP_SIMD16;

GenTreeFieldList* fieldList = new (this, GT_FIELD_LIST) GenTreeFieldList();
int offset = 0;
for (unsigned fieldId = 0; fieldId < fieldCount; fieldId++)
{
GenTreeLclFld* fldNode = gtNewLclFldNode(lclNum, fieldType, offset);
fieldList->AddField(this, fldNode, offset, fieldType);

offset += fieldSize;
}
return fieldList;
}
#endif // TARGET_ARM64

GenTree* Compiler::gtNewSimdWithLowerNode(var_types type,
GenTree* op1,
GenTree* op2,
Expand Down
11 changes: 11 additions & 0 deletions src/coreclr/jit/hwintrinsic.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ enum HWIntrinsicFlag : unsigned int

// The intrinsic supports some sort of containment analysis
HW_Flag_SupportsContainment = 0x2000,

// The intrinsic needs consecutive registers
HW_Flag_NeedsConsecutiveRegisters = 0x4000,
#else
#error Unsupported platform
#endif
Expand Down Expand Up @@ -751,6 +754,14 @@ struct HWIntrinsicInfo
return (flags & HW_Flag_SpecialCodeGen) != 0;
}

#ifdef TARGET_ARM64
static bool NeedsConsecutiveRegisters(NamedIntrinsic id)
{
HWIntrinsicFlag flags = lookupFlags(id);
return (flags & HW_Flag_NeedsConsecutiveRegisters) != 0;
}
#endif

static bool HasRMWSemantics(NamedIntrinsic id)
{
HWIntrinsicFlag flags = lookupFlags(id);
Expand Down
77 changes: 77 additions & 0 deletions src/coreclr/jit/hwintrinsicarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1900,7 +1900,84 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
retNode = impAssignMultiRegTypeToVar(op1, sig->retTypeSigClass DEBUGARG(CorInfoCallConvExtension::Managed));
break;
}
case NI_AdvSimd_VectorTableLookup:
case NI_AdvSimd_Arm64_VectorTableLookup:
kunalspathak marked this conversation as resolved.
Show resolved Hide resolved
{
assert(sig->numArgs == 2);

CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
var_types argType = TYP_UNKNOWN;
CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;

argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
op2 = getArgForHWIntrinsic(argType, argClass);
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass)));
op1 = impPopStack().val;

if (op1->TypeGet() == TYP_STRUCT)
{
info.compNeedsConsecutiveRegisters = true;
unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(argClass);

if (!op1->OperIs(GT_LCL_VAR))
{
unsigned tmp = lvaGrabTemp(true DEBUGARG("VectorTableLookup temp tree"));

impAssignTempGen(tmp, op1, CHECK_SPILL_NONE);
op1 = gtNewLclvNode(tmp, argType);
}

op1 = gtConvertTableOpToFieldList(op1, fieldCount);
}
else
{
assert(varTypeIsSIMD(op1->TypeGet()));
}

retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize);
break;
}
case NI_AdvSimd_VectorTableLookupExtension:
case NI_AdvSimd_Arm64_VectorTableLookupExtension:
{
kunalspathak marked this conversation as resolved.
Show resolved Hide resolved
assert(sig->numArgs == 3);

CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2);
var_types argType = TYP_UNKNOWN;
CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE;

argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass)));
op3 = getArgForHWIntrinsic(argType, argClass);
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
op2 = impPopStack().val;
op1 = impPopStack().val;

if (op2->TypeGet() == TYP_STRUCT)
{
info.compNeedsConsecutiveRegisters = true;
unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(argClass);

if (!op2->OperIs(GT_LCL_VAR))
{
unsigned tmp = lvaGrabTemp(true DEBUGARG("VectorTableLookupExtension temp tree"));

impAssignTempGen(tmp, op2, CHECK_SPILL_NONE);
op2 = gtNewLclvNode(tmp, argType);
}

op2 = gtConvertTableOpToFieldList(op2, fieldCount);
}
else
{
assert(varTypeIsSIMD(op1->TypeGet()));
}

retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize);
break;
}
default:
{
return nullptr;
Expand Down
104 changes: 104 additions & 0 deletions src/coreclr/jit/hwintrinsiccodegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,110 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
(emitSize == EA_8BYTE) ? INS_OPTS_8B : INS_OPTS_16B);
break;

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

GenTree* argNode = use.GetNode();
assert(argReg == argNode->GetRegNum());
argReg = REG_NEXT(argReg);
#endif
}
}
else
{
regCount = 1;
op1Reg = intrin.op1->GetRegNum();
}

switch (regCount)
{
case 2:
ins = INS_tbl_2regs;
break;
case 3:
ins = INS_tbl_3regs;
break;
case 4:
ins = INS_tbl_4regs;
break;
default:
assert(regCount == 1);
assert(ins == INS_tbl);
break;
}

GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt);
break;
}

case NI_AdvSimd_VectorTableLookupExtension:
case NI_AdvSimd_Arm64_VectorTableLookupExtension:
{
assert(isRMW);
unsigned regCount = 0;
op1Reg = intrin.op1->GetRegNum();
op3Reg = intrin.op3->GetRegNum();
assert(targetReg != op3Reg);
if (intrin.op2->OperIsFieldList())
{
GenTreeFieldList* fieldList = intrin.op2->AsFieldList();
GenTree* firstField = fieldList->Uses().GetHead()->GetNode();
op2Reg = firstField->GetRegNum();
INDEBUG(regNumber argReg = op2Reg);
for (GenTreeFieldList::Use& use : fieldList->Uses())
{
regCount++;
#ifdef DEBUG

GenTree* argNode = use.GetNode();

// registers should be consecutive
assert(argReg == argNode->GetRegNum());
// and they should not interfere with targetReg
assert(targetReg != argReg);
argReg = REG_NEXT(argReg);
#endif
}
}
else
{
regCount = 1;
op2Reg = intrin.op2->GetRegNum();
}

switch (regCount)
{
case 2:
ins = INS_tbx_2regs;
break;
case 3:
ins = INS_tbx_3regs;
break;
case 4:
ins = INS_tbx_4regs;
break;
default:
assert(regCount == 1);
assert(ins == INS_tbx);
break;
}

GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true);
GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op2Reg, op3Reg, opt);
break;
}
default:
unreached();
}
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/hwintrinsiclistarm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,8 @@ HARDWARE_INTRINSIC(AdvSimd, SubtractSaturateScalar,
HARDWARE_INTRINSIC(AdvSimd, SubtractScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sub, INS_sub, INS_fsub, INS_fsub}, HW_Category_SIMD, HW_Flag_SIMDScalar)
HARDWARE_INTRINSIC(AdvSimd, SubtractWideningLower, 8, 2, {INS_ssubl, INS_usubl, INS_ssubl, INS_usubl, INS_ssubl, INS_usubl, INS_ssubw, INS_usubw, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(AdvSimd, SubtractWideningUpper, 16, 2, {INS_ssubl2, INS_usubl2, INS_ssubl2, INS_usubl2, INS_ssubl2, INS_usubl2, INS_ssubw2, INS_usubw2, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(AdvSimd, VectorTableLookup, 8, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd, VectorTableLookupExtension, 8, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(AdvSimd, VectorTableLookup, 8, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NeedsConsecutiveRegisters)
HARDWARE_INTRINSIC(AdvSimd, VectorTableLookupExtension, 8, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics|HW_Flag_NeedsConsecutiveRegisters)
HARDWARE_INTRINSIC(AdvSimd, Xor, -1, 2, {INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor}, HW_Category_SIMD, HW_Flag_Commutative)
HARDWARE_INTRINSIC(AdvSimd, ZeroExtendWideningLower, 8, 1, {INS_uxtl, INS_uxtl, INS_uxtl, INS_uxtl, INS_uxtl, INS_uxtl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(AdvSimd, ZeroExtendWideningUpper, 16, 1, {INS_uxtl2, INS_uxtl2, INS_uxtl2, INS_uxtl2, INS_uxtl2, INS_uxtl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg)
Expand Down Expand Up @@ -651,8 +651,8 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64, TransposeEven,
HARDWARE_INTRINSIC(AdvSimd_Arm64, TransposeOdd, -1, 2, {INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, UnzipEven, -1, 2, {INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, UnzipOdd, -1, 2, {INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookup, 16, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookupExtension, 16, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookup, 16, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NeedsConsecutiveRegisters)
HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookupExtension, 16, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics|HW_Flag_NeedsConsecutiveRegisters)
HARDWARE_INTRINSIC(AdvSimd_Arm64, ZipHigh, -1, 2, {INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, ZipLow, -1, 2, {INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1}, HW_Category_SIMD, HW_Flag_NoFlag)

Expand Down
Loading