aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Sparc
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-04-14 04:35:16 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-04-14 04:35:16 +0000
commit26932106562adbe3f186b8f32fd5057d9f373875 (patch)
tree8658b7dc12581cafc3818ab4195c438e7e4ec5ea /lib/Target/Sparc
parentf7eaf29cf70a545f5b717c638db83ba6e8b6b3c5 (diff)
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
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp61
-rw-r--r--lib/Target/Sparc/SparcISelLowering.h1
2 files changed, 36 insertions, 26 deletions
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index 322f573510..cfe3d4f296 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<ConstantPoolSDNode>(Op))
+ return DAG.getTargetConstantPool(CP->getConstVal(),
+ CP->getValueType(0),
+ CP->getAlignment(),
+ CP->getOffset(), TF);
+
+ if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(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<ConstantPoolSDNode>(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 3ccdf7a973..21c183113b 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