summaryrefslogtreecommitdiff
path: root/src/jit/lsraxarch.cpp
diff options
context:
space:
mode:
authorPent Ploompuu <kaalikas@gmail.com>2018-09-07 00:11:03 +0300
committerGitHub <noreply@github.com>2018-09-07 00:11:03 +0300
commit58afb7fd657b8f0c7a683347457a0f029f8e4100 (patch)
tree0e3e846b4206d0ff15a9ca9aea7e0eba2e2f1b82 /src/jit/lsraxarch.cpp
parent6cd754ad87db79d7dcfbde0374b2e10ab8d3d616 (diff)
parent1d885d32db50e8ee931d0d9fbd1081bfbb7ce271 (diff)
downloadcoreclr-58afb7fd657b8f0c7a683347457a0f029f8e4100.tar.gz
coreclr-58afb7fd657b8f0c7a683347457a0f029f8e4100.tar.bz2
coreclr-58afb7fd657b8f0c7a683347457a0f029f8e4100.zip
Merge branch 'master' into xcnt-false-dep
Diffstat (limited to 'src/jit/lsraxarch.cpp')
-rw-r--r--src/jit/lsraxarch.cpp51
1 files changed, 48 insertions, 3 deletions
diff --git a/src/jit/lsraxarch.cpp b/src/jit/lsraxarch.cpp
index 56e3cc741b..e0c112d414 100644
--- a/src/jit/lsraxarch.cpp
+++ b/src/jit/lsraxarch.cpp
@@ -533,6 +533,7 @@ int LinearScan::BuildNode(GenTree* tree)
#ifdef FEATURE_HW_INTRINSICS
case GT_HW_INTRINSIC_CHK:
#endif // FEATURE_HW_INTRINSICS
+
// Consumes arrLen & index - has no result
srcCount = 2;
assert(dstCount == 0);
@@ -2311,7 +2312,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
if (op1->OperIsList())
{
assert(op2 == nullptr);
- assert(numArgs == 3);
+ assert(numArgs >= 3);
GenTreeArgList* argList = op1->AsArgList();
@@ -2321,10 +2322,16 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
op2 = argList->Current();
argList = argList->Rest();
- op3 = argList->Current();
+ op3 = argList->Current();
+
+ while (argList->Rest() != nullptr)
+ {
+ argList = argList->Rest();
+ }
+
+ lastOp = argList->Current();
argList = argList->Rest();
- lastOp = op3;
assert(argList == nullptr);
}
else if (op2 != nullptr)
@@ -2584,6 +2591,44 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
break;
}
+ case NI_AVX2_GatherVector128:
+ case NI_AVX2_GatherVector256:
+ {
+ assert(numArgs == 3);
+ // Any pair of the index, mask, or destination registers should be different
+ srcCount += BuildOperandUses(op1);
+ srcCount += BuildDelayFreeUses(op2);
+
+ // get a tmp register for mask that will be cleared by gather instructions
+ buildInternalFloatRegisterDefForNode(intrinsicTree, allSIMDRegs());
+ setInternalRegsDelayFree = true;
+
+ buildUses = false;
+ break;
+ }
+
+ case NI_AVX2_GatherMaskVector128:
+ case NI_AVX2_GatherMaskVector256:
+ {
+ assert(numArgs == 5);
+ // Any pair of the index, mask, or destination registers should be different
+ srcCount += BuildOperandUses(op1);
+ srcCount += BuildOperandUses(op2);
+ srcCount += BuildDelayFreeUses(op3);
+
+ assert(intrinsicTree->gtGetOp1()->OperIsList());
+ GenTreeArgList* argList = intrinsicTree->gtGetOp1()->AsArgList();
+ GenTree* op4 = argList->Rest()->Rest()->Rest()->Current();
+ srcCount += BuildDelayFreeUses(op4);
+
+ // get a tmp register for mask that will be cleared by gather instructions
+ buildInternalFloatRegisterDefForNode(intrinsicTree, allSIMDRegs());
+ setInternalRegsDelayFree = true;
+
+ buildUses = false;
+ break;
+ }
+
default:
{
assert((intrinsicId > NI_HW_INTRINSIC_START) && (intrinsicId < NI_HW_INTRINSIC_END));