summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Danes <onemihaid@hotmail.com>2016-06-23 22:02:50 +0300
committerMike Danes <onemihaid@hotmail.com>2016-07-12 07:24:05 +0300
commitcdb8a214a807ef0207b7e3cd9313cfaf163bf392 (patch)
treec588455e6df4833267f122f54471ffeaf9958803 /src
parent801c8370f3d54568a4a58422d243a7018aeab97f (diff)
downloadcoreclr-cdb8a214a807ef0207b7e3cd9313cfaf163bf392.tar.gz
coreclr-cdb8a214a807ef0207b7e3cd9313cfaf163bf392.tar.bz2
coreclr-cdb8a214a807ef0207b7e3cd9313cfaf163bf392.zip
Implement GT_NEG decomposition
Diffstat (limited to 'src')
-rw-r--r--src/jit/decomposelongs.cpp52
-rw-r--r--src/jit/decomposelongs.h1
-rw-r--r--[-rwxr-xr-x]src/jit/lower.cpp5
3 files changed, 56 insertions, 2 deletions
diff --git a/src/jit/decomposelongs.cpp b/src/jit/decomposelongs.cpp
index f505ed0faf..988d071de1 100644
--- a/src/jit/decomposelongs.cpp
+++ b/src/jit/decomposelongs.cpp
@@ -219,7 +219,7 @@ void DecomposeLongs::DecomposeNode(GenTree** ppTree, Compiler::fgWalkData* data)
break;
case GT_NEG:
- NYI("GT_NEG of TYP_LONG");
+ DecomposeNeg(ppTree, data);
break;
// Binary operators. Those that require different computation for upper and lower half are
@@ -905,6 +905,56 @@ void DecomposeLongs::DecomposeNot(GenTree** ppTree, Compiler::fgWalkData* data)
FinalizeDecomposition(ppTree, data, loResult, hiResult);
}
+//------------------------------------------------------------------------
+// DecomposeNeg: Decompose GT_NEG.
+//
+// Arguments:
+// ppTree - the tree to decompose
+// data - tree walk context
+//
+// Return Value:
+// None.
+//
+void DecomposeLongs::DecomposeNeg(GenTree** ppTree, Compiler::fgWalkData* data)
+{
+ assert(ppTree != nullptr);
+ assert(*ppTree != nullptr);
+ assert(data != nullptr);
+ assert((*ppTree)->OperGet() == GT_NEG);
+ assert(m_compiler->compCurStmt != nullptr);
+
+ GenTreeStmt* curStmt = m_compiler->compCurStmt->AsStmt();
+ GenTree* tree = *ppTree;
+ GenTree* op1 = tree->gtGetOp1();
+ noway_assert(op1->OperGet() == GT_LONG);
+
+ CreateTemporary(&(op1->gtOp.gtOp1));
+ CreateTemporary(&(op1->gtOp.gtOp2));
+ // Neither GT_NEG nor the introduced temporaries have side effects.
+ tree->gtFlags &= ~GTF_ALL_EFFECT;
+ GenTree* loOp1 = op1->gtGetOp1();
+ GenTree* hiOp1 = op1->gtGetOp2();
+ Compiler::fgSnipNode(curStmt, op1);
+
+ GenTree* loResult = tree;
+ loResult->gtType = TYP_INT;
+ loResult->gtOp.gtOp1 = loOp1;
+
+ GenTree* zero = m_compiler->gtNewZeroConNode(TYP_INT);
+ GenTree* hiAdjust = m_compiler->gtNewOperNode(GT_ADD_HI, TYP_INT, hiOp1, zero);
+ GenTree* hiResult = m_compiler->gtNewOperNode(GT_NEG, TYP_INT, hiAdjust);
+ hiResult->gtFlags = tree->gtFlags;
+
+ Compiler::fgSnipNode(curStmt, hiOp1);
+ // fgSnipNode doesn't clear gtNext/gtPrev...
+ hiOp1->gtNext = nullptr;
+ hiOp1->gtPrev = nullptr;
+ SimpleLinkNodeAfter(hiOp1, zero);
+ SimpleLinkNodeAfter(zero, hiAdjust);
+ SimpleLinkNodeAfter(hiAdjust, hiResult);
+
+ FinalizeDecomposition(ppTree, data, loResult, hiResult);
+}
//------------------------------------------------------------------------
// DecomposeArith: Decompose GT_ADD, GT_SUB, GT_OR, GT_XOR, GT_AND.
diff --git a/src/jit/decomposelongs.h b/src/jit/decomposelongs.h
index 376f655d53..b4a48a0882 100644
--- a/src/jit/decomposelongs.h
+++ b/src/jit/decomposelongs.h
@@ -44,6 +44,7 @@ private:
void DecomposeCall(GenTree** ppTree, Compiler::fgWalkData* data);
void DecomposeStoreInd(GenTree** ppTree, Compiler::fgWalkData* data);
void DecomposeNot(GenTree** ppTree, Compiler::fgWalkData* data);
+ void DecomposeNeg(GenTree** ppTree, Compiler::fgWalkData* data);
void DecomposeArith(GenTree** ppTree, Compiler::fgWalkData* data);
// Helper functions
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index 7a133f78c7..80b5f4cecf 100755..100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -1147,7 +1147,10 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
GenTreePtr argLo = arg->gtGetOp1();
GenTreePtr argHi = arg->gtGetOp2();
- NYI_IF(argHi->OperGet() == GT_ADD_HI || argHi->OperGet() == GT_SUB_HI, "Hi and Lo cannot be reordered");
+ NYI_IF((argHi->OperGet() == GT_ADD_HI) ||
+ (argHi->OperGet() == GT_SUB_HI) ||
+ (argHi->OperGet() == GT_NEG),
+ "Hi and Lo cannot be reordered");
GenTreePtr putArgLo = NewPutArg(call, argLo, info, type);
GenTreePtr putArgHi = NewPutArg(call, argHi, info, type);