@@ -85,11 +85,19 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
8585 // indirect jump.
8686 setOperationAction (ISD::BR_JT, MVT::Other, Custom);
8787
88- setOperationPromotedToType (ISD::BR_CC, MVT::i1, MVT::i32 );
8988 setOperationAction (ISD::BR_CC, MVT::i32 , Legal);
9089 setOperationAction (ISD::BR_CC, MVT::i64 , Expand);
9190 setOperationAction (ISD::BR_CC, MVT::f32 , Expand);
9291
92+ setOperationAction (ISD::SELECT, MVT::i32 , Expand);
93+ setOperationAction (ISD::SELECT_CC, MVT::i32 , Custom);
94+ setOperationAction (ISD::SETCC, MVT::i32 , Expand);
95+
96+ setCondCodeAction (ISD::SETGT, MVT::i32 , Expand);
97+ setCondCodeAction (ISD::SETLE, MVT::i32 , Expand);
98+ setCondCodeAction (ISD::SETUGT, MVT::i32 , Expand);
99+ setCondCodeAction (ISD::SETULE, MVT::i32 , Expand);
100+
93101 // Implement custom stack allocations
94102 setOperationAction (ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
95103 // Implement custom stack save and restore
@@ -514,6 +522,50 @@ XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
514522 return DAG.getNode (XtensaISD::RET, DL, MVT::Other, RetOps);
515523}
516524
525+ static unsigned getBranchOpcode (ISD::CondCode Cond) {
526+ switch (Cond) {
527+ case ISD::SETEQ:
528+ return Xtensa::BEQ;
529+ case ISD::SETNE:
530+ return Xtensa::BNE;
531+ case ISD::SETLT:
532+ return Xtensa::BLT;
533+ case ISD::SETLE:
534+ return Xtensa::BGE;
535+ case ISD::SETGT:
536+ return Xtensa::BLT;
537+ case ISD::SETGE:
538+ return Xtensa::BGE;
539+ case ISD::SETULT:
540+ return Xtensa::BLTU;
541+ case ISD::SETULE:
542+ return Xtensa::BGEU;
543+ case ISD::SETUGT:
544+ return Xtensa::BLTU;
545+ case ISD::SETUGE:
546+ return Xtensa::BGEU;
547+ default :
548+ llvm_unreachable (" Unknown branch kind" );
549+ }
550+ }
551+
552+ SDValue XtensaTargetLowering::LowerSELECT_CC (SDValue Op,
553+ SelectionDAG &DAG) const {
554+ SDLoc DL (Op);
555+ EVT Ty = Op.getOperand (0 ).getValueType ();
556+ SDValue LHS = Op.getOperand (0 );
557+ SDValue RHS = Op.getOperand (1 );
558+ SDValue TrueValue = Op.getOperand (2 );
559+ SDValue FalseValue = Op.getOperand (3 );
560+ ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand (4 ))->get ();
561+
562+ unsigned BrOpcode = getBranchOpcode (CC);
563+ SDValue TargetCC = DAG.getConstant (BrOpcode, DL, MVT::i32 );
564+
565+ return DAG.getNode (XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
566+ FalseValue, TargetCC);
567+ }
568+
517569SDValue XtensaTargetLowering::LowerImmediate (SDValue Op,
518570 SelectionDAG &DAG) const {
519571 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
@@ -676,6 +728,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
676728 return LowerJumpTable (Op, DAG);
677729 case ISD::ConstantPool:
678730 return LowerConstantPool (cast<ConstantPoolSDNode>(Op), DAG);
731+ case ISD::SELECT_CC:
732+ return LowerSELECT_CC (Op, DAG);
679733 case ISD::STACKSAVE:
680734 return LowerSTACKSAVE (Op, DAG);
681735 case ISD::STACKRESTORE:
@@ -697,6 +751,86 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
697751 return " XtensaISD::PCREL_WRAPPER" ;
698752 case XtensaISD::RET:
699753 return " XtensaISD::RET" ;
754+ case XtensaISD::SELECT_CC:
755+ return " XtensaISD::SELECT_CC" ;
700756 }
701757 return nullptr ;
702758}
759+
760+ // ===----------------------------------------------------------------------===//
761+ // Custom insertion
762+ // ===----------------------------------------------------------------------===//
763+
764+ MachineBasicBlock *
765+ XtensaTargetLowering::emitSelectCC (MachineInstr &MI,
766+ MachineBasicBlock *MBB) const {
767+ const TargetInstrInfo &TII = *Subtarget.getInstrInfo ();
768+ DebugLoc DL = MI.getDebugLoc ();
769+
770+ MachineOperand &LHS = MI.getOperand (1 );
771+ MachineOperand &RHS = MI.getOperand (2 );
772+ MachineOperand &TrueValue = MI.getOperand (3 );
773+ MachineOperand &FalseValue = MI.getOperand (4 );
774+ unsigned BrKind = MI.getOperand (5 ).getImm ();
775+
776+ // To "insert" a SELECT_CC instruction, we actually have to insert
777+ // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi
778+ // operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue
779+ // is passed from MMB and FalseValue is passed from CopyMBB.
780+ // MBB
781+ // | \
782+ // | CopyMBB
783+ // | /
784+ // SinkMBB
785+ // The incoming instruction knows the
786+ // destination vreg to set, the condition code register to branch on, the
787+ // true/false values to select between, and a branch opcode to use.
788+ const BasicBlock *LLVM_BB = MBB->getBasicBlock ();
789+ MachineFunction::iterator It = ++MBB->getIterator ();
790+
791+ MachineFunction *F = MBB->getParent ();
792+ MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock (LLVM_BB);
793+ MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock (LLVM_BB);
794+
795+ F->insert (It, CopyMBB);
796+ F->insert (It, SinkMBB);
797+
798+ // Transfer the remainder of MBB and its successor edges to SinkMBB.
799+ SinkMBB->splice (SinkMBB->begin (), MBB,
800+ std::next (MachineBasicBlock::iterator (MI)), MBB->end ());
801+ SinkMBB->transferSuccessorsAndUpdatePHIs (MBB);
802+
803+ MBB->addSuccessor (CopyMBB);
804+ MBB->addSuccessor (SinkMBB);
805+
806+ BuildMI (MBB, DL, TII.get (BrKind))
807+ .addReg (LHS.getReg ())
808+ .addReg (RHS.getReg ())
809+ .addMBB (SinkMBB);
810+
811+ CopyMBB->addSuccessor (SinkMBB);
812+
813+ // SinkMBB:
814+ // %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]
815+ // ...
816+
817+ BuildMI (*SinkMBB, SinkMBB->begin (), DL, TII.get (Xtensa::PHI),
818+ MI.getOperand (0 ).getReg ())
819+ .addReg (FalseValue.getReg ())
820+ .addMBB (CopyMBB)
821+ .addReg (TrueValue.getReg ())
822+ .addMBB (MBB);
823+
824+ MI.eraseFromParent (); // The pseudo instruction is gone now.
825+ return SinkMBB;
826+ }
827+
828+ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter (
829+ MachineInstr &MI, MachineBasicBlock *MBB) const {
830+ switch (MI.getOpcode ()) {
831+ case Xtensa::SELECT:
832+ return emitSelectCC (MI, MBB);
833+ default :
834+ llvm_unreachable (" Unexpected instr type to insert" );
835+ }
836+ }
0 commit comments