Minor fixes.
Added ConstantPool support.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53951 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index d991658..d6e5ecc 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -86,7 +86,7 @@
   setOperationAction(ISD::GlobalTLSAddress, MVT::i32,   Custom);
   setOperationAction(ISD::RET,              MVT::Other, Custom);
   setOperationAction(ISD::JumpTable,        MVT::i32,   Custom);
-  setOperationAction(ISD::ConstantPool,     MVT::f32,   Custom);
+  setOperationAction(ISD::ConstantPool,     MVT::i32,   Custom);
   setOperationAction(ISD::SELECT_CC,        MVT::i32,   Custom);
   setOperationAction(ISD::SELECT_CC,        MVT::f32,   Custom);
 
@@ -234,10 +234,14 @@
   return VReg;
 }
 
+// A address must be loaded from a small section if its size is less than the 
+// small section size threshold. Data in this section must be addressed using 
+// gp_rel operator.
+bool MipsTargetLowering::IsInSmallSection(unsigned Size) {
+  return (Size > 0 && (Size <= Subtarget->getSSectionThreshold()));
+}
+
 // Discover if this global address can be placed into small data/bss section. 
-// This should happen for globals with size less than small section size 
-// threshold in no abicall environments. Data in this section must be addressed 
-// using gp_rel operator.
 bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV)
 {
   const TargetData *TD = getTargetData();
@@ -258,10 +262,7 @@
       return false;
   }
 
-  if (Size > 0 && (Size <= Subtarget->getSSectionThreshold()))
-    return true;
-
-  return false;
+  return IsInSmallSection(Size);
 }
 
 //===----------------------------------------------------------------------===//
@@ -352,8 +353,24 @@
 SDOperand MipsTargetLowering::
 LowerConstantPool(SDOperand Op, SelectionDAG &DAG) 
 {
-  assert(0 && "ConstantPool not implemented for MIPS.");
-  return SDOperand(); // Not reached
+  SDOperand ResNode;
+  ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
+  Constant *C = N->getConstVal();
+  SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment());
+
+  // gp_rel relocation
+  if (!Subtarget->hasABICall() &&  
+      IsInSmallSection(getTargetData()->getABITypeSize(C->getType()))) {
+    SDOperand GPRelNode = DAG.getNode(MipsISD::GPRel, MVT::i32, CP);
+    SDOperand GOT = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i32);
+    ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode); 
+  } else { // %hi/%lo relocation
+    SDOperand HiPart = DAG.getNode(MipsISD::Hi, MVT::i32, CP);
+    SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, CP);
+    ResNode = DAG.getNode(ISD::ADD, MVT::i32, HiPart, Lo);
+  }
+
+  return ResNode;
 }
 
 //===----------------------------------------------------------------------===//