@@ -2696,35 +2696,6 @@ void CodeGen::genCodeForBinary(GenTreeOp* tree)
26962696 return ;
26972697 }
26982698
2699- if (tree->isContainedCompareChainSegment(op2))
2700- {
2701- GenCondition cond;
2702- bool chain = false;
2703-
2704- JITDUMP("Generating compare chain:\n");
2705- if (op1->isContained())
2706- {
2707- // Generate Op1 into flags.
2708- genCodeForContainedCompareChain(op1, &chain, &cond);
2709- assert(chain);
2710- }
2711- else
2712- {
2713- // Op1 is not contained, move it from a register into flags.
2714- emit->emitIns_R_I(INS_cmp, emitActualTypeSize(op1), op1->GetRegNum(), 0);
2715- cond = GenCondition::NE;
2716- chain = true;
2717- }
2718- // Gen Op2 into flags.
2719- genCodeForContainedCompareChain(op2, &chain, &cond);
2720- assert(chain);
2721-
2722- // Move the result from flags into a register.
2723- inst_SETCC(cond, tree->TypeGet(), targetReg);
2724- genProduceReg(tree);
2725- return;
2726- }
2727-
27282699 instruction ins = genGetInsForOper (tree->OperGet (), targetType);
27292700
27302701 if ((tree->gtFlags & GTF_SET_FLAGS) != 0 )
@@ -4600,108 +4571,36 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree)
46004571// tree - a compare node (GT_EQ etc)
46014572// cond - the condition of the previous generated compare.
46024573//
4603- void CodeGen::genCodeForConditionalCompare(GenTreeOp* tree, GenCondition prevCond )
4574+ void CodeGen::genCodeForCCMP (GenTreeCCMP* ccmp )
46044575{
46054576 emitter* emit = GetEmitter ();
46064577
4607- GenTree* op1 = tree->gtGetOp1( );
4608- GenTree* op2 = tree->gtGetOp2 ();
4609- var_types op1Type = genActualType(op1->TypeGet() );
4610- var_types op2Type = genActualType(op2 ->TypeGet());
4611- emitAttr cmpSize = EA_ATTR(genTypeSize(op1Type ));
4612- regNumber targetReg = tree->GetRegNum( );
4613- regNumber srcReg1 = op1->GetRegNum();
4578+ genConsumeOperands (ccmp );
4579+ GenTree* op1 = ccmp-> gtGetOp1 ();
4580+ GenTree* op2 = ccmp-> gtGetOp2 ( );
4581+ var_types op1Type = genActualType (op1 ->TypeGet ());
4582+ var_types op2Type = genActualType (op2-> TypeGet ( ));
4583+ emitAttr cmpSize = emitActualTypeSize (op1Type );
4584+ regNumber srcReg1 = op1->GetRegNum ();
46144585
46154586 // No float support or swapping op1 and op2 to generate cmp reg, imm.
46164587 assert (!varTypeIsFloating (op2Type));
46174588 assert (!op1->isContainedIntOrIImmed ());
46184589
4619- // Should only be called on contained nodes.
4620- assert(targetReg == REG_NA);
4621-
4622- // Should not be called for test conditionals (Arm64 does not have a ctst).
4623- assert(tree->OperIsCmpCompare());
4624-
46254590 // For the ccmp flags, invert the condition of the compare.
4626- insCflags cflags = InsCflagsForCcmp(GenCondition::FromRelop(tree));
4627-
46284591 // For the condition, use the previous compare.
4629- const GenConditionDesc& prevDesc = GenConditionDesc::Get(prevCond );
4630- insCond prevInsCond = JumpKindToInsCond(prevDesc .jumpKind1);
4592+ const GenConditionDesc& condDesc = GenConditionDesc::Get (ccmp-> gtCondition );
4593+ insCond insCond = JumpKindToInsCond (condDesc .jumpKind1 );
46314594
46324595 if (op2->isContainedIntOrIImmed ())
46334596 {
46344597 GenTreeIntConCommon* intConst = op2->AsIntConCommon ();
4635- emit->emitIns_R_I_FLAGS_COND(INS_ccmp, cmpSize, srcReg1, (int)intConst->IconValue(), cflags, prevInsCond );
4598+ emit->emitIns_R_I_FLAGS_COND (INS_ccmp, cmpSize, srcReg1, (int )intConst->IconValue (), ccmp-> gtFlagsVal , insCond );
46364599 }
46374600 else
46384601 {
46394602 regNumber srcReg2 = op2->GetRegNum ();
4640- emit->emitIns_R_R_FLAGS_COND(INS_ccmp, cmpSize, srcReg1, srcReg2, cflags, prevInsCond);
4641- }
4642- }
4643-
4644- //------------------------------------------------------------------------
4645- // genCodeForContainedCompareChain: Produce code for a chain of conditional compares.
4646- //
4647- // Only generates for contained nodes. Nodes that are not contained are assumed to be
4648- // generated as part of standard tree generation.
4649- //
4650- // Arguments:
4651- // tree - the node. Either a compare or a tree of compares connected by ANDs.
4652- // inChain - whether a contained chain is in progress.
4653- // prevCond - If a chain is in progress, the condition of the previous compare.
4654- // Return:
4655- // The last compare node generated.
4656- //
4657- void CodeGen::genCodeForContainedCompareChain(GenTree* tree, bool* inChain, GenCondition* prevCond)
4658- {
4659- assert(tree->isContained());
4660-
4661- if (tree->OperIs(GT_AND))
4662- {
4663- GenTree* op1 = tree->gtGetOp1();
4664- GenTree* op2 = tree->gtGetOp2();
4665-
4666- assert(op2->isContained());
4667-
4668- // If Op1 is contained, generate into flags. Otherwise, move the result into flags.
4669- if (op1->isContained())
4670- {
4671- genCodeForContainedCompareChain(op1, inChain, prevCond);
4672- assert(*inChain);
4673- }
4674- else
4675- {
4676- emitter* emit = GetEmitter();
4677- emit->emitIns_R_I(INS_cmp, emitActualTypeSize(op1), op1->GetRegNum(), 0);
4678- *prevCond = GenCondition::NE;
4679- *inChain = true;
4680- }
4681-
4682- // Generate Op2 based on Op1.
4683- genCodeForContainedCompareChain(op2, inChain, prevCond);
4684- assert(*inChain);
4685- }
4686- else
4687- {
4688- assert(tree->OperIsCmpCompare());
4689-
4690- // Generate the compare, putting the result in the flags register.
4691- if (!*inChain)
4692- {
4693- // First item in a chain. Use a standard compare.
4694- genCodeForCompare(tree->AsOp());
4695- }
4696- else
4697- {
4698- // Within the chain. Use a conditional compare (which is
4699- // dependent on the previous emitted compare).
4700- genCodeForConditionalCompare(tree->AsOp(), *prevCond);
4701- }
4702-
4703- *inChain = true;
4704- *prevCond = GenCondition::FromRelop(tree);
4603+ emit->emitIns_R_R_FLAGS_COND (INS_ccmp, cmpSize, srcReg1, srcReg2, ccmp->gtFlagsVal , insCond);
47054604 }
47064605}
47074606
@@ -4713,45 +4612,37 @@ void CodeGen::genCodeForContainedCompareChain(GenTree* tree, bool* inChain, GenC
47134612//
47144613void CodeGen::genCodeForSelect (GenTreeOp* tree)
47154614{
4716- assert(tree->OperIs(GT_SELECT));
4717- GenTreeConditional* select = tree->AsConditional();
4718- emitter* emit = GetEmitter();
4615+ assert (tree->OperIs (GT_SELECT, GT_SELECTCC));
4616+ GenTree* opcond = nullptr ;
4617+ if (tree->OperIs (GT_SELECT))
4618+ {
4619+ opcond = tree->AsConditional ()->gtCond ;
4620+ genConsumeRegs (opcond);
4621+ }
47194622
4720- GenTree* opcond = select->gtCond;
4721- GenTree* op1 = select->gtOp1;
4722- GenTree* op2 = select->gtOp2;
4723- var_types op1Type = genActualType(op1->TypeGet());
4724- var_types op2Type = genActualType(op2->TypeGet());
4725- emitAttr attr = emitActualTypeSize(select->TypeGet());
4623+ emitter* emit = GetEmitter ();
4624+
4625+ GenTree* op1 = tree->gtOp1 ;
4626+ GenTree* op2 = tree->gtOp2 ;
4627+ var_types op1Type = genActualType (op1);
4628+ var_types op2Type = genActualType (op2);
4629+ emitAttr attr = emitActualTypeSize (tree);
47264630
47274631 assert (!op1->isUsedFromMemory ());
47284632 assert (genTypeSize (op1Type) == genTypeSize (op2Type));
47294633
4730- GenCondition prevCond ;
4731- genConsumeRegs(opcond);
4732- if (opcond->isContained() )
4634+ GenCondition cond ;
4635+
4636+ if (opcond != nullptr )
47334637 {
4734- // Generate the contained condition.
4735- if (opcond->OperIsCompare())
4736- {
4737- genCodeForCompare(opcond->AsOp());
4738- prevCond = GenCondition::FromRelop(opcond);
4739- }
4740- else
4741- {
4742- // Condition is a compare chain. Try to contain it.
4743- assert(opcond->OperIs(GT_AND));
4744- bool chain = false;
4745- JITDUMP("Generating compare chain:\n");
4746- genCodeForContainedCompareChain(opcond, &chain, &prevCond);
4747- assert(chain);
4748- }
4638+ // Condition has been generated into a register - move it into flags.
4639+ emit->emitIns_R_I (INS_cmp, emitActualTypeSize (opcond), opcond->GetRegNum (), 0 );
4640+ cond = GenCondition::NE;
47494641 }
47504642 else
47514643 {
4752- // Condition has been generated into a register - move it into flags.
4753- emit->emitIns_R_I(INS_cmp, emitActualTypeSize(opcond), opcond->GetRegNum(), 0);
4754- prevCond = GenCondition::NE;
4644+ assert (tree->OperIs (GT_SELECTCC));
4645+ cond = tree->AsOpCC ()->gtCondition ;
47554646 }
47564647
47574648 assert (!op1->isContained () || op1->IsIntegralConst (0 ));
@@ -4760,7 +4651,7 @@ void CodeGen::genCodeForSelect(GenTreeOp* tree)
47604651 regNumber targetReg = tree->GetRegNum ();
47614652 regNumber srcReg1 = op1->IsIntegralConst (0 ) ? REG_ZR : genConsumeReg (op1);
47624653 regNumber srcReg2 = op2->IsIntegralConst (0 ) ? REG_ZR : genConsumeReg (op2);
4763- const GenConditionDesc& prevDesc = GenConditionDesc::Get(prevCond );
4654+ const GenConditionDesc& prevDesc = GenConditionDesc::Get (cond );
47644655
47654656 emit->emitIns_R_R_R_COND (INS_csel, attr, targetReg, srcReg1, srcReg2, JumpKindToInsCond (prevDesc.jumpKind1 ));
47664657
@@ -10382,50 +10273,6 @@ void CodeGen::genCodeForCond(GenTreeOp* tree)
1038210273 genProduceReg (tree);
1038310274}
1038410275
10385- //------------------------------------------------------------------------
10386- // InsCflagsForCcmp: Get the Cflags for a required for a CCMP instruction.
10387- //
10388- // Consider:
10389- // cmp w, x
10390- // ccmp y, z, A, COND
10391- // This is: compare w and x, if this matches condition COND, then compare y and z.
10392- // Otherwise set flags to A - this should match the case where cmp failed.
10393- // Given COND, this function returns A.
10394- //
10395- // Arguments:
10396- // cond - the GenCondition.
10397- //
10398- insCflags CodeGen::InsCflagsForCcmp(GenCondition cond)
10399- {
10400- GenCondition inverted = GenCondition::Reverse(cond);
10401- switch (inverted.GetCode())
10402- {
10403- case GenCondition::EQ:
10404- return INS_FLAGS_Z;
10405- case GenCondition::NE:
10406- return INS_FLAGS_NONE;
10407- case GenCondition::SGE:
10408- return INS_FLAGS_Z;
10409- case GenCondition::SGT:
10410- return INS_FLAGS_NONE;
10411- case GenCondition::SLT:
10412- return INS_FLAGS_NC;
10413- case GenCondition::SLE:
10414- return INS_FLAGS_NZC;
10415- case GenCondition::UGE:
10416- return INS_FLAGS_C;
10417- case GenCondition::UGT:
10418- return INS_FLAGS_C;
10419- case GenCondition::ULT:
10420- return INS_FLAGS_NONE;
10421- case GenCondition::ULE:
10422- return INS_FLAGS_Z;
10423- default:
10424- NO_WAY("unexpected condition type");
10425- return INS_FLAGS_NONE;
10426- }
10427- }
10428-
1042910276// ------------------------------------------------------------------------
1043010277// JumpKindToInsCond: Convert a Jump Kind to a condition.
1043110278//
0 commit comments