+/// LegalizeSetCCCondCode - Legalize a SETCC with given LHS and RHS and
+/// condition code CC on the current target. This routine assumes LHS and rHS
+/// have already been legalized by LegalizeSetCCOperands. It expands SETCC with
+/// illegal condition code into AND / OR of multiple SETCC values.
+void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT,
+ SDValue &LHS, SDValue &RHS,
+ SDValue &CC) {
+ MVT OpVT = LHS.getValueType();
+ ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
+ switch (TLI.getCondCodeAction(CCCode, OpVT)) {
+ default: assert(0 && "Unknown condition code action!");
+ case TargetLowering::Legal:
+ // Nothing to do.
+ break;
+ case TargetLowering::Expand: {
+ ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID;
+ unsigned Opc = 0;
+ switch (CCCode) {
+ default: assert(0 && "Don't know how to expand this condition!"); abort();
+ case ISD::SETOEQ: CC1 = ISD::SETO; CC2 = ISD::SETEQ; Opc = ISD::AND; break;
+ case ISD::SETOGT: CC1 = ISD::SETO; CC2 = ISD::SETGT; Opc = ISD::AND; break;
+ case ISD::SETOGE: CC1 = ISD::SETO; CC2 = ISD::SETGE; Opc = ISD::AND; break;
+ case ISD::SETOLT: CC1 = ISD::SETO; CC2 = ISD::SETLT; Opc = ISD::AND; break;
+ case ISD::SETOLE: CC1 = ISD::SETO; CC2 = ISD::SETLE; Opc = ISD::AND; break;
+ case ISD::SETONE: CC1 = ISD::SETO; CC2 = ISD::SETNE; Opc = ISD::AND; break;
+ case ISD::SETUEQ: CC1 = ISD::SETUO; CC2 = ISD::SETEQ; Opc = ISD::OR; break;
+ case ISD::SETUGT: CC1 = ISD::SETUO; CC2 = ISD::SETGT; Opc = ISD::OR; break;
+ case ISD::SETUGE: CC1 = ISD::SETUO; CC2 = ISD::SETGE; Opc = ISD::OR; break;
+ case ISD::SETULT: CC1 = ISD::SETUO; CC2 = ISD::SETLT; Opc = ISD::OR; break;
+ case ISD::SETULE: CC1 = ISD::SETUO; CC2 = ISD::SETLE; Opc = ISD::OR; break;
+ case ISD::SETUNE: CC1 = ISD::SETUO; CC2 = ISD::SETNE; Opc = ISD::OR; break;
+ // FIXME: Implement more expansions.
+ }
+
+ SDValue SetCC1 = DAG.getSetCC(VT, LHS, RHS, CC1);
+ SDValue SetCC2 = DAG.getSetCC(VT, LHS, RHS, CC2);
+ LHS = DAG.getNode(Opc, VT, SetCC1, SetCC2);
+ RHS = SDValue();
+ CC = SDValue();
+ break;
+ }
+ }
+}
+