aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Sparc/SparcISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Sparc/SparcISelLowering.cpp')
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp48
1 files changed, 42 insertions, 6 deletions
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index d9548ff90d7f..b04c6b112682 100644
--- a/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1450,7 +1450,7 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
const SparcSubtarget &STI)
: TargetLowering(TM), Subtarget(&STI) {
- MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize());
+ MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize(0));
// Instructions which use registers as conditionals examine all the
// bits (as does the pseudo SELECT_CC expansion). I don't think it
@@ -1590,6 +1590,11 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
+ setOperationAction(ISD::ADDC, MVT::i32, Custom);
+ setOperationAction(ISD::ADDE, MVT::i32, Custom);
+ setOperationAction(ISD::SUBC, MVT::i32, Custom);
+ setOperationAction(ISD::SUBE, MVT::i32, Custom);
+
if (Subtarget->is64Bit()) {
setOperationAction(ISD::ADDC, MVT::i64, Custom);
setOperationAction(ISD::ADDE, MVT::i64, Custom);
@@ -1700,6 +1705,9 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::UDIV, MVT::i32, Expand);
setLibcallName(RTLIB::UDIV_I32, ".udiv");
+
+ setLibcallName(RTLIB::SREM_I32, ".rem");
+ setLibcallName(RTLIB::UREM_I32, ".urem");
}
if (Subtarget->is64Bit()) {
@@ -1722,6 +1730,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::VAARG , MVT::Other, Custom);
setOperationAction(ISD::TRAP , MVT::Other, Legal);
+ setOperationAction(ISD::DEBUGTRAP , MVT::Other, Legal);
// Use the default implementation.
setOperationAction(ISD::VACOPY , MVT::Other, Expand);
@@ -1975,11 +1984,22 @@ SDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const {
// Handle PIC mode first. SPARC needs a got load for every variable!
if (isPositionIndependent()) {
- // This is the pic32 code model, the GOT is known to be smaller than 4GB.
- SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22,
- SparcMCExpr::VK_Sparc_GOT10, DAG);
+ const Module *M = DAG.getMachineFunction().getFunction().getParent();
+ PICLevel::Level picLevel = M->getPICLevel();
+ SDValue Idx;
+
+ if (picLevel == PICLevel::SmallPIC) {
+ // This is the pic13 code model, the GOT is known to be smaller than 8KiB.
+ Idx = DAG.getNode(SPISD::Lo, DL, Op.getValueType(),
+ withTargetFlags(Op, SparcMCExpr::VK_Sparc_GOT13, DAG));
+ } else {
+ // This is the pic32 code model, the GOT is known to be smaller than 4GB.
+ Idx = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22,
+ SparcMCExpr::VK_Sparc_GOT10, DAG);
+ }
+
SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
- SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo);
+ SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, Idx);
// GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
// function has calls.
MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
@@ -2036,7 +2056,7 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress(SDValue Op,
SelectionDAG &DAG) const {
GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
- if (DAG.getTarget().Options.EmulatedTLS)
+ if (DAG.getTarget().useEmulatedTLS())
return LowerToTLSEmulatedModel(GA, DAG);
SDLoc DL(GA);
@@ -3513,6 +3533,22 @@ SparcTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint,
VT);
}
+ if (name.substr(0, 1).equals("f") &&
+ !name.substr(1).getAsInteger(10, intVal) && intVal <= 63) {
+ std::string newConstraint;
+
+ if (VT == MVT::f32 || VT == MVT::Other) {
+ newConstraint = "{f" + utostr(intVal) + "}";
+ } else if (VT == MVT::f64 && (intVal % 2 == 0)) {
+ newConstraint = "{d" + utostr(intVal / 2) + "}";
+ } else if (VT == MVT::f128 && (intVal % 4 == 0)) {
+ newConstraint = "{q" + utostr(intVal / 4) + "}";
+ } else {
+ return std::make_pair(0U, nullptr);
+ }
+ return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint,
+ VT);
+ }
}
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);