Delete long compare support from ARM32 codegen
authorMike Danes <onemihaid@hotmail.com>
Wed, 24 May 2017 16:58:28 +0000 (19:58 +0300)
committerMike Danes <onemihaid@hotmail.com>
Fri, 2 Jun 2017 08:32:10 +0000 (11:32 +0300)
src/jit/codegenarm.cpp
src/jit/codegenlinear.h
src/jit/lsraarmarch.cpp

index 8c42bf8..438453b 100644 (file)
@@ -1289,52 +1289,35 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree)
     var_types  op1Type = op1->TypeGet();
     var_types  op2Type = op2->TypeGet();
 
-    if (varTypeIsLong(op1Type))
-    {
-#ifdef DEBUG
-        // The result of an unlowered long compare on a 32-bit target must either be
-        // a) materialized into a register, or
-        // b) unused.
-        //
-        // A long compare that has a result that is used but not materialized into a register should
-        // have been handled by Lowering::LowerCompare.
+    assert(!varTypeIsLong(op1Type));
+    assert(!varTypeIsLong(op2Type));
 
-        LIR::Use use;
-        assert((tree->gtRegNum != REG_NA) || !LIR::AsRange(compiler->compCurBB).TryGetUse(tree, &use));
-#endif
-        genCompareLong(tree);
+    regNumber targetReg = tree->gtRegNum;
+    emitter*  emit      = getEmitter();
+
+    genConsumeIfReg(op1);
+    genConsumeIfReg(op2);
+
+    if (varTypeIsFloating(op1Type))
+    {
+        assert(op1Type == op2Type);
+        assert(!tree->OperIs(GT_CMP));
+        emit->emitInsBinary(INS_vcmp, emitTypeSize(op1Type), op1, op2);
+        // vmrs with register 0xf has special meaning of transferring flags
+        emit->emitIns_R(INS_vmrs, EA_4BYTE, REG_R15);
     }
     else
     {
-        assert(!varTypeIsLong(op2Type));
-
-        regNumber targetReg = tree->gtRegNum;
-        emitter*  emit      = getEmitter();
-
-        genConsumeIfReg(op1);
-        genConsumeIfReg(op2);
-
-        if (varTypeIsFloating(op1Type))
-        {
-            assert(op1Type == op2Type);
-            assert(!tree->OperIs(GT_CMP));
-            emit->emitInsBinary(INS_vcmp, emitTypeSize(op1Type), op1, op2);
-            // vmrs with register 0xf has special meaning of transferring flags
-            emit->emitIns_R(INS_vmrs, EA_4BYTE, REG_R15);
-        }
-        else
-        {
-            assert(!varTypeIsFloating(op2Type));
-            var_types cmpType = (op1Type == op2Type) ? op1Type : TYP_INT;
-            emit->emitInsBinary(INS_cmp, emitTypeSize(cmpType), op1, op2);
-        }
+        assert(!varTypeIsFloating(op2Type));
+        var_types cmpType = (op1Type == op2Type) ? op1Type : TYP_INT;
+        emit->emitInsBinary(INS_cmp, emitTypeSize(cmpType), op1, op2);
+    }
 
-        // Are we evaluating this into a register?
-        if (targetReg != REG_NA)
-        {
-            genSetRegToCond(targetReg, tree);
-            genProduceReg(tree);
-        }
+    // Are we evaluating this into a register?
+    if (targetReg != REG_NA)
+    {
+        genSetRegToCond(targetReg, tree);
+        genProduceReg(tree);
     }
 }
 
@@ -1431,158 +1414,6 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
 }
 
 //------------------------------------------------------------------------
-// genCompareLong: Generate code for comparing two longs when the result of the compare
-// is manifested in a register.
-//
-// Arguments:
-//    treeNode - the compare tree
-//
-// Return Value:
-//    None.
-//
-// Comments:
-// For long compares, we need to compare the high parts of operands first, then the low parts.
-// If the high compare is false, we do not need to compare the low parts. For less than and
-// greater than, if the high compare is true, we can assume the entire compare is true.
-//
-void CodeGen::genCompareLong(GenTreePtr treeNode)
-{
-    assert(treeNode->OperIsCompare());
-
-    GenTreeOp* tree = treeNode->AsOp();
-    GenTreePtr op1  = tree->gtOp1;
-    GenTreePtr op2  = tree->gtOp2;
-
-    assert(varTypeIsLong(op1->TypeGet()));
-    assert(varTypeIsLong(op2->TypeGet()));
-
-    regNumber targetReg = treeNode->gtRegNum;
-
-    genConsumeOperands(tree);
-
-    GenTreePtr loOp1 = op1->gtGetOp1();
-    GenTreePtr hiOp1 = op1->gtGetOp2();
-    GenTreePtr loOp2 = op2->gtGetOp1();
-    GenTreePtr hiOp2 = op2->gtGetOp2();
-
-    // Create compare for the high parts
-    instruction ins     = INS_cmp;
-    var_types   cmpType = TYP_INT;
-    emitAttr    cmpAttr = emitTypeSize(cmpType);
-
-    // Emit the compare instruction
-    getEmitter()->emitInsBinary(ins, cmpAttr, hiOp1, hiOp2);
-
-    // If the result is not being materialized in a register, we're done.
-    if (targetReg == REG_NA)
-    {
-        return;
-    }
-
-    BasicBlock* labelTrue  = genCreateTempLabel();
-    BasicBlock* labelFalse = genCreateTempLabel();
-    BasicBlock* labelNext  = genCreateTempLabel();
-
-    genJccLongHi(tree->gtOper, labelTrue, labelFalse, tree->IsUnsigned());
-    getEmitter()->emitInsBinary(ins, cmpAttr, loOp1, loOp2);
-    genJccLongLo(tree->gtOper, labelTrue, labelFalse);
-
-    genDefineTempLabel(labelFalse);
-    getEmitter()->emitIns_R_I(INS_mov, emitActualTypeSize(tree->gtType), tree->gtRegNum, 0);
-    getEmitter()->emitIns_J(INS_b, labelNext);
-
-    genDefineTempLabel(labelTrue);
-    getEmitter()->emitIns_R_I(INS_mov, emitActualTypeSize(tree->gtType), tree->gtRegNum, 1);
-
-    genDefineTempLabel(labelNext);
-
-    genProduceReg(tree);
-}
-
-void CodeGen::genJccLongHi(genTreeOps cmp, BasicBlock* jumpTrue, BasicBlock* jumpFalse, bool isUnsigned)
-{
-    if (cmp != GT_NE)
-    {
-        jumpFalse->bbFlags |= BBF_JMP_TARGET | BBF_HAS_LABEL;
-    }
-
-    switch (cmp)
-    {
-        case GT_EQ:
-            inst_JMP(EJ_ne, jumpFalse);
-            break;
-
-        case GT_NE:
-            inst_JMP(EJ_ne, jumpTrue);
-            break;
-
-        case GT_LT:
-        case GT_LE:
-            if (isUnsigned)
-            {
-                inst_JMP(EJ_hi, jumpFalse);
-                inst_JMP(EJ_lo, jumpTrue);
-            }
-            else
-            {
-                inst_JMP(EJ_gt, jumpFalse);
-                inst_JMP(EJ_lt, jumpTrue);
-            }
-            break;
-
-        case GT_GE:
-        case GT_GT:
-            if (isUnsigned)
-            {
-                inst_JMP(EJ_lo, jumpFalse);
-                inst_JMP(EJ_hi, jumpTrue);
-            }
-            else
-            {
-                inst_JMP(EJ_lt, jumpFalse);
-                inst_JMP(EJ_gt, jumpTrue);
-            }
-            break;
-
-        default:
-            noway_assert(!"expected a comparison operator");
-    }
-}
-
-void CodeGen::genJccLongLo(genTreeOps cmp, BasicBlock* jumpTrue, BasicBlock* jumpFalse)
-{
-    switch (cmp)
-    {
-        case GT_EQ:
-            inst_JMP(EJ_eq, jumpTrue);
-            break;
-
-        case GT_NE:
-            inst_JMP(EJ_ne, jumpTrue);
-            break;
-
-        case GT_LT:
-            inst_JMP(EJ_lo, jumpTrue);
-            break;
-
-        case GT_LE:
-            inst_JMP(EJ_ls, jumpTrue);
-            break;
-
-        case GT_GE:
-            inst_JMP(EJ_hs, jumpTrue);
-            break;
-
-        case GT_GT:
-            inst_JMP(EJ_hi, jumpTrue);
-            break;
-
-        default:
-            noway_assert(!"expected comparison");
-    }
-}
-
-//------------------------------------------------------------------------
 // genSetRegToCond: Generate code to materialize a condition into a register.
 //
 // Arguments:
index 59763bc..54c6db1 100644 (file)
@@ -53,12 +53,6 @@ unsigned getFirstArgWithStackSlot();
 void genCompareFloat(GenTreePtr treeNode);
 void genCompareInt(GenTreePtr treeNode);
 
-#if defined(_TARGET_ARM_)
-void genCompareLong(GenTreePtr treeNode);
-void genJccLongHi(genTreeOps cmp, BasicBlock* jumpTrue, BasicBlock* jumpFalse, bool isUnsigned = false);
-void genJccLongLo(genTreeOps cmp, BasicBlock* jumpTrue, BasicBlock* jumpFalse);
-#endif // defined(_TARGET_ARM_)
-
 #ifdef FEATURE_SIMD
 enum SIMDScalarMoveType
 {
index ac1c126..e862047 100644 (file)
@@ -81,27 +81,6 @@ void Lowering::TreeNodeInfoInitCmp(GenTreePtr tree)
     info->srcCount = 2;
     info->dstCount = tree->OperIs(GT_CMP) ? 0 : 1;
 
-#ifdef _TARGET_ARM_
-
-    GenTreePtr op1     = tree->gtOp.gtOp1;
-    GenTreePtr op2     = tree->gtOp.gtOp2;
-    var_types  op1Type = op1->TypeGet();
-    var_types  op2Type = op2->TypeGet();
-
-    // Long compares will consume GT_LONG nodes, each of which produces two results.
-    // Thus for each long operand there will be an additional source.
-    // TODO-ARM-CQ: Mark hiOp2 and loOp2 as contained if it is a constant.
-    if (varTypeIsLong(op1Type))
-    {
-        info->srcCount++;
-    }
-    if (varTypeIsLong(op2Type))
-    {
-        info->srcCount++;
-    }
-
-#endif // _TARGET_ARM_
-
     CheckImmedAndMakeContained(tree, tree->gtOp.gtOp2);
 }