@@ -2639,6 +2639,62 @@ void CodeGen::genCodeForBinary(GenTreeOp* tree)
2639
2639
genProduceReg(tree);
2640
2640
return;
2641
2641
}
2642
+ else if (op2->OperIs(GT_CAST) && op2->isContained())
2643
+ {
2644
+ assert(varTypeIsIntegral(tree));
2645
+
2646
+ GenTree* a = op1;
2647
+ GenTree* b = op2->AsCast()->CastOp();
2648
+
2649
+ instruction ins = genGetInsForOper(tree->OperGet(), targetType);
2650
+ insOpts opt = INS_OPTS_NONE;
2651
+
2652
+ if ((tree->gtFlags & GTF_SET_FLAGS) != 0)
2653
+ {
2654
+ // A subset of operations can still set flags
2655
+
2656
+ switch (oper)
2657
+ {
2658
+ case GT_ADD:
2659
+ {
2660
+ ins = INS_adds;
2661
+ break;
2662
+ }
2663
+
2664
+ case GT_SUB:
2665
+ {
2666
+ ins = INS_subs;
2667
+ break;
2668
+ }
2669
+
2670
+ default:
2671
+ {
2672
+ noway_assert(!"Unexpected BinaryOp with GTF_SET_FLAGS set");
2673
+ }
2674
+ }
2675
+ }
2676
+
2677
+ bool isZeroExtending = op2->AsCast()->IsZeroExtending();
2678
+
2679
+ if (varTypeIsByte(op2->CastToType()))
2680
+ {
2681
+ opt = isZeroExtending ? INS_OPTS_UXTB : INS_OPTS_SXTB;
2682
+ }
2683
+ else if (varTypeIsShort(op2->CastToType()))
2684
+ {
2685
+ opt = isZeroExtending ? INS_OPTS_UXTH : INS_OPTS_SXTH;
2686
+ }
2687
+ else
2688
+ {
2689
+ assert(op2->TypeIs(TYP_LONG) && genActualTypeIsInt(b));
2690
+ opt = isZeroExtending ? INS_OPTS_UXTW : INS_OPTS_SXTW;
2691
+ }
2692
+
2693
+ emit->emitIns_R_R_R(ins, emitActualTypeSize(tree), targetReg, a->GetRegNum(), b->GetRegNum(), opt);
2694
+
2695
+ genProduceReg(tree);
2696
+ return;
2697
+ }
2642
2698
2643
2699
if (tree->OperIs(GT_AND) && op2->isContainedAndNotIntOrIImmed())
2644
2700
{
@@ -10564,54 +10620,6 @@ void CodeGen::genCodeForBfiz(GenTreeOp* tree)
10564
10620
genProduceReg(tree);
10565
10621
}
10566
10622
10567
- //------------------------------------------------------------------------
10568
- // genCodeForAddEx: Generates the code sequence for a GenTree node that
10569
- // represents an addition with sign or zero extended
10570
- //
10571
- // Arguments:
10572
- // tree - the add with extend node.
10573
- //
10574
- void CodeGen::genCodeForAddEx(GenTreeOp* tree)
10575
- {
10576
- assert(tree->OperIs(GT_ADDEX));
10577
- genConsumeOperands(tree);
10578
-
10579
- GenTree* op;
10580
- GenTree* containedOp;
10581
- if (tree->gtGetOp1()->isContained())
10582
- {
10583
- containedOp = tree->gtGetOp1();
10584
- op = tree->gtGetOp2();
10585
- }
10586
- else
10587
- {
10588
- containedOp = tree->gtGetOp2();
10589
- op = tree->gtGetOp1();
10590
- }
10591
- assert(containedOp->isContained() && !op->isContained());
10592
-
10593
- regNumber dstReg = tree->GetRegNum();
10594
- regNumber op1Reg = op->GetRegNum();
10595
- regNumber op2Reg = containedOp->gtGetOp1()->GetRegNum();
10596
-
10597
- if (containedOp->OperIs(GT_CAST))
10598
- {
10599
- GenTreeCast* cast = containedOp->AsCast();
10600
- assert(varTypeIsLong(cast->CastToType()));
10601
- insOpts opts = cast->IsUnsigned() ? INS_OPTS_UXTW : INS_OPTS_SXTW;
10602
- GetEmitter()->emitIns_R_R_R(tree->gtSetFlags() ? INS_adds : INS_add, emitActualTypeSize(tree), dstReg, op1Reg,
10603
- op2Reg, opts);
10604
- }
10605
- else
10606
- {
10607
- assert(containedOp->OperIs(GT_LSH));
10608
- ssize_t cns = containedOp->gtGetOp2()->AsIntCon()->IconValue();
10609
- GetEmitter()->emitIns_R_R_R_I(tree->gtSetFlags() ? INS_adds : INS_add, emitActualTypeSize(tree), dstReg, op1Reg,
10610
- op2Reg, cns, INS_OPTS_LSL);
10611
- }
10612
- genProduceReg(tree);
10613
- }
10614
-
10615
10623
//------------------------------------------------------------------------
10616
10624
// genCodeForCond: Generates the code sequence for a GenTree node that
10617
10625
// represents a conditional instruction.
0 commit comments