From 26932106562adbe3f186b8f32fd5057d9f373875 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 14 Apr 2013 04:35:16 +0000 Subject: [PATCH] Also put target flags on SPARC constant pool references. Constant pool entries are accessed exactly the same way as global variables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179471 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Sparc/SparcISelLowering.cpp | 61 +++++++++++++++----------- lib/Target/Sparc/SparcISelLowering.h | 1 + test/CodeGen/SPARC/constpool.ll | 30 +++++++++++++ 3 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 test/CodeGen/SPARC/constpool.ll diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 322f5735105..cfe3d4f2967 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -1363,6 +1363,17 @@ SDValue SparcTargetLowering::withTargetFlags(SDValue Op, unsigned TF, GA->getDebugLoc(), GA->getValueType(0), GA->getOffset(), TF); + + if (const ConstantPoolSDNode *CP = dyn_cast(Op)) + return DAG.getTargetConstantPool(CP->getConstVal(), + CP->getValueType(0), + CP->getAlignment(), + CP->getOffset(), TF); + + if (const ExternalSymbolSDNode *ES = dyn_cast(Op)) + return DAG.getTargetExternalSymbol(ES->getSymbol(), + ES->getValueType(0), TF); + llvm_unreachable("Unhandled address SDNode"); } @@ -1378,38 +1389,36 @@ SDValue SparcTargetLowering::makeHiLoPair(SDValue Op, return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); } +// Build SDNodes for producing an address from a GlobalAddress, ConstantPool, +// or ExternalSymbol SDNode. +SDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { + // Handle PIC mode first. + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { + // This is the pic32 code model, the GOT is known to be smaller than 4GB. + SDValue HiLo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG); + DebugLoc DL = Op.getDebugLoc(); + EVT VT = getPointerTy(); + SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT); + SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo); + return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr, + MachinePointerInfo::getGOT(), false, false, false, 0); + } + + // This is one of the absolute code models. + assert(getTargetMachine().getCodeModel() == CodeModel::Small && + "Only the abs32 code model is supported"); + + return makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG); +} + SDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { - SDValue HiLo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG); - if (getTargetMachine().getRelocationModel() != Reloc::PIC_) - return HiLo; - - DebugLoc DL = Op.getDebugLoc(); - SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, getPointerTy()); - SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, getPointerTy(), GlobalBase, HiLo); - return DAG.getLoad(getPointerTy(), DL, DAG.getEntryNode(), - AbsAddr, MachinePointerInfo(), false, false, false, 0); + return makeAddress(Op, DAG); } SDValue SparcTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { - ConstantPoolSDNode *N = cast(Op); - // FIXME there isn't really any debug info here - DebugLoc dl = Op.getDebugLoc(); - const Constant *C = N->getConstVal(); - SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment()); - SDValue Hi = DAG.getNode(SPISD::Hi, dl, MVT::i32, CP); - SDValue Lo = DAG.getNode(SPISD::Lo, dl, MVT::i32, CP); - if (getTargetMachine().getRelocationModel() != Reloc::PIC_) - return DAG.getNode(ISD::ADD, dl, MVT::i32, Lo, Hi); - - SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, dl, - getPointerTy()); - SDValue RelAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Lo, Hi); - SDValue AbsAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, - GlobalBase, RelAddr); - return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), - AbsAddr, MachinePointerInfo(), false, false, false, 0); + return makeAddress(Op, DAG); } static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) { diff --git a/lib/Target/Sparc/SparcISelLowering.h b/lib/Target/Sparc/SparcISelLowering.h index 3ccdf7a973d..21c183113bf 100644 --- a/lib/Target/Sparc/SparcISelLowering.h +++ b/lib/Target/Sparc/SparcISelLowering.h @@ -124,6 +124,7 @@ namespace llvm { SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, SelectionDAG &DAG) const; + SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; }; } // end namespace llvm diff --git a/test/CodeGen/SPARC/constpool.ll b/test/CodeGen/SPARC/constpool.ll new file mode 100644 index 00000000000..76c485ea196 --- /dev/null +++ b/test/CodeGen/SPARC/constpool.ll @@ -0,0 +1,30 @@ +; RUN: llc < %s -march=sparc -relocation-model=static -code-model=small | FileCheck --check-prefix=abs32 %s +; RUN: llc < %s -march=sparcv9 -relocation-model=static -code-model=small | FileCheck --check-prefix=abs32 %s +; RUN: llc < %s -march=sparc -relocation-model=pic -code-model=medium | FileCheck --check-prefix=v8pic32 %s +; RUN: llc < %s -march=sparcv9 -relocation-model=pic -code-model=medium | FileCheck --check-prefix=v9pic32 %s + +define float @floatCP() { +entry: + ret float 1.000000e+00 +} + +; abs32: floatCP +; abs32: sethi %hi(.LCPI0_0), %[[R:[gilo][0-7]]] +; abs32: ld [%[[R]]+%lo(.LCPI0_0)], %f +; abs32: jmp %i7+8 + +; v8pic32: floatCP +; v8pic32: _GLOBAL_OFFSET_TABLE_ +; v8pic32: sethi %hi(.LCPI0_0), %[[R1:[gilo][0-7]]] +; v8pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]] +; v8pic32: ld [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] +; v8pic32: ld [%[[Gaddr]]], %f0 +; v8pic32: jmp %i7+8 + +; v9pic32: floatCP +; v9pic32: _GLOBAL_OFFSET_TABLE_ +; v9pic32: sethi %hi(.LCPI0_0), %[[R1:[gilo][0-7]]] +; v9pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]] +; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]] +; v9pic32: ld [%[[Gaddr]]], %f1 +; v9pic32: jmp %i7+8 -- 2.34.1