@@ -77,6 +77,18 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
7777 }
7878
7979 setOperationAction (ISD::ConstantPool, PtrVT, Custom);
80+ setOperationAction (ISD::GlobalAddress, PtrVT, Custom);
81+ setOperationAction (ISD::BlockAddress, PtrVT, Custom);
82+ setOperationAction (ISD::JumpTable, PtrVT, Custom);
83+
84+ // Expand jump table branches as address arithmetic followed by an
85+ // indirect jump.
86+ setOperationAction (ISD::BR_JT, MVT::Other, Custom);
87+
88+ setOperationPromotedToType (ISD::BR_CC, MVT::i1, MVT::i32 );
89+ setOperationAction (ISD::BR_CC, MVT::i32 , Legal);
90+ setOperationAction (ISD::BR_CC, MVT::i64 , Expand);
91+ setOperationAction (ISD::BR_CC, MVT::f32 , Expand);
8092
8193 // Implement custom stack allocations
8294 setOperationAction (ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
@@ -88,6 +100,12 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
88100 computeRegisterProperties (STI.getRegisterInfo ());
89101}
90102
103+ bool XtensaTargetLowering::isOffsetFoldingLegal (
104+ const GlobalAddressSDNode *GA) const {
105+ // The Xtensa target isn't yet aware of offsets.
106+ return false ;
107+ }
108+
91109// ===----------------------------------------------------------------------===//
92110// Calling conventions
93111// ===----------------------------------------------------------------------===//
@@ -519,6 +537,72 @@ SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
519537 return Op;
520538}
521539
540+ SDValue XtensaTargetLowering::LowerGlobalAddress (SDValue Op,
541+ SelectionDAG &DAG) const {
542+ const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
543+ SDLoc DL (Op);
544+ auto PtrVT = Op.getValueType ();
545+ const GlobalValue *GV = G->getGlobal ();
546+
547+ SDValue CPAddr = DAG.getTargetConstantPool (GV, PtrVT, Align (4 ));
548+ SDValue CPWrap = getAddrPCRel (CPAddr, DAG);
549+
550+ return CPWrap;
551+ }
552+
553+ SDValue XtensaTargetLowering::LowerBlockAddress (SDValue Op,
554+ SelectionDAG &DAG) const {
555+ BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
556+ const BlockAddress *BA = Node->getBlockAddress ();
557+ EVT PtrVT = Op.getValueType ();
558+
559+ XtensaConstantPoolValue *CPV =
560+ XtensaConstantPoolConstant::Create (BA, 0 , XtensaCP::CPBlockAddress);
561+ SDValue CPAddr = DAG.getTargetConstantPool (CPV, PtrVT, Align (4 ));
562+ SDValue CPWrap = getAddrPCRel (CPAddr, DAG);
563+
564+ return CPWrap;
565+ }
566+
567+ SDValue XtensaTargetLowering::LowerBR_JT (SDValue Op, SelectionDAG &DAG) const {
568+ SDValue Chain = Op.getOperand (0 );
569+ SDValue Table = Op.getOperand (1 );
570+ SDValue Index = Op.getOperand (2 );
571+ SDLoc DL (Op);
572+ JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
573+ MachineFunction &MF = DAG.getMachineFunction ();
574+ const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ();
575+ SDValue TargetJT = DAG.getTargetJumpTable (JT->getIndex (), MVT::i32 );
576+ const DataLayout &TD = DAG.getDataLayout ();
577+ EVT PtrVT = Table.getValueType ();
578+ unsigned EntrySize = MJTI->getEntrySize (TD);
579+
580+ Index = DAG.getNode (ISD::MUL, DL, Index.getValueType (), Index,
581+ DAG.getConstant (EntrySize, DL, Index.getValueType ()));
582+ SDValue Addr = DAG.getNode (ISD::ADD, DL, Index.getValueType (), Index, Table);
583+ SDValue LD =
584+ DAG.getLoad (PtrVT, DL, Chain, Addr,
585+ MachinePointerInfo::getJumpTable (DAG.getMachineFunction ()));
586+
587+ return DAG.getNode (XtensaISD::BR_JT, DL, MVT::Other, LD.getValue (1 ), LD,
588+ TargetJT);
589+ }
590+
591+ SDValue XtensaTargetLowering::LowerJumpTable (SDValue Op,
592+ SelectionDAG &DAG) const {
593+ JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
594+ EVT PtrVT = Op.getValueType ();
595+
596+ // Create a constant pool entry for the callee address
597+ XtensaConstantPoolValue *CPV =
598+ XtensaConstantPoolJumpTable::Create (*DAG.getContext (), JT->getIndex ());
599+
600+ // Get the address of the callee into a register
601+ SDValue CPAddr = DAG.getTargetConstantPool (CPV, PtrVT, Align (4 ));
602+
603+ return getAddrPCRel (CPAddr, DAG);
604+ }
605+
522606SDValue XtensaTargetLowering::getAddrPCRel (SDValue Op,
523607 SelectionDAG &DAG) const {
524608 SDLoc DL (Op);
@@ -580,8 +664,16 @@ SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
580664SDValue XtensaTargetLowering::LowerOperation (SDValue Op,
581665 SelectionDAG &DAG) const {
582666 switch (Op.getOpcode ()) {
667+ case ISD::BR_JT:
668+ return LowerBR_JT (Op, DAG);
583669 case ISD::Constant:
584670 return LowerImmediate (Op, DAG);
671+ case ISD::GlobalAddress:
672+ return LowerGlobalAddress (Op, DAG);
673+ case ISD::BlockAddress:
674+ return LowerBlockAddress (Op, DAG);
675+ case ISD::JumpTable:
676+ return LowerJumpTable (Op, DAG);
585677 case ISD::ConstantPool:
586678 return LowerConstantPool (cast<ConstantPoolSDNode>(Op), DAG);
587679 case ISD::STACKSAVE:
@@ -597,6 +689,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
597689
598690const char *XtensaTargetLowering::getTargetNodeName (unsigned Opcode) const {
599691 switch (Opcode) {
692+ case XtensaISD::BR_JT:
693+ return " XtensaISD::BR_JT" ;
600694 case XtensaISD::CALL:
601695 return " XtensaISD::CALL" ;
602696 case XtensaISD::PCREL_WRAPPER:
0 commit comments