@@ -219,7 +219,7 @@ void DecomposeLongs::DecomposeNode(GenTree** ppTree, Compiler::fgWalkData* data)
219
219
break ;
220
220
221
221
case GT_NEG:
222
- NYI ( " GT_NEG of TYP_LONG " );
222
+ DecomposeNeg (ppTree, data );
223
223
break ;
224
224
225
225
// 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)
905
905
FinalizeDecomposition (ppTree, data, loResult, hiResult);
906
906
}
907
907
908
+ // ------------------------------------------------------------------------
909
+ // DecomposeNeg: Decompose GT_NEG.
910
+ //
911
+ // Arguments:
912
+ // ppTree - the tree to decompose
913
+ // data - tree walk context
914
+ //
915
+ // Return Value:
916
+ // None.
917
+ //
918
+ void DecomposeLongs::DecomposeNeg (GenTree** ppTree, Compiler::fgWalkData* data)
919
+ {
920
+ assert (ppTree != nullptr );
921
+ assert (*ppTree != nullptr );
922
+ assert (data != nullptr );
923
+ assert ((*ppTree)->OperGet () == GT_NEG);
924
+ assert (m_compiler->compCurStmt != nullptr );
925
+
926
+ GenTreeStmt* curStmt = m_compiler->compCurStmt ->AsStmt ();
927
+ GenTree* tree = *ppTree;
928
+ GenTree* op1 = tree->gtGetOp1 ();
929
+ noway_assert (op1->OperGet () == GT_LONG);
930
+
931
+ CreateTemporary (&(op1->gtOp .gtOp1 ));
932
+ CreateTemporary (&(op1->gtOp .gtOp2 ));
933
+ // Neither GT_NEG nor the introduced temporaries have side effects.
934
+ tree->gtFlags &= ~GTF_ALL_EFFECT;
935
+ GenTree* loOp1 = op1->gtGetOp1 ();
936
+ GenTree* hiOp1 = op1->gtGetOp2 ();
937
+ Compiler::fgSnipNode (curStmt, op1);
938
+
939
+ GenTree* loResult = tree;
940
+ loResult->gtType = TYP_INT;
941
+ loResult->gtOp .gtOp1 = loOp1;
942
+
943
+ GenTree* zero = m_compiler->gtNewZeroConNode (TYP_INT);
944
+ GenTree* hiAdjust = m_compiler->gtNewOperNode (GT_ADD_HI, TYP_INT, hiOp1, zero);
945
+ GenTree* hiResult = m_compiler->gtNewOperNode (GT_NEG, TYP_INT, hiAdjust);
946
+ hiResult->gtFlags = tree->gtFlags ;
947
+
948
+ Compiler::fgSnipNode (curStmt, hiOp1);
949
+ // fgSnipNode doesn't clear gtNext/gtPrev...
950
+ hiOp1->gtNext = nullptr ;
951
+ hiOp1->gtPrev = nullptr ;
952
+ SimpleLinkNodeAfter (hiOp1, zero);
953
+ SimpleLinkNodeAfter (zero, hiAdjust);
954
+ SimpleLinkNodeAfter (hiAdjust, hiResult);
955
+
956
+ FinalizeDecomposition (ppTree, data, loResult, hiResult);
957
+ }
908
958
909
959
// ------------------------------------------------------------------------
910
960
// DecomposeArith: Decompose GT_ADD, GT_SUB, GT_OR, GT_XOR, GT_AND.
0 commit comments