diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index ab8be5a3fbb..58ca76a230c 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -65,6 +65,7 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : setOperationAction(ISD::SRA, MVT::i16, Custom); setOperationAction(ISD::RET, MVT::Other, Custom); + setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); } SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { @@ -73,6 +74,7 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SRA: return LowerShifts(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); case ISD::CALL: return LowerCALL(Op, DAG); + case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); default: assert(0 && "unimplemented operand"); return SDValue(); @@ -421,11 +423,22 @@ SDValue MSP430TargetLowering::LowerShifts(SDValue Op, return Victim; } +SDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { + const GlobalValue *GV = cast(Op)->getGlobal(); + int64_t Offset = cast(Op)->getOffset(); + + // Create the TargetGlobalAddress node, folding in the constant offset. + SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset); + return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(), + getPointerTy(), Result); +} + const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { default: return NULL; case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; case MSP430ISD::RRA: return "MSP430ISD::RRA"; case MSP430ISD::CALL: return "MSP430ISD::CALL"; + case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; } } diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h index 9e18cb093dd..a1f03ac9633 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.h +++ b/lib/Target/MSP430/MSP430ISelLowering.h @@ -32,7 +32,11 @@ namespace llvm { /// CALL/TAILCALL - These operations represent an abstract call /// instruction, which includes a bunch of information. - CALL + CALL, + + /// Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol, + /// and TargetGlobalAddress. + Wrapper }; } @@ -55,6 +59,7 @@ namespace llvm { SDValue LowerRET(SDValue Op, SelectionDAG &DAG); SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG); SDValue LowerShifts(SDValue Op, SelectionDAG &DAG); + SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC); diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td index 5d3566df5ff..e337b291e0d 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.td +++ b/lib/Target/MSP430/MSP430InstrInfo.td @@ -25,6 +25,7 @@ class SDTCisI16 : SDTCisVT; def SDT_MSP430Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; def SDT_MSP430CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>]>; def SDT_MSP430CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>; +def SDT_MSP430Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; //===----------------------------------------------------------------------===// // MSP430 Specific Node Definitions. @@ -42,6 +43,7 @@ def MSP430callseq_start : def MSP430callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MSP430CallSeqEnd, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; +def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>; //===----------------------------------------------------------------------===// // MSP430 Operand Definitions. @@ -611,6 +613,12 @@ def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>; def : Pat<(i8 (trunc GR16:$src)), (EXTRACT_SUBREG GR16:$src, subreg_8bit)>; +// GlobalAddress +def : Pat<(i16 (MSP430Wrapper tglobaladdr :$dst)), (MOV16ri tglobaladdr :$dst)>; + +def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)), + (ADD16ri GR16:$src1, tglobaladdr:$src2)>; + // calls def : Pat<(MSP430call (i16 tglobaladdr:$dst)), (CALLi tglobaladdr:$dst)>;