@@ -85,11 +85,19 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
85
85
// indirect jump.
86
86
setOperationAction (ISD::BR_JT, MVT::Other, Custom);
87
87
88
- setOperationPromotedToType (ISD::BR_CC, MVT::i1, MVT::i32);
89
88
setOperationAction (ISD::BR_CC, MVT::i32, Legal);
90
89
setOperationAction (ISD::BR_CC, MVT::i64, Expand);
91
90
setOperationAction (ISD::BR_CC, MVT::f32, Expand);
92
91
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
+
93
101
// Implement custom stack allocations
94
102
setOperationAction (ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
95
103
// Implement custom stack save and restore
@@ -514,6 +522,50 @@ XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
514
522
return DAG.getNode (XtensaISD::RET, DL, MVT::Other, RetOps);
515
523
}
516
524
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
+
517
569
SDValue XtensaTargetLowering::LowerImmediate (SDValue Op,
518
570
SelectionDAG &DAG) const {
519
571
const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
@@ -676,6 +728,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
676
728
return LowerJumpTable (Op, DAG);
677
729
case ISD::ConstantPool:
678
730
return LowerConstantPool (cast<ConstantPoolSDNode>(Op), DAG);
731
+ case ISD::SELECT_CC:
732
+ return LowerSELECT_CC (Op, DAG);
679
733
case ISD::STACKSAVE:
680
734
return LowerSTACKSAVE (Op, DAG);
681
735
case ISD::STACKRESTORE:
@@ -697,6 +751,86 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
697
751
return " XtensaISD::PCREL_WRAPPER" ;
698
752
case XtensaISD::RET:
699
753
return " XtensaISD::RET" ;
754
+ case XtensaISD::SELECT_CC:
755
+ return " XtensaISD::SELECT_CC" ;
700
756
}
701
757
return nullptr ;
702
758
}
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