diff options
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 6dea471dd95..ae1c8b72e42 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -545,10 +545,38 @@ SDValue SystemZTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { DebugLoc dl = Op.getDebugLoc(); GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); - SDValue GA = DAG.getTargetGlobalAddress(GV, getPointerTy()); + int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); + + bool IsPic = getTargetMachine().getRelocationModel() == Reloc::PIC_; + bool ExtraLoadRequired = + Subtarget.GVRequiresExtraLoad(GV, getTargetMachine(), false); + + SDValue Result; + if (!IsPic && !ExtraLoadRequired) { + Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset); + Offset = 0; + } else { + unsigned char OpFlags = 0; + if (ExtraLoadRequired) + OpFlags = SystemZII::MO_GOTENT; + + Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), 0, OpFlags); + } + + Result = DAG.getNode(SystemZISD::PCRelativeWrapper, dl, + getPointerTy(), Result); + + if (ExtraLoadRequired) + Result = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Result, + PseudoSourceValue::getGOT(), 0); + + // If there was a non-zero offset that we didn't fold, create an explicit + // addition for it. + if (Offset != 0) + Result = DAG.getNode(ISD::ADD, dl, getPointerTy(), Result, + DAG.getConstant(Offset, getPointerTy())); - // FIXME: Verify stuff for constant globals entries - return DAG.getNode(SystemZISD::PCRelativeWrapper, dl, getPointerTy(), GA); + return Result; } |