[mips] N64 static relocation model support

This patch makes one change to GOT handling and two changes to N64's
relocation model handling. Furthermore, the jumptable encodings have
been corrected for static N64.

Big GOT handling is now done via a new SDNode MipsGotHi - this node is
unconditionally lowered to an lui instruction.

The first change to N64's relocation handling is the lifting of the
restriction that N64 always uses PIC. Now it is possible to target static
environments.

The second change adds support for 64 bit symbols and enables them by
default. Previously N64 had patterns for sym32 mode only. In this mode all
symbols are assumed to have 32 bit addresses. sym32 mode support
is selectable with attribute 'sym32'. A follow on patch for clang will
add the necessary frontend parameter.

This partially resolves PR/23485.

Thanks to Brooks Davis for reporting the issue!

Reviewers: dsanders, seanbruno, zoran.jovanovic, vkalintiris

Differential Revision: https://reviews.llvm.org/D23652

llvm-svn: 293164
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index b2efd72..44494b1 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -524,6 +524,8 @@
   case ELF::R_MIPS_GOT16:
   case ELF::R_MIPS16_GOT16:
   case ELF::R_MICROMIPS_GOT16:
+  case ELF::R_MIPS_HIGHER:
+  case ELF::R_MIPS_HIGHEST:
   case ELF::R_MIPS_HI16:
   case ELF::R_MIPS16_HI16:
   case ELF::R_MICROMIPS_HI16:
@@ -567,8 +569,6 @@
   case ELF::R_MIPS_INSERT_A:
   case ELF::R_MIPS_INSERT_B:
   case ELF::R_MIPS_DELETE:
-  case ELF::R_MIPS_HIGHER:
-  case ELF::R_MIPS_HIGHEST:
   case ELF::R_MIPS_CALL_HI16:
   case ELF::R_MIPS_CALL_LO16:
   case ELF::R_MIPS_SCN_DISP:
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 7f79eb4..93c74fa 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -721,10 +721,6 @@
   if (Features[Mips::FeatureNaN2008])
     EFlags |= ELF::EF_MIPS_NAN2008;
 
-  // -mabicalls and -mplt are not implemented but we should act as if they were
-  // given.
-  EFlags |= ELF::EF_MIPS_CPIC;
-
   MCA.setELFHeaderEFlags(EFlags);
 }
 
@@ -795,10 +791,14 @@
   } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
     EFlags |= ELF::EF_MIPS_32BITMODE;
 
-  // If we've set the cpic eflag and we're n64, go ahead and set the pic
-  // one as well.
-  if (EFlags & ELF::EF_MIPS_CPIC && getABI().IsN64())
-    EFlags |= ELF::EF_MIPS_PIC;
+  // -mplt is not implemented but we should act as if it was
+  // given.
+  if ((!Features[Mips::FeatureNoABICalls] && !getABI().IsN64()) ||
+      (getABI().IsN64() && Features[Mips::FeatureSym32]))
+    EFlags |= ELF::EF_MIPS_CPIC;
+
+  if (Pic)
+    EFlags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC;
 
   MCA.setELFHeaderEFlags(EFlags);
 
diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
index 05aad51..6b7f39e 100644
--- a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
@@ -475,29 +475,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-def : MipsPat<(MipsLo tglobaladdr:$in),
-              (DADDIU_MM64R6 ZERO_64, tglobaladdr:$in)>, ISA_MICROMIPS64R6;
-def : MipsPat<(MipsLo tblockaddress:$in),
-              (DADDIU_MM64R6 ZERO_64, tblockaddress:$in)>, ISA_MICROMIPS64R6;
-def : MipsPat<(MipsLo tjumptable:$in),
-              (DADDIU_MM64R6 ZERO_64, tjumptable:$in)>, ISA_MICROMIPS64R6;
-def : MipsPat<(MipsLo tconstpool:$in),
-              (DADDIU_MM64R6 ZERO_64, tconstpool:$in)>, ISA_MICROMIPS64R6;
-def : MipsPat<(MipsLo tglobaltlsaddr:$in),
-              (DADDIU_MM64R6 ZERO_64, tglobaltlsaddr:$in)>, ISA_MICROMIPS64R6;
-def : MipsPat<(MipsLo texternalsym:$in),
-              (DADDIU_MM64R6 ZERO_64, texternalsym:$in)>, ISA_MICROMIPS64R6;
+defm : MipsHiLoRelocs<LUi64, DADDIU_MM64R6, ZERO_64, GPR64Opnd>, SYM_32,
+                      ISA_MICROMIPS64R6;
 
-def : MipsPat<(add GPR64:$hi, (MipsLo tglobaladdr:$lo)),
-              (DADDIU_MM64R6 GPR64:$hi, tglobaladdr:$lo)>, ISA_MICROMIPS64R6;
-def : MipsPat<(add GPR64:$hi, (MipsLo tblockaddress:$lo)),
-              (DADDIU_MM64R6 GPR64:$hi, tblockaddress:$lo)>, ISA_MICROMIPS64R6;
-def : MipsPat<(add GPR64:$hi, (MipsLo tjumptable:$lo)),
-              (DADDIU_MM64R6 GPR64:$hi, tjumptable:$lo)>, ISA_MICROMIPS64R6;
-def : MipsPat<(add GPR64:$hi, (MipsLo tconstpool:$lo)),
-              (DADDIU_MM64R6 GPR64:$hi, tconstpool:$lo)>, ISA_MICROMIPS64R6;
-def : MipsPat<(add GPR64:$hi, (MipsLo tglobaltlsaddr:$lo)),
-              (DADDIU_MM64R6 GPR64:$hi, tglobaltlsaddr:$lo)>, ISA_MICROMIPS64R6;
+defm : MipsHighestHigherHiLoRelocs<LUi64, DADDIU_MM64R6>, SYM_64,
+                                   ISA_MICROMIPS64R6;
 
 def : MipsPat<(addc GPR64:$lhs, GPR64:$rhs),
               (DADDU_MM64R6 GPR64:$lhs, GPR64:$rhs)>, ISA_MICROMIPS64R6;
diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td
index 670272d..9615bc3 100644
--- a/llvm/lib/Target/Mips/Mips.td
+++ b/llvm/lib/Target/Mips/Mips.td
@@ -156,6 +156,8 @@
                                 "Mips64r6 ISA Support [experimental]",
                                 [FeatureMips32r6, FeatureMips64r5,
                                  FeatureNaN2008]>;
+def FeatureSym32       : SubtargetFeature<"sym32", "HasSym32", "true",
+                                          "Symbols are 32 bit on Mips64">;
 
 def FeatureMips16  : SubtargetFeature<"mips16", "InMips16Mode", "true",
                                       "Mips16 mode">;
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index 521e22f..03882da 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -513,42 +513,88 @@
 def : MipsPat<(i64 (extloadi32 addr:$src)), (LW64 addr:$src)>;
 
 // hi/lo relocs
-def : MipsPat<(MipsHi tglobaladdr:$in), (LUi64 tglobaladdr:$in)>;
-def : MipsPat<(MipsHi tblockaddress:$in), (LUi64 tblockaddress:$in)>;
-def : MipsPat<(MipsHi tjumptable:$in), (LUi64 tjumptable:$in)>;
-def : MipsPat<(MipsHi tconstpool:$in), (LUi64 tconstpool:$in)>;
-def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi64 tglobaltlsaddr:$in)>;
-def : MipsPat<(MipsHi texternalsym:$in), (LUi64 texternalsym:$in)>;
+let AdditionalPredicates = [NotInMicroMips] in
+defm : MipsHiLoRelocs<LUi64, DADDiu, ZERO_64, GPR64Opnd>, SYM_32;
 
-let AdditionalPredicates = [NotInMicroMips] in {
-  def : MipsPat<(MipsLo tglobaladdr:$in), (DADDiu ZERO_64, tglobaladdr:$in)>;
-  def : MipsPat<(MipsLo tblockaddress:$in),
-                (DADDiu ZERO_64, tblockaddress:$in)>;
-  def : MipsPat<(MipsLo tjumptable:$in), (DADDiu ZERO_64, tjumptable:$in)>;
-  def : MipsPat<(MipsLo tconstpool:$in), (DADDiu ZERO_64, tconstpool:$in)>;
-  def : MipsPat<(MipsLo tglobaltlsaddr:$in),
-                (DADDiu ZERO_64, tglobaltlsaddr:$in)>;
-  def : MipsPat<(MipsLo texternalsym:$in), (DADDiu ZERO_64, texternalsym:$in)>;
+def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi64 tglobaladdr:$in)>;
+def : MipsPat<(MipsGotHi texternalsym:$in), (LUi64 texternalsym:$in)>;
 
-  def : MipsPat<(add GPR64:$hi, (MipsLo tglobaladdr:$lo)),
-                (DADDiu GPR64:$hi, tglobaladdr:$lo)>;
-  def : MipsPat<(add GPR64:$hi, (MipsLo tblockaddress:$lo)),
-                (DADDiu GPR64:$hi, tblockaddress:$lo)>;
-  def : MipsPat<(add GPR64:$hi, (MipsLo tjumptable:$lo)),
-                (DADDiu GPR64:$hi, tjumptable:$lo)>;
-  def : MipsPat<(add GPR64:$hi, (MipsLo tconstpool:$lo)),
-                (DADDiu GPR64:$hi, tconstpool:$lo)>;
-  def : MipsPat<(add GPR64:$hi, (MipsLo tglobaltlsaddr:$lo)),
-                (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>;
+multiclass MipsHighestHigherHiLoRelocs<Instruction Lui, Instruction Daddiu> {
+  def : MipsPat<(MipsJmpLink (i64 texternalsym:$dst)),
+                (JAL texternalsym:$dst)>;
+  def : MipsPat<(MipsHighest (i64 tglobaladdr:$in)),
+                (Lui tglobaladdr:$in)>;
+  def : MipsPat<(MipsHighest (i64 tblockaddress:$in)),
+                (Lui tblockaddress:$in)>;
+  def : MipsPat<(MipsHighest (i64 tjumptable:$in)),
+                (Lui tjumptable:$in)>;
+  def : MipsPat<(MipsHighest (i64 tconstpool:$in)),
+                (Lui tconstpool:$in)>;
+  def : MipsPat<(MipsHighest (i64 tglobaltlsaddr:$in)),
+                (Lui tglobaltlsaddr:$in)>;
+  def : MipsPat<(MipsHighest (i64 texternalsym:$in)),
+                (Lui texternalsym:$in)>;
 
-  def : WrapperPat<tglobaladdr, DADDiu, GPR64>;
-  def : WrapperPat<tconstpool, DADDiu, GPR64>;
-  def : WrapperPat<texternalsym, DADDiu, GPR64>;
-  def : WrapperPat<tblockaddress, DADDiu, GPR64>;
-  def : WrapperPat<tjumptable, DADDiu, GPR64>;
-  def : WrapperPat<tglobaltlsaddr, DADDiu, GPR64>;
+  def : MipsPat<(MipsHigher (i64 tglobaladdr:$in)),
+                (Daddiu ZERO_64, tglobaladdr:$in)>;
+  def : MipsPat<(MipsHigher (i64 tblockaddress:$in)),
+                (Daddiu ZERO_64, tblockaddress:$in)>;
+  def : MipsPat<(MipsHigher (i64 tjumptable:$in)),
+                (Daddiu ZERO_64, tjumptable:$in)>;
+  def : MipsPat<(MipsHigher (i64 tconstpool:$in)),
+                (Daddiu ZERO_64, tconstpool:$in)>;
+  def : MipsPat<(MipsHigher (i64 tglobaltlsaddr:$in)),
+                (Daddiu ZERO_64, tglobaltlsaddr:$in)>;
+  def : MipsPat<(MipsHigher (i64 texternalsym:$in)),
+                (Daddiu ZERO_64, texternalsym:$in)>;
+
+  def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tglobaladdr:$lo))),
+                (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tblockaddress:$lo))),
+                (Daddiu GPR64:$hi, tblockaddress:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tjumptable:$lo))),
+                (Daddiu GPR64:$hi, tjumptable:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tconstpool:$lo))),
+                (Daddiu GPR64:$hi, tconstpool:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tglobaltlsaddr:$lo))),
+                (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>;
+
+  def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaladdr:$lo))),
+                (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tblockaddress:$lo))),
+                (Daddiu GPR64:$hi, tblockaddress:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tjumptable:$lo))),
+                (Daddiu GPR64:$hi, tjumptable:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tconstpool:$lo))),
+                (Daddiu GPR64:$hi, tconstpool:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaltlsaddr:$lo))),
+                (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>;
+
+  def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaladdr:$lo))),
+                (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tblockaddress:$lo))),
+                (Daddiu GPR64:$hi, tblockaddress:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tjumptable:$lo))),
+                (Daddiu GPR64:$hi, tjumptable:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tconstpool:$lo))),
+                (Daddiu GPR64:$hi, tconstpool:$lo)>;
+  def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaltlsaddr:$lo))),
+                (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>;
+
 }
 
+// highest/higher/hi/lo relocs
+let AdditionalPredicates = [NotInMicroMips] in
+defm : MipsHighestHigherHiLoRelocs<LUi64, DADDiu>, SYM_64;
+
+def : WrapperPat<tglobaladdr, DADDiu, GPR64>;
+def : WrapperPat<tconstpool, DADDiu, GPR64>;
+def : WrapperPat<texternalsym, DADDiu, GPR64>;
+def : WrapperPat<tblockaddress, DADDiu, GPR64>;
+def : WrapperPat<tjumptable, DADDiu, GPR64>;
+def : WrapperPat<tglobaltlsaddr, DADDiu, GPR64>;
+
+
 defm : BrcondPats<GPR64, BEQ64, BEQ, BNE64, SLT64, SLTu64, SLTi64, SLTiu64,
                   ZERO_64>;
 def : MipsPat<(brcond (i32 (setlt i64:$lhs, 1)), bb:$dst),
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 04d6529..04c5d96 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -574,6 +574,8 @@
   case MipsII::MO_GOT:      O << "%got(";    break;
   case MipsII::MO_ABS_HI:   O << "%hi(";     break;
   case MipsII::MO_ABS_LO:   O << "%lo(";     break;
+  case MipsII::MO_HIGHER:   O << "%higher("; break;
+  case MipsII::MO_HIGHEST:  O << "%highest(("; break;
   case MipsII::MO_TLSGD:    O << "%tlsgd(";  break;
   case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
   case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
@@ -698,7 +700,7 @@
     //        Ideally it should test for properties of the ABI and not the ABI
     //        itself.
     //        For the moment, I'm only correcting enough to make MIPS-IV work.
-    if (!isPositionIndependent() && !ABI.IsN64())
+    if (!isPositionIndependent() && STI.hasSym32())
       TS.emitDirectiveOptionPic0();
   }
 
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 9c511bd..f0f2424 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -112,8 +112,11 @@
   case MipsISD::FIRST_NUMBER:      break;
   case MipsISD::JmpLink:           return "MipsISD::JmpLink";
   case MipsISD::TailCall:          return "MipsISD::TailCall";
+  case MipsISD::Highest:           return "MipsISD::Highest";
+  case MipsISD::Higher:            return "MipsISD::Higher";
   case MipsISD::Hi:                return "MipsISD::Hi";
   case MipsISD::Lo:                return "MipsISD::Lo";
+  case MipsISD::GotHi:             return "MipsISD::GotHi";
   case MipsISD::GPRel:             return "MipsISD::GPRel";
   case MipsISD::ThreadPointer:     return "MipsISD::ThreadPointer";
   case MipsISD::Ret:               return "MipsISD::Ret";
@@ -1733,7 +1736,7 @@
   GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
   const GlobalValue *GV = N->getGlobal();
 
-  if (!isPositionIndependent() && !ABI.IsN64()) {
+  if (!isPositionIndependent()) {
     const MipsTargetObjectFile *TLOF =
         static_cast<const MipsTargetObjectFile *>(
             getTargetMachine().getObjFileLowering());
@@ -1742,8 +1745,10 @@
       // %gp_rel relocation
       return getAddrGPRel(N, SDLoc(N), Ty, DAG);
 
-    // %hi/%lo relocation
-    return getAddrNonPIC(N, SDLoc(N), Ty, DAG);
+                                 // %hi/%lo relocation
+    return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
+                                 // %highest/%higher/%hi/%lo relocation
+                                 : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
   }
 
   // Every other architecture would use shouldAssumeDSOLocal in here, but
@@ -1777,8 +1782,9 @@
   BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
   EVT Ty = Op.getValueType();
 
-  if (!isPositionIndependent() && !ABI.IsN64())
-    return getAddrNonPIC(N, SDLoc(N), Ty, DAG);
+  if (!isPositionIndependent())
+    return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
+                                : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
 
   return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64());
 }
@@ -1870,8 +1876,9 @@
   JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
   EVT Ty = Op.getValueType();
 
-  if (!isPositionIndependent() && !ABI.IsN64())
-    return getAddrNonPIC(N, SDLoc(N), Ty, DAG);
+  if (!isPositionIndependent())
+    return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
+                                : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
 
   return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64());
 }
@@ -1882,7 +1889,7 @@
   ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
   EVT Ty = Op.getValueType();
 
-  if (!isPositionIndependent() && !ABI.IsN64()) {
+  if (!isPositionIndependent()) {
     const MipsTargetObjectFile *TLOF =
         static_cast<const MipsTargetObjectFile *>(
             getTargetMachine().getObjFileLowering());
@@ -1892,10 +1899,11 @@
       // %gp_rel relocation
       return getAddrGPRel(N, SDLoc(N), Ty, DAG);
 
-    return getAddrNonPIC(N, SDLoc(N), Ty, DAG);
+    return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
+                                : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
   }
 
-  return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64());
+ return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64());
 }
 
 SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const {
@@ -2796,14 +2804,13 @@
   // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
   // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
   // node so that legalize doesn't hack it.
-  bool IsPICCall = (ABI.IsN64() || IsPIC); // true if calls are translated to
-                                           // jalr $25
+
   SDValue CalleeLo;
   EVT Ty = Callee.getValueType();
   bool GlobalOrExternal = false, IsCallReloc = false;
 
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
-    if (IsPICCall) {
+    if (IsPIC) {
       const GlobalValue *Val = G->getGlobal();
       InternalLinkage = Val->hasInternalLinkage();
 
@@ -2828,7 +2835,7 @@
   else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
     const char *Sym = S->getSymbol();
 
-    if (!ABI.IsN64() && !IsPIC) // !N64 && static
+    if (!IsPIC) // static
       Callee = DAG.getTargetExternalSymbol(
           Sym, getPointerTy(DAG.getDataLayout()), MipsII::MO_NO_FLAG);
     else if (LargeGOT) {
@@ -2836,7 +2843,7 @@
                                      MipsII::MO_CALL_LO16, Chain,
                                      FuncInfo->callPtrInfo(Sym));
       IsCallReloc = true;
-    } else { // N64 || PIC
+    } else { // PIC
       Callee = getAddrGlobal(S, DL, Ty, DAG, MipsII::MO_GOT_CALL, Chain,
                              FuncInfo->callPtrInfo(Sym));
       IsCallReloc = true;
@@ -2848,7 +2855,7 @@
   SmallVector<SDValue, 8> Ops(1, Chain);
   SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
 
-  getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage,
+  getOpndList(Ops, RegsToPass, IsPIC, GlobalOrExternal, InternalLinkage,
               IsCallReloc, CLI, Callee, Chain);
 
   if (IsTailCall) {
@@ -3683,7 +3690,9 @@
 }
 
 unsigned MipsTargetLowering::getJumpTableEncoding() const {
-  if (ABI.IsN64())
+
+  // FIXME: For space reasons this should be: EK_GPRel32BlockAddress.
+  if (ABI.IsN64() && isPositionIndependent())
     return MachineJumpTableInfo::EK_GPRel64BlockAddress;
 
   return TargetLowering::getJumpTableEncoding();
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index cddf090..abc34be 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -37,14 +37,23 @@
       // Tail call
       TailCall,
 
-      // Get the Higher 16 bits from a 32-bit immediate
+      // Get the Highest (63-48) 16 bits from a 64-bit immediate
+      Highest,
+
+      // Get the Higher (47-32) 16 bits from a 64-bit immediate
+      Higher,
+
+      // Get the High 16 bits from a 32/64-bit immediate
       // No relation with Mips Hi register
       Hi,
 
-      // Get the Lower 16 bits from a 32-bit immediate
+      // Get the Lower 16 bits from a 32/64-bit immediate
       // No relation with Mips Lo register
       Lo,
 
+      // Get the High 16 bits from a 32 bit immediate for accessing the GOT.
+      GotHi,
+
       // Handle gp_rel (small data/bss sections) relocation.
       GPRel,
 
@@ -297,7 +306,7 @@
     }
 
     bool isJumpTableRelative() const override {
-      return getTargetMachine().isPositionIndependent() || ABI.IsN64();
+      return getTargetMachine().isPositionIndependent();
     }
 
   protected:
@@ -344,8 +353,8 @@
                                   SelectionDAG &DAG, unsigned HiFlag,
                                   unsigned LoFlag, SDValue Chain,
                                   const MachinePointerInfo &PtrInfo) const {
-      SDValue Hi =
-          DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(N, Ty, DAG, HiFlag));
+      SDValue Hi = DAG.getNode(MipsISD::GotHi, DL, Ty,
+                               getTargetNode(N, Ty, DAG, HiFlag));
       Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty));
       SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
                                     getTargetNode(N, Ty, DAG, LoFlag));
@@ -356,6 +365,8 @@
     // computing a symbol's address in non-PIC mode:
     //
     // (add %hi(sym), %lo(sym))
+    //
+    // This method covers O32, N32 and N64 in sym32 mode.
     template <class NodeTy>
     SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty,
                           SelectionDAG &DAG) const {
@@ -364,7 +375,37 @@
       return DAG.getNode(ISD::ADD, DL, Ty,
                          DAG.getNode(MipsISD::Hi, DL, Ty, Hi),
                          DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
-    }
+   }
+
+   // This method creates the following nodes, which are necessary for
+   // computing a symbol's address in non-PIC mode for N64.
+   //
+   // (add (shl (add (shl (add %highest(sym), %higher(sim)), 16), %high(sym)),
+   //            16), %lo(%sym))
+   //
+   // FIXME: This method is not efficent for (micro)MIPS64R6.
+   template <class NodeTy>
+   SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty,
+                          SelectionDAG &DAG) const {
+      SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
+      SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
+
+      SDValue Highest =
+          DAG.getNode(MipsISD::Highest, DL, Ty,
+                      getTargetNode(N, Ty, DAG, MipsII::MO_HIGHEST));
+      SDValue Higher = getTargetNode(N, Ty, DAG, MipsII::MO_HIGHER);
+      SDValue HigherPart =
+          DAG.getNode(ISD::ADD, DL, Ty, Highest,
+                      DAG.getNode(MipsISD::Higher, DL, Ty, Higher));
+      SDValue Cst = DAG.getConstant(16, DL, MVT::i32);
+      SDValue Shift = DAG.getNode(ISD::SHL, DL, Ty, HigherPart, Cst);
+      SDValue Add = DAG.getNode(ISD::ADD, DL, Ty, Shift,
+                                DAG.getNode(MipsISD::Hi, DL, Ty, Hi));
+      SDValue Shift2 = DAG.getNode(ISD::SHL, DL, Ty, Add, Cst);
+
+      return DAG.getNode(ISD::ADD, DL, Ty, Shift2,
+                         DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
+   }
 
     // This method creates the following nodes, which are necessary for
     // computing a symbol's address using gp-relative addressing:
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index 5bc4833..883dac3 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -59,10 +59,20 @@
 // Hi and Lo nodes are used to handle global addresses. Used on
 // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
 // static model. (nothing to do with Mips Registers Hi and Lo)
+
+// Hi is the odd node out, on MIPS64 it can expand to either daddiu when
+// using static relocations with 64 bit symbols, or lui when using 32 bit
+// symbols.
+def MipsHigher : SDNode<"MipsISD::Higher", SDTIntUnaryOp>;
+def MipsHighest : SDNode<"MipsISD::Highest", SDTIntUnaryOp>;
 def MipsHi    : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
 def MipsLo    : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
+
 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
 
+// Hi node for accessing the GOT.
+def MipsGotHi : SDNode<"MipsISD::GotHi", SDTIntUnaryOp>;
+
 // TlsGd node is used to handle General Dynamic TLS
 def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>;
 
@@ -205,6 +215,10 @@
                       AssemblerPredicate<"FeatureCnMips">;
 def NotCnMips    :    Predicate<"!Subtarget->hasCnMips()">,
                       AssemblerPredicate<"!FeatureCnMips">;
+def IsSym32     :     Predicate<"Subtarget->HasSym32()">,
+                      AssemblerPredicate<"FeatureSym32">;
+def IsSym64     :     Predicate<"!Subtarget->HasSym32()">,
+                      AssemblerPredicate<"!FeatureSym32">;
 def RelocNotPIC :     Predicate<"!TM.isPositionIndependent()">;
 def RelocPIC    :     Predicate<"TM.isPositionIndependent()">;
 def NoNaNsFPMath :    Predicate<"TM.Options.NoNaNsFPMath">;
@@ -237,6 +251,14 @@
 class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
 
 //===----------------------------------------------------------------------===//
+// Mips Symbol size adjectives.
+// They are mutally exculsive.
+//===----------------------------------------------------------------------===//
+
+class SYM_32 { list<Predicate> SYMPredicates = [IsSym32]; }
+class SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
+
+//===----------------------------------------------------------------------===//
 // Mips ISA/ASE membership and instruction group membership adjectives.
 // They are mutually exclusive.
 //===----------------------------------------------------------------------===//
@@ -2647,30 +2669,40 @@
 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
               (TAILCALL texternalsym:$dst)>;
 // hi/lo relocs
-def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
-def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
-def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
-def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
-def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
-def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
+multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
+                          Register ZeroReg, RegisterOperand GPROpnd> {
+  def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
+  def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
+  def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
+  def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
+  def : MipsPat<(MipsHi tglobaltlsaddr:$in), (Lui tglobaltlsaddr:$in)>;
+  def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
 
-def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
-def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
-def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
-def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
-def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
-def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
+  def : MipsPat<(MipsLo tglobaladdr:$in), (Addiu ZeroReg, tglobaladdr:$in)>;
+  def : MipsPat<(MipsLo tblockaddress:$in),
+                (Addiu ZeroReg, tblockaddress:$in)>;
+  def : MipsPat<(MipsLo tjumptable:$in), (Addiu ZeroReg, tjumptable:$in)>;
+  def : MipsPat<(MipsLo tconstpool:$in), (Addiu ZeroReg, tconstpool:$in)>;
+  def : MipsPat<(MipsLo tglobaltlsaddr:$in),
+                (Addiu ZeroReg, tglobaltlsaddr:$in)>;
+  def : MipsPat<(MipsLo texternalsym:$in), (Addiu ZeroReg, texternalsym:$in)>;
 
-def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
-              (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
-def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
-              (ADDiu GPR32:$hi, tblockaddress:$lo)>;
-def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
-              (ADDiu GPR32:$hi, tjumptable:$lo)>;
-def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
-              (ADDiu GPR32:$hi, tconstpool:$lo)>;
-def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
-              (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
+  def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
+              (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
+  def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
+              (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
+  def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
+              (Addiu GPROpnd:$hi, tjumptable:$lo)>;
+  def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
+              (Addiu GPROpnd:$hi, tconstpool:$lo)>;
+  def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
+              (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
+}
+
+defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>;
+
+def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
+def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>;
 
 // gp_rel relocs
 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 92d3c00..edec107 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -97,11 +97,13 @@
   // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0".
   if ((MI.getOpcode() == Mips::ADDiu) &&
       (MI.getOperand(1).getReg() == Mips::ZERO) &&
+      (MI.getOperand(2).isImm()) &&
       (MI.getOperand(2).getImm() == 0)) {
     DstReg = MI.getOperand(0).getReg();
     ZeroReg = Mips::ZERO;
   } else if ((MI.getOpcode() == Mips::DADDiu) &&
              (MI.getOperand(1).getReg() == Mips::ZERO_64) &&
+             (MI.getOperand(2).isImm()) &&
              (MI.getOperand(2).getImm() == 0)) {
     DstReg = MI.getOperand(0).getReg();
     ZeroReg = Mips::ZERO_64;
diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp
index 3e7570f..2e346d6 100644
--- a/llvm/lib/Target/Mips/MipsSubtarget.cpp
+++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp
@@ -117,6 +117,9 @@
   if (NoABICalls && TM.isPositionIndependent())
     report_fatal_error("position-independent code requires '-mabicalls'");
 
+  if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32())
+    NoABICalls = true;
+
   // Set UseSmallSection.
   UseSmallSection = GPOpt;
   if (!NoABICalls && GPOpt) {
diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h
index 38d3cee..5f6fc7c 100644
--- a/llvm/lib/Target/Mips/MipsSubtarget.h
+++ b/llvm/lib/Target/Mips/MipsSubtarget.h
@@ -142,6 +142,9 @@
   // UseTCCInDIV -- Enables the use of trapping in the assembler.
   bool UseTCCInDIV;
 
+  // Sym32 -- On Mips64 symbols are 32 bits.
+  bool HasSym32;
+
   // HasEVA -- supports EVA ASE.
   bool HasEVA;
 
@@ -229,6 +232,9 @@
   unsigned getGPRSizeInBytes() const { return isGP64bit() ? 8 : 4; }
   bool isPTR64bit() const { return IsPTR64bit; }
   bool isPTR32bit() const { return !IsPTR64bit; }
+  bool hasSym32() const {
+    return (HasSym32 && isABI_N64()) || isABI_N32() || isABI_O32();
+  }
   bool isSingleFloat() const { return IsSingleFloat; }
   bool hasVFPU() const { return HasVFPU; }
   bool inMips16Mode() const { return InMips16Mode; }
diff --git a/llvm/test/CodeGen/Mips/2009-11-16-CstPoolLoad.ll b/llvm/test/CodeGen/Mips/2009-11-16-CstPoolLoad.ll
index c0229c6..d3cc03f 100644
--- a/llvm/test/CodeGen/Mips/2009-11-16-CstPoolLoad.ll
+++ b/llvm/test/CodeGen/Mips/2009-11-16-CstPoolLoad.ll
@@ -17,7 +17,7 @@
 ; STATIC-N32: lwc1 $f0, %lo(.LCPI0_0)($[[R0]])
 ; PIC-N64: ld  $[[R0:[0-9]+]], %got_page(.LCPI0_0)
 ; PIC-N64: lwc1 $f0, %got_ofst(.LCPI0_0)($[[R0]])
-; STATIC-N64: ld  $[[R0:[0-9]+]], %got_page(.LCPI0_0)
-; STATIC-N64: lwc1 $f0, %got_ofst(.LCPI0_0)($[[R0]])
+; STATIC-N64: lui  $[[R0:[0-9]+]], %highest(.LCPI0_0)
+; STATIC-N64: lwc1 $f0, %lo(.LCPI0_0)($[[R0]])
   ret float 0x400B333340000000
 }
diff --git a/llvm/test/CodeGen/Mips/2010-07-20-Switch.ll b/llvm/test/CodeGen/Mips/2010-07-20-Switch.ll
index 5f0a0a5..087a34f 100644
--- a/llvm/test/CodeGen/Mips/2010-07-20-Switch.ll
+++ b/llvm/test/CodeGen/Mips/2010-07-20-Switch.ll
@@ -3,13 +3,13 @@
 ; RUN: llc < %s -march=mips -relocation-model=pic | \
 ; RUN: FileCheck %s -check-prefix=PIC-O32 
 ; RUN: llc < %s -march=mips64 -relocation-model=pic -mcpu=mips4 | \
-; RUN:     FileCheck %s -check-prefix=N64
+; RUN:     FileCheck %s -check-prefix=PIC-N64
 ; RUN: llc < %s -march=mips64 -relocation-model=static -mcpu=mips4 | \
-; RUN:     FileCheck %s -check-prefix=N64
+; RUN:     FileCheck %s -check-prefix=STATIC-N64
 ; RUN: llc < %s -march=mips64 -relocation-model=pic -mcpu=mips64 | \
-; RUN:     FileCheck %s -check-prefix=N64
+; RUN:     FileCheck %s -check-prefix=PIC-N64
 ; RUN: llc < %s -march=mips64 -relocation-model=static -mcpu=mips64 | \
-; RUN:     FileCheck %s -check-prefix=N64
+; RUN:     FileCheck %s -check-prefix=STATIC-N64
 
 define i32 @main() nounwind readnone {
 entry:
@@ -20,18 +20,29 @@
 ; STATIC-O32: lui $[[R1:[0-9]+]], %hi($JTI0_0)
 ; STATIC-O32: addu $[[R2:[0-9]+]], $[[R0]], $[[R1]]
 ; STATIC-O32: lw $[[R3:[0-9]+]], %lo($JTI0_0)($[[R2]])
+
 ; PIC-O32: sll $[[R0:[0-9]+]], ${{[0-9]+}}, 2
 ; PIC-O32: lw $[[R1:[0-9]+]], %got($JTI0_0)
 ; PIC-O32: addu $[[R2:[0-9]+]], $[[R0]], $[[R1]]
 ; PIC-O32: lw $[[R4:[0-9]+]], %lo($JTI0_0)($[[R2]])
 ; PIC-O32: addu $[[R5:[0-9]+]], $[[R4:[0-9]+]]
 ; PIC-O32: jr  $[[R5]]
-; N64: dsll $[[R0:[0-9]+]], ${{[0-9]+}}, 3
-; N64: ld $[[R1:[0-9]+]], %got_page(.LJTI0_0)
-; N64: daddu $[[R2:[0-9]+]], $[[R0:[0-9]+]], $[[R1]]
-; N64: ld $[[R4:[0-9]+]], %got_ofst(.LJTI0_0)($[[R2]])
-; N64: daddu $[[R5:[0-9]+]], $[[R4:[0-9]+]]
-; N64: jr  $[[R5]]
+
+; STATIC-N64: mflo $[[R0:[0-9]]]
+; STATIC-N64: lui $[[R1:[0-9]]], %highest(.LJTI0_0)
+; STATIC-N64: daddiu $[[R2:[0-9]]], $[[R1]], %higher(.LJTI0_0)
+; STATIC-N64: dsll $[[R3:[0-9]]], $[[R2]], 16
+; STATIC-N64: daddiu $[[R4:[0-9]]], $[[R3]], %hi(.LJTI0_0)
+; STATIC-N64: dsll $[[R5:[0-9]]], $[[R4]], 16
+; STATIC-N64: daddu $[[R6:[0-9]]], $[[R0]], $[[R4]]
+; STATIC-N64: ld ${{[0-9]+}}, %lo(.LJTI0_0)($[[R6]])
+
+; PIC-N64: dsll $[[R0:[0-9]+]], ${{[0-9]+}}, 32
+; PIC-N64: ld $[[R1:[0-9]+]], %got_page(.LJTI0_0)
+; PIC-N64: daddu $[[R2:[0-9]+]], $[[R0:[0-9]+]], $[[R1]]
+; PIC-N64: ld $[[R4:[0-9]+]], %got_ofst(.LJTI0_0)($[[R2]])
+; PIC-N64: daddu $[[R5:[0-9]+]], $[[R4:[0-9]+]]
+; PIC-N64: jr  $[[R5]]
   switch i32 %0, label %bb4 [
     i32 0, label %bb5
     i32 1, label %bb1
@@ -65,12 +76,18 @@
 ; PIC-O32: $JTI0_0:
 ; PIC-O32: .gpword
 ; PIC-O32: .gpword
-; PIC-O32: .gpword 
-; PIC-O32: .gpword 
-; N64: .p2align  3
-; N64: .LJTI0_0:
-; N64: .gpdword
-; N64: .gpdword
-; N64: .gpdword 
-; N64: .gpdword 
+; PIC-O32: .gpword
+; PIC-O32: .gpword
+; STATIC-N64: .p2align  3
+; STATIC-N64: LJTI0_0:
+; STATIC-N64: .8byte
+; STATIC-N64: .8byte
+; STATIC-N64: .8byte
+; STATIC-N64: .8byte
+;; PIC-N64: .p2align  3
+; PIC-N64: .LJTI0_0:
+; PIC-N64: .gpdword
+; PIC-N64: .gpdword
+; PIC-N64: .gpdword
+; PIC-N64: .gpdword
 
diff --git a/llvm/test/CodeGen/Mips/abicalls.ll b/llvm/test/CodeGen/Mips/abicalls.ll
index 26bbab4..2de5397 100644
--- a/llvm/test/CodeGen/Mips/abicalls.ll
+++ b/llvm/test/CodeGen/Mips/abicalls.ll
@@ -1,7 +1,12 @@
 ; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=static %s -o - | FileCheck -check-prefixes=ABICALLS,STATIC %s
 ; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=pic %s -o - | FileCheck -check-prefixes=ABICALLS,PIC %s
-; RUN: llc -filetype=asm -mtriple mips64el-unknown-linux -mcpu=mips4 -relocation-model=static %s -o - | FileCheck -check-prefixes=ABICALLS,PIC %s
-; RUN: llc -filetype=asm -mtriple mips64el-unknown-linux -mcpu=mips64 -relocation-model=static %s -o - | FileCheck -check-prefixes=ABICALLS,PIC %s
+; RUN: llc -filetype=asm -mtriple mips64el-unknown-linux -mcpu=mips4 -relocation-model=static %s -o - | FileCheck -check-prefixes=N64-STATIC %s
+; RUN: llc -filetype=asm -mtriple mips64el-unknown-linux -mcpu=mips64 -relocation-model=static %s -o - | FileCheck -check-prefixes=N64-STATIC %s
+; RUN: llc -filetype=asm -mtriple mips64el-unknown-linux -mcpu=mips4 -relocation-model=static -mattr=+sym32 %s -o - | FileCheck -check-prefixes=ABICALLS,STATIC %s
+; RUN: llc -filetype=asm -mtriple mips64el-unknown-linux -mcpu=mips64 -relocation-model=static -mattr=+sym32 %s -o - | FileCheck -check-prefixes=ABICALLS,STATIC %s
+; RUN: llc -filetype=asm -mtriple mips64el-unknown-linux -mcpu=mips4 -relocation-model=pic %s -o - | FileCheck -check-prefixes=ABICALLS %s
+; RUN: llc -filetype=asm -mtriple mips64el-unknown-linux -mcpu=mips64 -relocation-model=pic %s -o - | FileCheck -check-prefixes=ABICALLS %s
+
 
 ; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 -mattr noabicalls -relocation-model=static %s -o - | FileCheck -implicit-check-not='.abicalls' -implicit-check-not='pic0' %s
 
@@ -9,3 +14,6 @@
 
 ; STATIC: pic0
 ; PIC-NOT: pic0
+
+; N64-STATIC-NOT: .abicalls
+; N64-STATIC-NOT: .pic0
diff --git a/llvm/test/CodeGen/Mips/blockaddr.ll b/llvm/test/CodeGen/Mips/blockaddr.ll
index 9bc9a30..80b24bc 100644
--- a/llvm/test/CodeGen/Mips/blockaddr.ll
+++ b/llvm/test/CodeGen/Mips/blockaddr.ll
@@ -34,10 +34,14 @@
 ; PIC-N64: daddiu ${{[0-9]+}}, $[[R0]], %got_ofst(.Ltmp[[T0]])
 ; PIC-N64: ld  $[[R1:[0-9]+]], %got_page(.Ltmp[[T1:[0-9]+]])
 ; PIC-N64: daddiu ${{[0-9]+}}, $[[R1]], %got_ofst(.Ltmp[[T1]])
-; STATIC-N64: ld  $[[R2:[0-9]+]], %got_page(.Ltmp[[T2:[0-9]+]])
-; STATIC-N64: daddiu ${{[0-9]+}}, $[[R2]], %got_ofst(.Ltmp[[T2]])
-; STATIC-N64: ld  $[[R3:[0-9]+]], %got_page(.Ltmp[[T3:[0-9]+]])
-; STATIC-N64: daddiu ${{[0-9]+}}, $[[R3]], %got_ofst(.Ltmp[[T3]])
+
+; STATIC-N64: lui $[[R0:[0-9]]], %highest(.Ltmp[[L0:[0-9]]])
+; STATIC-N64: daddiu $[[R1:[0-9]]], $[[R0]], %higher(.Ltmp[[L0]])
+; STATIC-N64: dsll $[[R2:[0-9]]], $[[R1]], 16
+; STATIC-N64: daddiu $[[R3:[0-9]]], $[[R2]], %hi(.Ltmp[[L0]])
+; STATIC-N64: dsll $[[R4:[0-9]]], $[[R3]], 16
+; STATIC-N64: daddiu $[[R5:[0-9]]], $[[R4]], %lo(.Ltmp[[L0]])
+
 ; STATIC-MIPS16-1: .ent	f
 ; STATIC-MIPS16-2: .ent	f
 ; STATIC-MIPS16-1: li  $[[R1_16:[0-9]+]], %hi($tmp[[TI_16:[0-9]+]])
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-float.ll b/llvm/test/CodeGen/Mips/cconv/arguments-float.ll
index a76cf62..7d32992 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-float.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-float.ll
@@ -49,7 +49,7 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(doubles)(
+; SYM64-DAG:           daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(doubles)
 
 ; The first four arguments are the same in O32/N32/N64.
 ; The first argument is floating point but soft-float is enabled so floating
@@ -132,7 +132,7 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(floats)(
+; SYM64-DAG:           daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(floats)
 
 ; The first four arguments are the same in O32/N32/N64.
 ; The first argument is floating point but soft-float is enabled so floating
@@ -180,10 +180,10 @@
 ; ALL-LABEL: double_arg2:
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
-; SYM32-DAG:           addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
-; SYM64-DAG:           ld [[R1:\$[0-9]]], %got_disp(bytes)(
-; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(doubles)(
+; SYM32-DAG:           addiu  [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
+; SYM64-DAG:           daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(bytes)
+; SYM32-DAG:           addiu  [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
+; SYM64-DAG:           daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(doubles)
 
 ; The first four arguments are the same in O32/N32/N64.
 ; The first argument isn't floating point so floating point registers are not
@@ -207,10 +207,11 @@
 ; ALL-LABEL: float_arg2:
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
-; SYM32-DAG:           addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
-; SYM64-DAG:           ld [[R1:\$[0-9]]], %got_disp(bytes)(
-; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(floats)(
+; SYM32-DAG:         addiu  [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
+; SYM64-DAG:         daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(bytes)
+; SYM32-DAG:         addiu  [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
+; SYM64-DAG:         daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(floats)
+
 
 ; The first four arguments are the same in O32/N32/N64.
 ; The first argument isn't floating point so floating point registers are not
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-fp128.ll b/llvm/test/CodeGen/Mips/cconv/arguments-fp128.ll
index 70df976..086ba9b 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-fp128.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-fp128.ll
@@ -30,7 +30,7 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(ldoubles)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(ldoubles)(
+; SYM64-DAG:           daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(ldoubles)
 
 ; The first four arguments are the same in N32/N64.
 ; The first argument is floating point but soft-float is enabled so floating
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-hard-float-varargs.ll b/llvm/test/CodeGen/Mips/cconv/arguments-hard-float-varargs.ll
index 5f7a865..c59ec02 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-hard-float-varargs.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-hard-float-varargs.ll
@@ -42,7 +42,7 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:         addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
-; SYM64-DAG:         ld [[R2:\$[0-9]]], %got_disp(doubles)(
+; SYM64-DAG:         daddiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
 
 ; O32 forbids using floating point registers for the non-variable portion.
 ; N32/N64 allow it.
@@ -107,7 +107,7 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:         addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
-; SYM64-DAG:         ld [[R2:\$[0-9]]], %got_disp(floats)(
+; SYM64-DAG:         daddiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
 
 ; The first four arguments are the same in O32/N32/N64.
 ; The non-variable portion should be unaffected.
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-hard-float.ll b/llvm/test/CodeGen/Mips/cconv/arguments-hard-float.ll
index 2e753d0..24bb95c 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-hard-float.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-hard-float.ll
@@ -49,7 +49,7 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(doubles)(
+; SYM64-DAG:           daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(doubles)
 
 ; The first argument is floating point so floating point registers are used.
 ; The first argument is the same for O32/N32/N64 but the second argument differs
@@ -111,8 +111,8 @@
 ; ALL-LABEL: float_args:
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
-; SYM32-DAG:           addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
-; SYM64-DAG:           ld [[R1:\$[0-9]]], %got_disp(floats)(
+; SYM32-DAG:           addiu  [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
+; SYM64-DAG:           daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(floats)
 
 ; The first argument is floating point so floating point registers are used.
 ; The first argument is the same for O32/N32/N64 but the second argument differs
@@ -164,9 +164,9 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
-; SYM64-DAG:           ld [[R1:\$[0-9]]], %got_disp(bytes)(
+; SYM64-DAG:           daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(bytes)
 ; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(doubles)(
+; SYM64-DAG:           daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(doubles)
 
 ; The first argument is the same in O32/N32/N64.
 ; ALL-DAG:           sb $4, 1([[R1]])
@@ -195,9 +195,9 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
-; SYM64-DAG:           ld [[R1:\$[0-9]]], %got_disp(bytes)(
+; SYM64-DAG:           daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(bytes)
 ; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(floats)(
+; SYM64-DAG:           daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(floats)
 
 ; The first argument is the same in O32/N32/N64.
 ; ALL-DAG:           sb $4, 1([[R1]])
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-hard-fp128.ll b/llvm/test/CodeGen/Mips/cconv/arguments-hard-fp128.ll
index 1a3b664..6c601e9 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-hard-fp128.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-hard-fp128.ll
@@ -30,7 +30,7 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(ldoubles)
-; SYM64-DAG:           ld [[R2:\$[0-9]]], %got_disp(ldoubles)(
+; SYM64-DAG:           daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(ldoubles)
 
 ; The first four arguments are the same in N32/N64.
 ; ALL-DAG:           sdc1 $f12, 16([[R2]])
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-struct.ll b/llvm/test/CodeGen/Mips/cconv/arguments-struct.ll
index 44ea7c0..6288b5d 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-struct.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-struct.ll
@@ -28,7 +28,7 @@
 ; SYM32-DAG:   lui   [[PTR_HI:\$[0-9]+]], %hi(bytes)
 ; SYM32-DAG:   addiu [[PTR:\$[0-9]+]], [[PTR_HI]], %lo(bytes)
 
-; SYM64-DAG:   ld    [[PTR:\$[0-9]+]], %got_disp(bytes)(
+; SYM64-DAG:   addiu [[PTR:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
 
 ; O32-BE-DAG:  srl [[ARG:\$[0-9]+]], $4, 24
 ; O32-BE-DAG:  sb  [[ARG]], 1([[PTR]])
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-byte.ll b/llvm/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-byte.ll
index ba3aeb5..b41b5b7 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-byte.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-byte.ll
@@ -259,7 +259,9 @@
   call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i64 inreg %3)
   ret void
  ; CHECK-LABEL: smallStruct_8b:
+ ; Check that the structure is not shifted before the pointer to str is loaded.
  ; CHECK-NOT: dsll
+ ; CHECK: lui
 }
 
 define void @smallStruct_9b(%struct.SmallStruct_9b* %ss) #0 {
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-combinations.ll b/llvm/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-combinations.ll
index 74d3d85..8a20f5e 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-combinations.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-combinations.ll
@@ -96,6 +96,7 @@
   ret void
  ; CHECK-LABEL: smallStruct_1b1i:
  ; CHECK-NOT: dsll
+ ; CHECK: lui
 }
 
 define void @smallStruct_1b1s1b(%struct.SmallStruct_1b1s1b* %ss) #0 {
@@ -129,6 +130,7 @@
   ret void
  ; CHECK-LABEL: smallStruct_1s1i:
  ; CHECK-NOT: dsll
+ ; CHECK: lui
 }
 
 define void @smallStruct_3b1s(%struct.SmallStruct_3b1s* %ss) #0 {
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll b/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll
index 9c20b88..785188b 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll
@@ -85,7 +85,7 @@
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
 
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(hwords)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
 
 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
 
@@ -203,7 +203,7 @@
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
 
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(words)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
 
 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
 
@@ -324,7 +324,7 @@
 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
 
@@ -448,7 +448,7 @@
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
 
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(hwords)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
 
 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
 
@@ -566,7 +566,7 @@
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
 
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(words)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
 
 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
 
@@ -687,7 +687,7 @@
 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
 
@@ -810,7 +810,7 @@
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
 
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(hwords)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
 
 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
 
@@ -927,7 +927,7 @@
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
 
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(words)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
 
 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
 
@@ -1047,7 +1047,7 @@
 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
 
 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
-; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
+; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
 
diff --git a/llvm/test/CodeGen/Mips/cconv/arguments.ll b/llvm/test/CodeGen/Mips/cconv/arguments.ll
index 7af4e55..2466d59 100644
--- a/llvm/test/CodeGen/Mips/cconv/arguments.ll
+++ b/llvm/test/CodeGen/Mips/cconv/arguments.ll
@@ -55,7 +55,7 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
-; SYM64-DAG:           ld [[R1:\$[0-9]+]], %got_disp(bytes)(
+; SYM64-DAG:           daddiu [[R1:\$[0-9]+]], ${{[0-9]+}},  %lo(bytes)
 
 ; The first four arguments are the same in O32/N32/N64
 ; ALL-DAG:           sb $4, 1([[R1]])
@@ -120,9 +120,9 @@
 ; We won't test the way the global address is calculated in this test. This is
 ; just to get the register number for the other checks.
 ; SYM32-DAG:           addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
-; SYM64-DAG:           ld [[R1:\$[0-9]+]], %got_disp(bytes)(
+; SYM64-DAG:           daddiu [[R1:\$[0-9]+]], ${{[0-9]+}},  %lo(bytes)
 ; SYM32-DAG:           addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
-; SYM64-DAG:           ld [[R2:\$[0-9]+]], %got_disp(dwords)(
+; SYM64-DAG:           daddiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
 
 ; The first argument is the same in O32/N32/N64.
 ; ALL-DAG:           sb $4, 1([[R1]])
diff --git a/llvm/test/CodeGen/Mips/cconv/return-float.ll b/llvm/test/CodeGen/Mips/cconv/return-float.ll
index b9a6d6c..dd457fc 100644
--- a/llvm/test/CodeGen/Mips/cconv/return-float.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return-float.ll
@@ -30,8 +30,7 @@
 ; O32-DAG:           lw $2, %lo(float)([[R1]])
 ; N32-DAG:           lui [[R1:\$[0-9]+]], %hi(float)
 ; N32-DAG:           lw $2, %lo(float)([[R1]])
-; N64-DAG:           ld  [[R1:\$[0-9]+]], %got_disp(float)(
-; N64-DAG:           lw $2, 0([[R1]])
+; N64-DAG:           lw $2, %lo(float)([[R1:\$[0-9+]]])
 
 define double @retdouble() nounwind {
 entry:
@@ -44,5 +43,4 @@
 ; O32-DAG:           addiu [[R2:\$[0-9]+]], [[R1]], %lo(double)
 ; O32-DAG:           lw $3, 4([[R2]])
 ; N32-DAG:           ld $2, %lo(double)([[R1:\$[0-9]+]])
-; N64-DAG:           ld  [[R1:\$[0-9]+]], %got_disp(double)(
-; N64-DAG:           ld $2, 0([[R1]])
+; N64-DAG:           ld $2, %lo(double)([[R1:\$[0-9]+]])
diff --git a/llvm/test/CodeGen/Mips/cconv/return-hard-float.ll b/llvm/test/CodeGen/Mips/cconv/return-hard-float.ll
index 768cb6a..44ef65e 100644
--- a/llvm/test/CodeGen/Mips/cconv/return-hard-float.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return-hard-float.ll
@@ -33,8 +33,7 @@
 ; O32-DAG:           lwc1 $f0, %lo(float)([[R1]])
 ; N32-DAG:           lui [[R1:\$[0-9]+]], %hi(float)
 ; N32-DAG:           lwc1 $f0, %lo(float)([[R1]])
-; N64-DAG:           ld  [[R1:\$[0-9]+]], %got_disp(float)(
-; N64-DAG:           lwc1 $f0, 0([[R1]])
+; N64-DAG:           lwc1 $f0, %lo(float)([[R1:\$[0-9+]]])
 
 define double @retdouble() nounwind {
 entry:
@@ -45,8 +44,7 @@
 ; ALL-LABEL: retdouble:
 ; O32-DAG:           ldc1 $f0, %lo(double)([[R1:\$[0-9]+]])
 ; N32-DAG:           ldc1 $f0, %lo(double)([[R1:\$[0-9]+]])
-; N64-DAG:           ld  [[R1:\$[0-9]+]], %got_disp(double)(
-; N64-DAG:           ldc1 $f0, 0([[R1]])
+; N64-DAG:           ldc1 $f0, %lo(double)([[R1:\$[0-9]+]])
 
 define { double, double } @retComplexDouble() #0 {
   %retval = alloca { double, double }, align 8
diff --git a/llvm/test/CodeGen/Mips/cconv/return-hard-fp128.ll b/llvm/test/CodeGen/Mips/cconv/return-hard-fp128.ll
index bdbfb80..e527866 100644
--- a/llvm/test/CodeGen/Mips/cconv/return-hard-fp128.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return-hard-fp128.ll
@@ -24,8 +24,8 @@
 ; N32-DAG:           dmtc1 [[R2]], $f0
 ; N32-DAG:           dmtc1 [[R4]], $f2
 
-; N64-DAG:           ld [[R2:\$[0-9]+]], %got_disp(fp128)([[R1:\$[0-9]+]])
-; N64-DAG:           ld [[R3:\$[0-9]+]], 0([[R2]])
+; N64-DAG:           lui [[R2:\$[0-9]+]], %highest(fp128)
+; N64-DAG:           ld [[R3:\$[0-9]+]], %lo(fp128)([[R2]])
 ; N64-DAG:           ld [[R4:\$[0-9]+]], 8([[R2]])
 ; N64-DAG:           dmtc1 [[R3]], $f0
 ; N64-DAG:           dmtc1 [[R4]], $f2
diff --git a/llvm/test/CodeGen/Mips/cconv/return-hard-struct-f128.ll b/llvm/test/CodeGen/Mips/cconv/return-hard-struct-f128.ll
index 9b178e4..492db76 100644
--- a/llvm/test/CodeGen/Mips/cconv/return-hard-struct-f128.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return-hard-struct-f128.ll
@@ -29,8 +29,8 @@
 ; N32-DAG:        ld  [[R4:\$[0-9]+]], 8([[R3]])
 ; N32-DAG:        dmtc1 [[R4]], $f1
 
-; N64-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_fp128)($1)
-; N64-DAG:        ld  [[R2:\$[0-9]+]], 0([[R1]])
+; N64-DAG:        lui  [[R1:\$[0-9]+]], %highest(struct_fp128)
+; N64-DAG:        ld  [[R2:\$[0-9]+]], %lo(struct_fp128)([[R1]])
 ; N64-DAG:        dmtc1 [[R2]], $f0
 ; N64-DAG:        ld  [[R4:\$[0-9]+]], 8([[R1]])
 ; N64-DAG:        dmtc1 [[R4]], $f1
diff --git a/llvm/test/CodeGen/Mips/cconv/return-struct.ll b/llvm/test/CodeGen/Mips/cconv/return-struct.ll
index da20919..0997cfb 100644
--- a/llvm/test/CodeGen/Mips/cconv/return-struct.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return-struct.ll
@@ -37,12 +37,10 @@
 ; N32-BE-DAG:        lb [[R2:\$[0-9]+]], %lo(struct_byte)([[R1]])
 ; N32-BE-DAG:        dsll $2, [[R2]], 56
 
-; N64-LE-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_byte)($1)
-; N64-LE-DAG:        lb $2, 0([[R1]])
+; N64-LE-DAG:        lb $2, %lo(struct_byte)(${{[0-9]+}})
 
-; N64-BE-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_byte)($1)
-; N64-BE-DAG:        lb [[R2:\$[0-9]+]], 0([[R1]])
-; N64-BE-DAG:        dsll $2, [[R2]], 56
+; N64-BE-DAG:        lb [[R1:\$[0-9]+]], %lo(struct_byte)(${{[0-9]+}})
+; N64-BE-DAG:        dsll $2, [[R1]], 56
 
 ; This test is based on the way clang currently lowers {i8,i8} to {i16}.
 ; FIXME: It should probably work for without any lowering too but this doesn't
@@ -75,13 +73,15 @@
 ; N32-BE-DAG:        lh  [[R3:\$[0-9]+]], 8([[SP:\$sp]])
 ; N32-BE-DAG:        dsll $2, [[R3]], 48
 
-; N64-LE-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_2byte)($1)
-; N64-LE-DAG:        lhu [[R2:\$[0-9]+]], 0([[R1]])
+; N64-LE-DAG:        daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %hi(struct_2byte)
+; N64-LE-DAG:        dsll [[R1:\$[0-9]]], $[[R0]], 16
+; N64-LE-DAG:        lhu [[R2:\$[0-9]+]], %lo(struct_2byte)([[R1]])
 ; N64-LE-DAG:        sh  [[R2]], 8([[SP:\$sp]])
 ; N64-LE-DAG:        lh  $2, 8([[SP:\$sp]])
 
-; N64-BE-DAG:        ld  [[R1:\$[0-9]+]], %got_disp(struct_2byte)($1)
-; N64-BE-DAG:        lhu [[R2:\$[0-9]+]], 0([[R1]])
+; N64-BE-DAG:        daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %hi(struct_2byte)
+; N64-BE-DAG:        dsll $[[R1:[0-9]]], $[[R0]], 16
+; N64-BE-DAG:        lhu [[R2:\$[0-9]+]], %lo(struct_2byte)($[[R1]])
 ; N64-BE-DAG:        sh  [[R2]], 8([[SP:\$sp]])
 ; N64-BE-DAG:        lh  [[R3:\$[0-9]+]], 8([[SP:\$sp]])
 ; N64-BE-DAG:        dsll $2, [[R3]], 48
@@ -126,14 +126,14 @@
 ; N32-BE-DAG:        or [[R4:\$[0-9]+]], [[R3]], [[R2]]
 ; N32-BE-DAG:        dsll $2, [[R4]], 16
 
-; N64-LE-DAG:        ld  [[PTR:\$[0-9]+]], %got_disp(struct_3xi16)($1)
+; N64-LE-DAG:        daddiu [[PTR:\$[0-9]+]], [[R0:\$[0-9]+]], %lo(struct_3xi16)
 ; N64-LE-DAG:        lh [[R1:\$[0-9]+]], 4([[PTR]])
-; N64-LE-DAG:        lwu [[R2:\$[0-9]+]], 0([[PTR]])
+; N64-LE-DAG:        lwu [[R2:\$[0-9]+]], %lo(struct_3xi16)([[R0]])
 ; N64-LE-DAG:        dsll [[R3:\$[0-9]+]], [[R1]], 32
 ; N64-LE-DAG:        or $2, [[R2]], [[R3]]
 
-; N64-BE-DAG:        ld  [[PTR:\$[0-9]+]], %got_disp(struct_3xi16)($1)
-; N64-BE-DAG:        lw [[R1:\$[0-9]+]], 0([[PTR]])
+; N64-BE-DAG:        daddiu [[PTR:\$[0-9]+]], [[R0:\$[0-9]+]], %lo(struct_3xi16)
+; N64-BE-DAG:        lw [[R1:\$[0-9]+]], %lo(struct_3xi16)([[R0]])
 ; N64-BE-DAG:        dsll [[R2:\$[0-9]+]], [[R1]], 16
 ; N64-BE-DAG:        lhu [[R3:\$[0-9]+]], 4([[PTR]])
 ; N64-BE-DAG:        or [[R4:\$[0-9]+]], [[R3]], [[R2]]
@@ -161,9 +161,8 @@
 ; N32:            jal memcpy
 
 ; sret pointer is already in $4
-; N64-DAG:        ld $5, %got_disp(struct_128xi16)(
-; N64-DAG:        ld $25, %call16(memcpy)(
-; N64:            jalr $25
+; N64-DAG:        lui ${{[0-9]}}, %highest(struct_128xi16)
+; N64:            jal memcpy
 
 ; Ensure that large structures (>128-bit) are returned indirectly.
 ; This will generate inlined memcpy's anyway so pick the smallest large
@@ -214,13 +213,14 @@
 ; N32-DAG:        sw [[T5]], 20([[RET_PTR]])
 
 ; sret pointer is already in $4
-; N64-DAG:        ld [[PTR:\$[0-9]+]], %got_disp(struct_6xi32)(
-; N64-DAG:        lw [[T0:\$[0-9]+]], 0([[PTR]])
+; N64-DAG:        lui [[PTR_HI:\$[0-9]+]], %highest(struct_6xi32)
+; N64-DAG:        daddiu [[PTR:\$[0-9]+]], [[PTR_HI]], %lo(struct_6xi32)
 ; N64-DAG:        lw [[T1:\$[0-9]+]], 4([[PTR]])
 ; N64-DAG:        lw [[T2:\$[0-9]+]], 8([[PTR]])
 ; N64-DAG:        lw [[T3:\$[0-9]+]], 12([[PTR]])
 ; N64-DAG:        lw [[T4:\$[0-9]+]], 16([[PTR]])
 ; N64-DAG:        lw [[T5:\$[0-9]+]], 20([[PTR]])
+; N64-DAG:        lw [[T0:\$[0-9]+]], %lo(struct_6xi32)([[PTR_HI]])
 ; N64-DAG:        sw [[T0]], 0($4)
 ; N64-DAG:        sw [[T1]], 4($4)
 ; N64-DAG:        sw [[T2]], 8($4)
diff --git a/llvm/test/CodeGen/Mips/cconv/return.ll b/llvm/test/CodeGen/Mips/cconv/return.ll
index 561c94c..c2bbe77 100644
--- a/llvm/test/CodeGen/Mips/cconv/return.ll
+++ b/llvm/test/CodeGen/Mips/cconv/return.ll
@@ -33,8 +33,8 @@
 ; O32-DAG:           lbu $2, %lo(byte)([[R1]])
 ; N32-DAG:           lui [[R1:\$[0-9]+]], %hi(byte)
 ; N32-DAG:           lbu $2, %lo(byte)([[R1]])
-; N64-DAG:           ld  [[R1:\$[0-9]+]], %got_disp(byte)(
-; N64-DAG:           lbu $2, 0([[R1]])
+; N64-DAG:           lui  [[R1:\$[0-9]+]], %highest(byte)
+; N64-DAG:           lbu $2, %lo(byte)([[R1]])
 
 define i32 @reti32() nounwind {
 entry:
@@ -47,8 +47,8 @@
 ; O32-DAG:           lw $2, %lo(word)([[R1]])
 ; N32-DAG:           lui [[R1:\$[0-9]+]], %hi(word)
 ; N32-DAG:           lw $2, %lo(word)([[R1]])
-; N64-DAG:           ld  [[R1:\$[0-9]+]], %got_disp(word)(
-; N64-DAG:           lw $2, 0([[R1]])
+; N64-DAG:           lui [[R1:\$[0-9]+]], %highest(word)
+; N64-DAG:           lw $2, %lo(word)([[R1]])
 
 define i64 @reti64() nounwind {
 entry:
@@ -62,5 +62,5 @@
 ; O32-DAG:           addiu [[R2:\$[0-9]+]], [[R1]], %lo(dword)
 ; O32-DAG:           lw $3, 4([[R2]])
 ; N32-DAG:           ld $2, %lo(dword)([[R1:\$[0-9]+]])
-; N64-DAG:           ld  [[R1:\$[0-9]+]], %got_disp(dword)([[R1:\$[0-9]+]])
-; N64-DAG:           ld $2, 0([[R1]])
+; N64-DAG:           lui  [[R1:\$[0-9]+]], %highest(dword)
+; N64-DAG:           ld $2, %lo(dword)([[R1]])
diff --git a/llvm/test/CodeGen/Mips/cconv/roundl-call.ll b/llvm/test/CodeGen/Mips/cconv/roundl-call.ll
index 8e4d659..0861197 100644
--- a/llvm/test/CodeGen/Mips/cconv/roundl-call.ll
+++ b/llvm/test/CodeGen/Mips/cconv/roundl-call.ll
@@ -5,8 +5,8 @@
 
 ; RUN: llc -march=mips64 -mcpu=mips64 -target-abi=n64 -relocation-model=pic < \
 ; RUN:     %s | FileCheck %s -check-prefixes=ALL,N64,HARD-FLOAT
-; RUN: llc -march=mips64el -mcpu=mips64 -target-abi=n64 -relocation-model=pic < \
-; RUN:     %s | FileCheck %s -check-prefixes=ALL,N64,HARD-FLOAT
+; RUN: llc -march=mips64el -mcpu=mips64 -target-abi=n64 -relocation-model=pic \
+; RUN:     < %s | FileCheck %s -check-prefixes=ALL,N64,HARD-FLOAT
 
 ; RUN: llc -march=mips64 -mcpu=mips64 -mattr=+soft-float -target-abi=n32 \
 ; RUN:     -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,N32,SOFT-FLOAT
@@ -14,9 +14,11 @@
 ; RUN:     -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,N32,SOFT-FLOAT
 
 ; RUN: llc -march=mips64 -mcpu=mips64 -mattr=+soft-float -target-abi=n64 < %s \
-; RUN: | FileCheck %s -check-prefixes=ALL,N64,SOFT-FLOAT
+; RUN:     -relocation-model=pic | FileCheck %s \
+; RUN:     -check-prefixes=ALL,N64,SOFT-FLOAT
 ; RUN: llc -march=mips64el -mcpu=mips64 -mattr=+soft-float -target-abi=n64 < \
-; RUN:     %s | FileCheck %s -check-prefixes=ALL,N64,SOFT-FLOAT
+; RUN:     %s -relocation-model=pic | FileCheck %s \
+; RUN:     -check-prefixes=ALL,N64,SOFT-FLOAT
 
 @fp128 = global fp128 zeroinitializer
 
diff --git a/llvm/test/CodeGen/Mips/compactbranches/compact-branches-64.ll b/llvm/test/CodeGen/Mips/compactbranches/compact-branches-64.ll
index cda42a3..1290acd 100644
--- a/llvm/test/CodeGen/Mips/compactbranches/compact-branches-64.ll
+++ b/llvm/test/CodeGen/Mips/compactbranches/compact-branches-64.ll
@@ -1,4 +1,5 @@
-; RUN: llc -march=mipsel -mcpu=mips64r6 -disable-mips-delay-filler -target-abi=n64 < %s | FileCheck %s
+; RUN: llc -relocation-model=pic -march=mipsel -mcpu=mips64r6 \
+; RUN:     -disable-mips-delay-filler -target-abi=n64 < %s | FileCheck %s
 
 ; Function Attrs: nounwind
 define void @l() {
diff --git a/llvm/test/CodeGen/Mips/compactbranches/compact-branches.ll b/llvm/test/CodeGen/Mips/compactbranches/compact-branches.ll
index 8ec85bc..ebbeea5 100644
--- a/llvm/test/CodeGen/Mips/compactbranches/compact-branches.ll
+++ b/llvm/test/CodeGen/Mips/compactbranches/compact-branches.ll
@@ -1,5 +1,7 @@
-; RUN: llc -march=mipsel -mcpu=mips32r6 -relocation-model=static -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=STATIC32
-; RUN: llc -march=mipsel -mcpu=mips64r6 -target-abi n64 -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=PIC
+; RUN: llc -march=mipsel -mcpu=mips32r6 -relocation-model=static \
+; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=STATIC32
+; RUN: llc -march=mipsel -mcpu=mips64r6 -relocation-model=pic -target-abi n64 \
+; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=PIC
 
 ; Function Attrs: nounwind
 define void @l()  {
diff --git a/llvm/test/CodeGen/Mips/cstmaterialization/stack.ll b/llvm/test/CodeGen/Mips/cstmaterialization/stack.ll
index 7266d00..41b5bf6 100644
--- a/llvm/test/CodeGen/Mips/cstmaterialization/stack.ll
+++ b/llvm/test/CodeGen/Mips/cstmaterialization/stack.ll
@@ -1,5 +1,5 @@
 ; RUN: llc -march=mipsel -mcpu=mips32 < %s | FileCheck %s -check-prefix=CHECK-MIPS32
-; RUN: llc -march=mips64el -mcpu=mips64 < %s | \
+; RUN: llc -march=mips64el -mcpu=mips64 -relocation-model=pic < %s | \
 ; RUN:      FileCheck %s -check-prefix=CHECK-MIPS64
 ; RUN: llc -march=mipsel -mcpu=mips64 -target-abi n32 < %s | \
 ; RUN:      FileCheck %s -check-prefix=CHECK-MIPSN32
diff --git a/llvm/test/CodeGen/Mips/elf_eflags.ll b/llvm/test/CodeGen/Mips/elf_eflags.ll
index 40910d8..80b9c48 100644
--- a/llvm/test/CodeGen/Mips/elf_eflags.ll
+++ b/llvm/test/CodeGen/Mips/elf_eflags.ll
@@ -14,7 +14,6 @@
 ; EF_MIPS_ARCH_64R2 (0x80000000)
 
 ; Note that EF_MIPS_CPIC is set by -mabicalls which is the default on Linux
-; TODO need to support -mno-abicalls
 
 ; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-LE32 %s
 ; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 %s -o - | FileCheck -check-prefix=CHECK-LE32_PIC %s
@@ -24,12 +23,12 @@
 ; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips %s -o - | FileCheck -check-prefix=CHECK-LE32R2-MICROMIPS_PIC %s
 
 ; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips4 -target-abi n64 -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-LE64 %s
-; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips4 -target-abi n64 %s -o - | FileCheck -check-prefix=CHECK-LE64_PIC %s
+; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips4 -target-abi n64 -relocation-model=pic %s -o - | FileCheck -check-prefix=CHECK-LE64_PIC %s
 
 ; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 -target-abi n64 -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-LE64 %s
-; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 -target-abi n64 %s -o - | FileCheck -check-prefix=CHECK-LE64_PIC %s
+; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 -target-abi n64 -relocation-model=pic %s -o - | FileCheck -check-prefix=CHECK-LE64_PIC %s
 ; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -target-abi n64 -relocation-model=static %s -o - | FileCheck -check-prefix=CHECK-LE64R2 %s
-; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -target-abi n64 %s -o - | FileCheck -check-prefix=CHECK-LE64R2_PIC %s
+; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -target-abi n64 -relocation-model=pic %s -o - | FileCheck -check-prefix=CHECK-LE64R2_PIC %s
 
 ; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+mips16 -relocation-model=pic %s -o - | FileCheck -check-prefix=CHECK-LE32R2-MIPS16 %s
 
@@ -61,7 +60,6 @@
 ; CHECK-LE32R2-MICROMIPS_PIC: .set micromips
 ;
 ; 64(R1) bit with NO_REORDER and static
-; CHECK-LE64: .abicalls
 ; CHECK-LE64: .set noreorder
 ;
 ; 64(R1) bit with NO_REORDER and PIC
@@ -69,7 +67,6 @@
 ; CHECK-LE64_PIC: .set noreorder
 ;
 ; 64R2 bit with NO_REORDER and static
-; CHECK-LE64R2: .abicalls
 ; CHECK-LE64R2: .set noreorder
 ;
 ; 64R2 bit with NO_REORDER and PIC
diff --git a/llvm/test/CodeGen/Mips/fcmp.ll b/llvm/test/CodeGen/Mips/fcmp.ll
index e22b12a..eb6c06d 100644
--- a/llvm/test/CodeGen/Mips/fcmp.ll
+++ b/llvm/test/CodeGen/Mips/fcmp.ll
@@ -1076,12 +1076,12 @@
 ; 32-CMP-DAG:    bnezc    $[[T4]],
 
 ; 64-C-DAG:      add.s    $[[T0:f[0-9]+]], $f13, $f12
-; 64-C-DAG:      lwc1     $[[T1:f[0-9]+]], %got_ofst(.LCPI32_0)(
+; 64-C-DAG:      lwc1     $[[T1:f[0-9]+]], %lo(.LCPI32_0)(
 ; 64-C-DAG:      c.ole.s  $[[T0]], $[[T1]]
 ; 64-C-DAG:      bc1t
 
 ; 64-CMP-DAG:    add.s    $[[T0:f[0-9]+]], $f13, $f12
-; 64-CMP-DAG:    lwc1     $[[T1:f[0-9]+]], %got_ofst(.LCPI32_0)(
+; 64-CMP-DAG:    lwc1     $[[T1:f[0-9]+]], %lo(.LCPI32_0)(
 ; 64-CMP-DAG:    cmp.le.s $[[T2:f[0-9]+]], $[[T0]], $[[T1]]
 ; 64-CMP-DAG:    mfc1     $[[T3:[0-9]+]], $[[T2]]
 ; FIXME: This instruction is redundant.
@@ -1102,16 +1102,17 @@
 ; MM32R6-DAG:    andi16   $[[T5:[0-9]+]], $[[T4]], 1
 ; MM32R6-DAG:    bnez     $[[T5]],
 
-; MM64R6-DAG:    lui      $[[T0:[0-9]+]], %hi(%neg(%gp_rel(bug1_f32)))
-; MM64R6-DAG:    daddu    $[[T1:[0-9]+]], $[[T0]], $25
-; MM64R6-DAG:    daddiu   $[[T2:[0-9]+]], $[[T1]], %lo(%neg(%gp_rel(bug1_f32)))
-; MM64R6-DAG:    add.s    $[[T3:f[0-9]+]], $f13, $f12
-; MM64R6-DAG:    ld       $[[T4:[0-9]+]], %got_page(.LCPI32_0)($[[T2]])
-; MM64R6-DAG:    lwc1     $[[T5:f[0-9]+]], %got_ofst(.LCPI32_0)($[[T4]])
-; MM64R6-DAG:    cmp.le.s $[[T6:f[0-9]+]], $[[T3]], $[[T5]]
-; MM64R6-DAG:    mfc1     $[[T7:[0-9]+]], $[[T6]]
-; MM64R6-DAG:    andi16   $[[T8:[0-9]+]], $[[T7]], 1
-; MM64R6-DAG:    bnez     $[[T8]],
+; MM64R6-DAG:    add.s    $[[T0:f[0-9]+]], $f13, $f12
+; MM64R6-DAG:    lui      $[[T1:[0-9]+]], %highest(.LCPI32_0)
+; MM64R6-DAG:    daddiu   $[[T2:[0-9]+]], $[[T1]], %higher(.LCPI32_0)
+; MM64R6-DAG:    dsll     $[[T3:[0-9]+]], $[[T2]], 16
+; MM64R6-DAG:    daddiu   $[[T4:[0-9]+]], $[[T3]], %hi(.LCPI32_0)
+; MM64R6-DAG:    dsll     $[[T5:[0-9]+]], $[[T4]], 16
+; MM64R6-DAG:    lwc1     $[[T6:f[0-9]+]], %lo(.LCPI32_0)($[[T5]])
+; MM64R6-DAG:    cmp.le.s $[[T7:f[0-9]+]], $[[T0]], $[[T6]]
+; MM64R6-DAG:    mfc1     $[[T8:[0-9]+]], $[[T7]]
+; MM64R6-DAG:    andi16   $[[T9:[0-9]+]], $[[T8]], 1
+; MM64R6-DAG:    bnez     $[[T9]],
 
   %add = fadd fast float %at, %angle
   %cmp = fcmp ogt float %add, 1.000000e+00
@@ -1145,12 +1146,12 @@
 ; 32-CMP-DAG:    bnezc    $[[T4]],
 
 ; 64-C-DAG:      add.d    $[[T0:f[0-9]+]], $f13, $f12
-; 64-C-DAG:      ldc1     $[[T1:f[0-9]+]], %got_ofst(.LCPI33_0)(
+; 64-C-DAG:      ldc1     $[[T1:f[0-9]+]], %lo(.LCPI33_0)(
 ; 64-C-DAG:      c.ole.d  $[[T0]], $[[T1]]
 ; 64-C-DAG:      bc1t
 
 ; 64-CMP-DAG:    add.d    $[[T0:f[0-9]+]], $f13, $f12
-; 64-CMP-DAG:    ldc1     $[[T1:f[0-9]+]], %got_ofst(.LCPI33_0)(
+; 64-CMP-DAG:    ldc1     $[[T1:f[0-9]+]], %lo(.LCPI33_0)(
 ; 64-CMP-DAG:    cmp.le.d $[[T2:f[0-9]+]], $[[T0]], $[[T1]]
 ; 64-CMP-DAG:    mfc1     $[[T3:[0-9]+]], $[[T2]]
 ; FIXME: This instruction is redundant.
@@ -1171,16 +1172,17 @@
 ; MM32R6-DAG:    andi16   $[[T5:[0-9]+]], $[[T4]], 1
 ; MM32R6-DAG:    bnez     $[[T5]],
 
-; MM64R6-DAG:    lui      $[[T0:[0-9]+]], %hi(%neg(%gp_rel(bug1_f64)))
-; MM64R6-DAG:    daddu    $[[T1:[0-9]+]], $[[T0]], $25
-; MM64R6-DAG:    daddiu   $[[T2:[0-9]+]], $[[T1]], %lo(%neg(%gp_rel(bug1_f64)))
-; MM64R6-DAG:    add.d    $[[T3:f[0-9]+]], $f13, $f12
-; MM64R6-DAG:    ld       $[[T4:[0-9]+]], %got_page(.LCPI33_0)($[[T2]])
-; MM64R6-DAG:    ldc1     $[[T5:f[0-9]+]], %got_ofst(.LCPI33_0)($[[T4]])
-; MM64R6-DAG:    cmp.le.d $[[T6:f[0-9]+]], $[[T3]], $[[T5]]
-; MM64R6-DAG:    mfc1     $[[T7:[0-9]+]], $[[T6]]
-; MM64R6-DAG:    andi16   $[[T8:[0-9]+]], $[[T7]], 1
-; MM64R6-DAG:    bnez     $[[T8]],
+; MM64R6-DAG:    add.d    $[[T0:f[0-9]+]], $f13, $f12
+; MM64R6-DAG:    lui      $[[T1:[0-9]+]], %highest(.LCPI33_0)
+; MM64R6-DAG:    daddiu   $[[T2:[0-9]+]], $[[T1]], %higher(.LCPI33_0)
+; MM64R6-DAG:    dsll     $[[T3:[0-9]+]], $[[T2]], 16
+; MM64R6-DAG:    daddiu   $[[T4:[0-9]+]], $[[T3]], %hi(.LCPI33_0)
+; MM64R6-DAG:    dsll     $[[T5:[0-9]+]], $[[T4]], 16
+; MM64R6-DAG:    ldc1     $[[T6:f[0-9]+]], %lo(.LCPI33_0)($[[T5]])
+; MM64R6-DAG:    cmp.le.d $[[T7:f[0-9]+]], $[[T0]], $[[T6]]
+; MM64R6-DAG:    mfc1     $[[T8:[0-9]+]], $[[T7]]
+; MM64R6-DAG:    andi16   $[[T9:[0-9]+]], $[[T8]], 1
+; MM64R6-DAG:    bnez     $[[T9]],
 
   %add = fadd fast double %at, %angle
   %cmp = fcmp ogt double %add, 1.000000e+00
diff --git a/llvm/test/CodeGen/Mips/fcopysign-f32-f64.ll b/llvm/test/CodeGen/Mips/fcopysign-f32-f64.ll
index a3ea22f..e0229d1 100644
--- a/llvm/test/CodeGen/Mips/fcopysign-f32-f64.ll
+++ b/llvm/test/CodeGen/Mips/fcopysign-f32-f64.ll
@@ -36,12 +36,12 @@
 entry:
 ; ALL-LABEL: func3:
 
-; 64:     dmfc1   $[[R0:[0-9]+]], ${{.*}}
+; 64:     mfc1    $[[MFC:[0-9]+]], $f13
 ; 64:     daddiu  $[[R1:[0-9]+]], $zero, 1
+; 64:     dmfc1   $[[R0:[0-9]+]], ${{.*}}
 ; 64:     dsll    $[[R2:[0-9]+]], $[[R1]], 63
 ; 64:     daddiu  $[[R3:[0-9]+]], $[[R2]], -1
 ; 64:     and     $[[AND0:[0-9]+]], $[[R0]], $[[R3]]
-; 64:     mfc1    $[[MFC:[0-9]+]], $f13
 ; 64:     srl     $[[SRL:[0-9]+]], $[[MFC:[0-9]+]], 31
 ; 64:     dsll    $[[DSLL:[0-9]+]], $[[SRL]], 63
 ; 64:     or      $[[OR:[0-9]+]], $[[AND0]], $[[DSLL]]
diff --git a/llvm/test/CodeGen/Mips/global-address.ll b/llvm/test/CodeGen/Mips/global-address.ll
index ecf5e56..ed79de9 100644
--- a/llvm/test/CodeGen/Mips/global-address.ll
+++ b/llvm/test/CodeGen/Mips/global-address.ll
@@ -29,9 +29,15 @@
 ; PIC-N64: ld  $[[R0:[0-9]+]], %got_page(s1)
 ; PIC-N64: lw  ${{[0-9]+}}, %got_ofst(s1)($[[R0]])
 ; PIC-N64: ld  ${{[0-9]+}}, %got_disp(g1)
-; STATIC-N64: ld  $[[R1:[0-9]+]], %got_page(s1)
-; STATIC-N64: lw  ${{[0-9]+}}, %got_ofst(s1)($[[R1]])
-; STATIC-N64: ld  ${{[0-9]+}}, %got_disp(g1)
+; STATIC-N64: lui $[[R1:[0-9]+]], %highest(s1)
+; STATIC-N64: daddiu ${{[0-9]+}}, ${{[0-9]+}}, %higher(s1)
+; STATIC-N64: daddiu ${{[0-9]+}}, ${{[0-9]+}}, %hi(s1)
+; STATIC-N64: dsll $[[R2:[0-9]+]], $[[R1]], 16
+; STATIC-N64: lw  ${{[0-9]+}}, %lo(s1)($[[R2]])
+; STATIC-N64: lui $[[R3:[0-9]+]], %highest(g1)
+; STATIC-N64: daddiu $[[R3]], $[[R3]], %higher(g1)
+; STATIC-N64: daddiu $[[R3]], $[[R3]], %hi(g1)
+; STATIC-N64: lw  ${{[0-9]+}}, %lo(g1)($[[R3]])
 
   %0 = load i32, i32* @s1, align 4
   tail call void @foo1(i32 %0) nounwind
diff --git a/llvm/test/CodeGen/Mips/inlineasm-constraint_ZC_2.ll b/llvm/test/CodeGen/Mips/inlineasm-constraint_ZC_2.ll
index a99cb97..2a0904c 100644
--- a/llvm/test/CodeGen/Mips/inlineasm-constraint_ZC_2.ll
+++ b/llvm/test/CodeGen/Mips/inlineasm-constraint_ZC_2.ll
@@ -1,7 +1,9 @@
 ; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s --check-prefixes=ALL,R6
-; RUN: llc -march=mips -mcpu=mips64r6 -target-abi=n64 < %s | FileCheck %s --check-prefixes=ALL,R6
+; RUN: llc -march=mips -mcpu=mips64r6 -target-abi=n64 -relocation-model=pic \
+; RUN:     < %s | FileCheck %s --check-prefixes=ALL,R6
 ; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s --check-prefixes=ALL,PRER6
-; RUN: llc -march=mips -mcpu=mips64 -target-abi=n64 < %s | FileCheck %s --check-prefixes=ALL,PRER6
+; RUN: llc -march=mips -mcpu=mips64 -target-abi=n64 -relocation-model=pic \
+; RUN:     < %s | FileCheck %s --check-prefixes=ALL,PRER6
 
 
 %struct.anon = type { [63 x i32], i32, i32 }
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/call.ll b/llvm/test/CodeGen/Mips/llvm-ir/call.ll
index 9af3e8d..a036faf 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/call.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/call.ll
@@ -6,24 +6,24 @@
 ; RUN: llc -march=mips   -mcpu=mips32r5 -relocation-model=pic  -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
 ; RUN: llc -march=mips   -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler  -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
 ; RUN: llc -march=mips   -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler  -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
-; RUN: llc -march=mips64 -mcpu=mips4     -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64    -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r2  -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r3  -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r5  -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r6 -disable-mips-delay-filler  -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,R6C
+; RUN: llc -march=mips64 -mcpu=mips4    -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64   -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r2 -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r3 -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r5 -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r6 -relocation-model=pic  -disable-mips-delay-filler  -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,R6C
 ; RUN: llc -march=mips   -mcpu=mips32   -relocation-model=pic  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
 ; RUN: llc -march=mips   -mcpu=mips32r2 -relocation-model=pic  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
 ; RUN: llc -march=mips   -mcpu=mips32r3 -relocation-model=pic  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
 ; RUN: llc -march=mips   -mcpu=mips32r5 -relocation-model=pic  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
 ; RUN: llc -march=mips   -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C
 ; RUN: llc -march=mips   -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C
-; RUN: llc -march=mips64 -mcpu=mips4     -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64    -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r2  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r3  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r5  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
-; RUN: llc -march=mips64 -mcpu=mips64r6 -disable-mips-delay-filler  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=R6C
+; RUN: llc -march=mips64 -mcpu=mips4    -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64   -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r2 -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r3 -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r5 -relocation-model=pic   -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
+; RUN: llc -march=mips64 -mcpu=mips64r6 -relocation-model=pic  -disable-mips-delay-filler  -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=R6C
 
 declare void @extern_void_void()
 declare i32 @extern_i32_void()
diff --git a/llvm/test/CodeGen/Mips/mips64-f128-call.ll b/llvm/test/CodeGen/Mips/mips64-f128-call.ll
index 9a093e6..c59f25e 100644
--- a/llvm/test/CodeGen/Mips/mips64-f128-call.ll
+++ b/llvm/test/CodeGen/Mips/mips64-f128-call.ll
@@ -4,8 +4,8 @@
 @gld1 = external global fp128
 
 ; CHECK: foo0
+; CHECK: sdc1  $f12, %lo(gld0)(${{[0-9]+}})
 ; CHECK: sdc1  $f13, 8(${{[0-9]+}})
-; CHECK: sdc1  $f12, 0(${{[0-9]+}})
 
 define void @foo0(fp128 %a0) {
 entry:
@@ -14,8 +14,8 @@
 }
 
 ; CHECK: foo1
+; CHECK: ldc1  $f12, %lo(gld0)(${{[0-9]+}})
 ; CHECK: ldc1  $f13, 8(${{[0-9]+}})
-; CHECK: ldc1  $f12, 0(${{[0-9]+}})
 
 define void @foo1() {
 entry:
@@ -26,13 +26,19 @@
 
 declare void @foo2(fp128)
 
-; CHECK: foo3
-; CHECK: ld   $[[R0:[0-9]+]], %got_disp(gld0)
-; CHECK: sdc1 $f2, 8($[[R0]])
-; CHECK: sdc1 $f0, 0($[[R0]])
-; CHECK: ld   $[[R1:[0-9]+]], %got_disp(gld1)
-; CHECK: ldc1 $f0, 0($[[R1]])
-; CHECK: ldc1 $f2, 8($[[R1]])
+; CHECK: foo3:
+; CHECK: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %hi(gld0)
+; CHECK: dsll $[[R1:[0-9]+]], $[[R0]], 16
+; CHECK: sdc1 $f0, %lo(gld0)($[[R1]])
+; CHECK: daddiu $[[R2:[0-9]]], $[[R1]], %lo(gld0)
+; CHECK: sdc1 $f2, 8($[[R2]])
+; CHECK: daddiu $[[R3:[0-9]+]], ${{[0-9]+}}, %hi(gld1)
+; CHECK: dsll $[[R4:[0-9]+]], $[[R3]], 16
+; CHECK: ldc1 $f0, %lo(gld1)($[[R4]])
+; CHECK: daddiu $[[R5:[0-9]]], $[[R4]], %lo(gld1)
+; CHECK: ldc1 $f2, 8($[[R5]])
+
+
 
 define fp128 @foo3() {
 entry:
diff --git a/llvm/test/CodeGen/Mips/mips64-f128.ll b/llvm/test/CodeGen/Mips/mips64-f128.ll
index 2b1c154..304ab8b 100644
--- a/llvm/test/CodeGen/Mips/mips64-f128.ll
+++ b/llvm/test/CodeGen/Mips/mips64-f128.ll
@@ -1,11 +1,15 @@
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips4 -mattr=+soft-float -O1 \
-; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6
+; RUN:     -disable-mips-delay-filler -relocation-model=pic < %s | FileCheck \
+; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64 -mattr=+soft-float -O1 \
-; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6
-; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r2 -mattr=+soft-float -O1 \
-; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6
-; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r6 -mattr=+soft-float -O1 \
-; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,CMP_CC_FMT,R6
+; RUN:     -disable-mips-delay-filler -relocation-model=pic < %s | FileCheck \
+; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6
+; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r2 -mattr=+soft-float \
+; RUN:     -O1 -disable-mips-delay-filler -relocation-model=pic < %s | FileCheck \
+; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6
+; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r6 -mattr=+soft-float \
+; RUN:     -O1 -disable-mips-delay-filler -relocation-model=pic < %s | FileCheck \
+; RUN:     %s -check-prefixes=ALL,CMP_CC_FMT,R6
 
 @gld0 = external global fp128
 @gld1 = external global fp128
diff --git a/llvm/test/CodeGen/Mips/mips64-libcall.ll b/llvm/test/CodeGen/Mips/mips64-libcall.ll
index 8512e9f..7c0e5b2 100644
--- a/llvm/test/CodeGen/Mips/mips64-libcall.ll
+++ b/llvm/test/CodeGen/Mips/mips64-libcall.ll
@@ -20,7 +20,7 @@
 ; Check call16.
 ;
 ; SOFT-LABEL: f64add:
-; SOFT: ld $25, %call16(__adddf3)
+; SOFT: jal __adddf3
 
 define double @f64add(double %a, double %b) {
 entry:
diff --git a/llvm/test/CodeGen/Mips/mips64instrs.ll b/llvm/test/CodeGen/Mips/mips64instrs.ll
index 8f124c8..c08c1b7 100644
--- a/llvm/test/CodeGen/Mips/mips64instrs.ll
+++ b/llvm/test/CodeGen/Mips/mips64instrs.ll
@@ -111,10 +111,8 @@
 define i64 @f14(i64 %a, i64 %b) nounwind readnone {
 entry:
 ; ALL-LABEL: f14:
-; ALL-DAG:       ld $[[P0:[0-9]+]], %got_disp(gll0)(
-; ALL-DAG:       ld $[[P1:[0-9]+]], %got_disp(gll1)(
-; ALL-DAG:       ld $[[T0:[0-9]+]], 0($[[P0]])
-; ALL-DAG:       ld $[[T1:[0-9]+]], 0($[[P1]])
+; ALL-DAG:       ld $[[T0:[0-9]+]], %lo(gll0)(${{[0-9]+}})
+; ALL-DAG:       ld $[[T1:[0-9]+]], %lo(gll1)(${{[0-9]+}})
 
 ; ACCMULDIV:     ddiv $zero, $[[T0]], $[[T1]]
 ; ACCMULDIV:     teq $[[T1]], $zero, 7
@@ -132,10 +130,8 @@
 define i64 @f15() nounwind readnone {
 entry:
 ; ALL-LABEL: f15:
-; ALL-DAG:       ld $[[P0:[0-9]+]], %got_disp(gll0)(
-; ALL-DAG:       ld $[[P1:[0-9]+]], %got_disp(gll1)(
-; ALL-DAG:       ld $[[T0:[0-9]+]], 0($[[P0]])
-; ALL-DAG:       ld $[[T1:[0-9]+]], 0($[[P1]])
+; ALL-DAG:       ld $[[T0:[0-9]+]], %lo(gll0)(${{[0-9]+}})
+; ALL-DAG:       ld $[[T1:[0-9]+]], %lo(gll1)(${{[0-9]+}})
 
 ; ACCMULDIV:     ddivu $zero, $[[T0]], $[[T1]]
 ; ACCMULDIV:     teq $[[T1]], $zero, 7
diff --git a/llvm/test/CodeGen/Mips/start-asm-file.ll b/llvm/test/CodeGen/Mips/start-asm-file.ll
index 6d0a542..bcea5da 100644
--- a/llvm/test/CodeGen/Mips/start-asm-file.ll
+++ b/llvm/test/CodeGen/Mips/start-asm-file.ll
@@ -75,7 +75,7 @@
 ; CHECK-PIC-N32-NLEGACY: .nan legacy
 ; CHECK-PIC-N32-N2008: .nan 2008
 
-; CHECK-STATIC-N64: .abicalls
+; CHECK-STATIC-N64-NOT: .abicalls
 ; CHECK-STATIC-N64-NOT: .option pic0
 ; CHECK-STATIC-N64: .section .mdebug.abi64
 ; CHECK-STATIC-N64-NLEGACY: .nan legacy
diff --git a/llvm/test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll b/llvm/test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll
index 6b09b69..25a5e5b 100644
--- a/llvm/test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll
+++ b/llvm/test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll
@@ -4,8 +4,11 @@
 ; RUN: llc -filetype=obj -march=mipsel -relocation-model=static -verify-machineinstrs -mips-tail-calls=1 < %s -o - \
 ; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=STATIC32
 
-; RUN: llc -filetype=obj -march=mips64el -mcpu=mips64 -verify-machineinstrs -mips-tail-calls=1 < %s -o - \
-; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=N64
+; RUN: llc -filetype=obj -march=mips64el -relocation-model=pic -mcpu=mips64 -verify-machineinstrs -mips-tail-calls=1 < %s -o - \
+; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=PIC64
+
+; RUN: llc -filetype=obj -march=mips64el -relocation-model=static -mcpu=mips64 -verify-machineinstrs -mips-tail-calls=1 < %s -o - \
+; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=STATIC64
 
 ; RUN: llc -filetype=obj -march=mipsel -relocation-model=pic -mattr=+micromips -mips-tail-calls=1 < %s -o - \
 ; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=PIC32MM
@@ -18,8 +21,11 @@
 ; RUN: llc -filetype=obj -march=mipsel -relocation-model=static -mcpu=mips32r6 -mips-tail-calls=1 < %s -o - \
 ; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=STATIC32R6
 
-; RUN: llc -filetype=obj -march=mips64el -mcpu=mips64r6 -mips-tail-calls=1 < %s -o - \
-; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=N64R6
+; RUN: llc -filetype=obj -march=mips64el -relocation-model=pic -mcpu=mips64r6 -mips-tail-calls=1 < %s -o - \
+; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=PIC64R6
+; RUN: llc -filetype=obj -march=mips64el -relocation-model=static -mcpu=mips64r6 -mips-tail-calls=1 < %s -o - \
+; RUN:   | llvm-objdump  -d - | FileCheck %s -check-prefix=STATIC64R6
+
 
 define internal i8 @f2(i8) {
   ret i8 4
@@ -34,7 +40,8 @@
 ; PIC32:      {{[0-9a-z]}}: 08 00 20 03  jr $25
 ; STATIC32:   {{[0-9a-z]}}: 00 00 00 08  j 0
 
-; N64:        {{[0-9a-z]+}}: 08 00 20 03  jr $25
+; PIC64:      {{[0-9a-z]+}}: 08 00 20 03  jr $25
+; STATIC64:   {{[0-9]}}: 00 00 00 08  j 0
 
 ; PIC32MM:    {{[0-9a-z]+}}: b9 45 jrc $25
 ; STATIC32MM: {{[0-9a-z]}}: 00 d4 00 00 j 0
@@ -42,5 +49,5 @@
 ; PIC32R6:    {{[0-9a-z]}}: 00 00 19 d8  jrc $25
 ; STATIC32R6: {{[0-9a-z]}}: 00 00 00 08  j 0
 
-; N64R6:      {{[0-9a-z]+}}: 00 00 19 d8  jrc $25
-
+; PIC64R6:    {{[0-9a-z]+}}: 00 00 19 d8  jrc $25
+; STATIC64R6: {{[0-9]}}: 00 00 00 08  j 0
diff --git a/llvm/test/CodeGen/Mips/tailcall/tailcall.ll b/llvm/test/CodeGen/Mips/tailcall/tailcall.ll
index b0ac28d..3f04e1c 100644
--- a/llvm/test/CodeGen/Mips/tailcall/tailcall.ll
+++ b/llvm/test/CodeGen/Mips/tailcall/tailcall.ll
@@ -2,8 +2,10 @@
 ; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,PIC32
 ; RUN: llc -march=mipsel -relocation-model=static  \
 ; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC32
-; RUN: llc -march=mips64el -mcpu=mips64r2  \
-; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64
+; RUN: llc -march=mips64el -mcpu=mips64r2  -relocation-model=pic \
+; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,PIC64
+; RUN: llc -march=mips64el -mcpu=mips64r2  -relocation-model=static \
+; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC64
 ; RUN: llc -march=mipsel -mattr=mips16 -relocation-model=pic \
 ; RUN:      -verify-machineinstrs -mips-tail-calls=1 < %s | \
 ; RUN:     FileCheck %s -check-prefixes=ALL,PIC16
@@ -15,17 +17,21 @@
 
 ; RUN: llc -march=mipsel -relocation-model=pic -mcpu=mips32r6 -mips-tail-calls=1 < %s | \
 ; RUN:     FileCheck %s -check-prefixes=ALL,PIC32R6
-; RUN: llc -march=mipsel -relocation-model=static -mcpu=mips32r6 \
+; RUN: llc -march=mipsel -relocation-model=static -mcpu=mips32r2 \
 ; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC32
-; RUN: llc -march=mips64el -mcpu=mips64r6  \
-; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64R6
+; RUN: llc -march=mips64el -relocation-model=pic -mcpu=mips64r2  \
+; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=PIC64
+; RUN: llc -march=mips64el -relocation-model=pic -mcpu=mips64r6  \
+; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=STATIC64
 
 ; RUN: llc -march=mipsel -relocation-model=pic -mcpu=mips32r6 -mattr=+micromips \
 ; RUN:      -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,PIC32MM
 ; RUN: llc -march=mipsel -relocation-model=static -mcpu=mips32r6 \
 ; RUN:     -mattr=+micromips -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC32
-; RUN: llc -march=mips64el -mcpu=mips64r6 -mattr=+micromips -mips-tail-calls=1 < %s \
-; RUN:      | FileCheck %s -check-prefixes=ALL,N64
+; RUN: llc -march=mips64el -relocation-model=pic -mcpu=mips64r6 \
+; RUN:     -mattr=+micromips -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=PIC64R6MM
+; RUN: llc -march=mips64el -relocation-model=static -mcpu=mips64r6 \
+; RUN:     -mattr=+micromips -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=STATIC64
 
 @g0 = common global i32 0, align 4
 @g1 = common global i32 0, align 4
@@ -96,7 +102,8 @@
 ; PIC32R6: jalr $25
 ; PIC32MM: jalr $25
 ; STATIC32: jal
-; N64: jalr $25
+; PIC64: jalr $25
+; STATIC64: jal
 ; N64R6: jalr $25
 ; PIC16: jalrc
 
@@ -113,8 +120,8 @@
 ; PIC32R6: jr $25
 ; PIC32MM: jr
 ; STATIC32: j
-; N64: jr $25
-; N64R6: jr $25
+; PIC64: jr $25
+; STATIC64: j
 ; PIC16: jalrc
 
   %0 = load i32, i32* @g0, align 4
@@ -154,8 +161,10 @@
 ; PIC32R6: jrc $25
 ; PIC32MM: jrc
 ; STATIC32: j
-; N64: jr $25
-; N64R6: jrc $25
+; PIC64: jr $25
+; PIC64R6: jrc $25
+; PIC64R6MM: jr $25
+; STATIC64: j
 ; PIC16: jalrc
 
   %call = tail call fastcc i32 @caller8_1()
@@ -169,8 +178,8 @@
 ; PIC32R6: jalr $25
 ; PIC32MM: jalr $25
 ; STATIC32: jal
-; N64: jalr $25
-; N64R6: jalr $25
+; PIC64: jalr $25
+; STATIC64: jal
 ; PIC16: jalrc
 
   %call = tail call i32 (i32, ...) @callee8(i32 2, i32 1) nounwind
@@ -190,8 +199,9 @@
 ; PIC32R6: jrc $25
 ; PIC32MM: jrc
 ; STATIC32: j
-; N64: jr $25
-; N64R6: jrc $25
+; PIC64: jr $25
+; STATIC64: j
+; PIC64R6: jrc $25
 ; PIC16: jalrc
   %call = tail call fastcc i32 @caller9_1()
   ret i32 %call
@@ -204,8 +214,9 @@
 ; PIC32R6: jalrc $25
 ; PIC32MM: jalr $25
 ; STATIC32: jal
-; N64: jalr $25
-; N64R6: jalrc $25
+; STATIC64: jal
+; PIC64: jalr $25
+; PIC64R6: jalrc $25
 ; PIC16: jalrc
 
   %call = tail call i32 @callee9(%struct.S* byval @gs1) nounwind
@@ -221,8 +232,9 @@
 ; PIC32R6: jalr $25
 ; PIC32MM: jalr $25
 ; STATIC32: jal
-; N64: jalr $25
-; N64R6: jalr $25
+; STATIC64: jal
+; PIC64: jalr $25
+; PIC64R6: jalr $25
 ; PIC16: jalrc
 
   %call = tail call i32 @callee10(i32 %a8, i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) nounwind
@@ -238,8 +250,9 @@
 ; PIC32R6: jalrc $25
 ; PIC32MM: jalr $25
 ; STATIC32: jal
-; N64: jalr $25
-; N64R6: jalrc $25
+; STATIC64: jal
+; PIC64: jalr $25
+; PIC64R6: jalrc $25
 ; PIC16: jalrc
 
   %call = tail call i32 @callee11(%struct.S* byval @gs1) nounwind
@@ -257,8 +270,9 @@
 ; PIC32R6: jalrc $25
 ; PIC32MM: jalr $25
 ; STATIC32: jal
-; N64: jalr $25
-; N64R6: jalrc $25
+; STATIC64: jal
+; PIC64: jalr $25
+; PIC64R6: jalrc $25
 ; PIC16: jalrc
 
   %0 = bitcast %struct.S* %a0 to i8*
@@ -271,13 +285,14 @@
 
 define i32 @caller13() nounwind {
 entry:
-; ALL-LABEL: caller13
+; ALL-LABEL: caller13:
 ; PIC32: jalr $25
 ; PIC32R6: jalr $25
 ; PIC32MM: jalr $25
 ; STATIC32: jal
-; N64: jalr $25
-; N64R6: jalr $25
+; STATIC64: jal
+; PIC64R6: jalr $25
+; PIC64: jalr $25
 ; PIC16: jalrc
 
   %call = tail call i32 (i32, ...) @callee13(i32 1, i32 2) nounwind
diff --git a/llvm/test/MC/Mips/elf_eflags.s b/llvm/test/MC/Mips/elf_eflags.s
index 244b07d..38742a8 100644
--- a/llvm/test/MC/Mips/elf_eflags.s
+++ b/llvm/test/MC/Mips/elf_eflags.s
@@ -2,26 +2,48 @@
 # corresponding options (-mcpu=mips32 -> -mips32 for example).
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r6 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R6 %s
-# MIPSEL-MIPS64R6: Flags [ (0xA0000406)
+# MIPSEL-MIPS64R6: Flags [ (0xA0000400)
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r6 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R6-NAN2008 %s
-# MIPSEL-MIPS64R6-NAN2008: Flags [ (0xA0000406)
+# MIPSEL-MIPS64R6-NAN2008: Flags [ (0xA0000400)
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r2 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2 %s
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r3 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2 %s
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r5 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2 %s
-# MIPSEL-MIPS64R2: Flags [ (0x80000006)
+# MIPSEL-MIPS64R2: Flags [ (0x80000000)
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r2 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-NAN2008 %s
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r3 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-NAN2008 %s
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64r5 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-NAN2008 %s
-# MIPSEL-MIPS64R2-NAN2008: Flags [ (0x80000406)
+# MIPSEL-MIPS64R2-NAN2008: Flags [ (0x80000400)
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64 %s
-# MIPSEL-MIPS64: Flags [ (0x60000006)
+# MIPSEL-MIPS64: Flags [ (0x60000000)
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips64 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64-NAN2008 %s
-# MIPSEL-MIPS64-NAN2008: Flags [ (0x60000406)
+# MIPSEL-MIPS64-NAN2008: Flags [ (0x60000400)
+
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64r6 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R6-PIC %s
+# MIPSEL-MIPS64R6-PIC: Flags [ (0xA0000406)
+
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64r6 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R6-NAN2008-PIC %s
+# MIPSEL-MIPS64R6-NAN2008-PIC: Flags [ (0xA0000406)
+
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64r2 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-PIC %s
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64r3 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-PIC %s
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64r5 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-PIC %s
+# MIPSEL-MIPS64R2-PIC: Flags [ (0x80000006)
+
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64r2 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-NAN2008-PIC %s
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64r3 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-NAN2008-PIC %s
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64r5 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64R2-NAN2008-PIC %s
+# MIPSEL-MIPS64R2-NAN2008-PIC: Flags [ (0x80000406)
+
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64-PIC %s
+# MIPSEL-MIPS64-PIC: Flags [ (0x60000006)
+
+# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -position-independent -mcpu=mips64 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS64-NAN2008-PIC %s
+# MIPSEL-MIPS64-NAN2008-PIC: Flags [ (0x60000406)
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32r6 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS32R6 %s
 # MIPSEL-MIPS32R6: Flags [ (0x90001404)
@@ -59,16 +81,28 @@
 # MIPS64EL-MIPS64-N32-NAN2008: Flags [ (0x60000424)
 
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64r2 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2-N64 %s
-# MIPS64EL-MIPS64R2-N64: Flags [ (0x80000006)
+# MIPS64EL-MIPS64R2-N64: Flags [ (0x80000000)
 
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64r2 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2-N64-NAN2008 %s
-# MIPS64EL-MIPS64R2-N64-NAN2008: Flags [ (0x80000406)
+# MIPS64EL-MIPS64R2-N64-NAN2008: Flags [ (0x80000400)
 
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64 %s -target-abi n64 -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64-N64 %s
-# MIPS64EL-MIPS64-N64: Flags [ (0x60000006)
+# MIPS64EL-MIPS64-N64: Flags [ (0x60000000)
 
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64 %s -target-abi n64 -mattr=+nan2008 -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64-N64-NAN2008 %s
-# MIPS64EL-MIPS64-N64-NAN2008: Flags [ (0x60000406)
+# MIPS64EL-MIPS64-N64-NAN2008: Flags [ (0x60000400)
+
+# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -position-independent -mcpu=mips64r2 -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2-N64-PIC %s
+# MIPS64EL-MIPS64R2-N64-PIC: Flags [ (0x80000006)
+
+# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -position-independent -mcpu=mips64r2 -target-abi n64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2-N64-NAN2008-PIC %s
+# MIPS64EL-MIPS64R2-N64-NAN2008-PIC: Flags [ (0x80000406)
+
+# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -position-independent -mcpu=mips64 %s -target-abi n64 -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64-N64-PIC %s
+# MIPS64EL-MIPS64-N64-PIC: Flags [ (0x60000006)
+
+# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -position-independent -mcpu=mips64 %s -target-abi n64 -mattr=+nan2008 -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64-N64-NAN2008-PIC %s
+# MIPS64EL-MIPS64-N64-NAN2008-PIC: Flags [ (0x60000406)
 
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64r2 -target-abi o32 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2-O32 %s
 # MIPS64EL-MIPS64R2-O32: Flags [ (0x80001104)
@@ -77,22 +111,40 @@
 # MIPS64EL-MIPS64R2-O32-NAN2008: Flags [ (0x80001504)
 
 # RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips5 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS5 %s
-# MIPS5: Flags [ (0x40000006)
+# MIPS5: Flags [ (0x40000000)
 
- # RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips5 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS5-NAN2008 %s
-# MIPS5-NAN2008: Flags [ (0x40000406)
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips5 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS5-NAN2008 %s
+# MIPS5-NAN2008: Flags [ (0x40000400)
 
 # RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips4 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS4 %s
-# MIPS4: Flags [ (0x30000006)
+# MIPS4: Flags [ (0x30000000)
 
- # RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips4 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS4-NAN2008 %s
-# MIPS4-NAN2008: Flags [ (0x30000406)
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips4 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS4-NAN2008 %s
+# MIPS4-NAN2008: Flags [ (0x30000400)
 
 # RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips3 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS3 %s
-# MIPS3: Flags [ (0x20000006)
+# MIPS3: Flags [ (0x20000000)
 
- # RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips3 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS3-NAN2008 %s
-# MIPS3-NAN2008: Flags [ (0x20000406)
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -mcpu=mips3 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS3-NAN2008 %s
+# MIPS3-NAN2008: Flags [ (0x20000400)
+
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -position-independent -mcpu=mips5 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS5-PIC %s
+# MIPS5-PIC: Flags [ (0x40000006)
+
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -position-independent -mcpu=mips5 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS5-NAN2008-PIC %s
+# MIPS5-NAN2008-PIC: Flags [ (0x40000406)
+
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -position-independent -mcpu=mips4 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS4-PIC %s
+# MIPS4-PIC: Flags [ (0x30000006)
+
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -position-independent -mcpu=mips4 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS4-NAN2008-PIC %s
+# MIPS4-NAN2008-PIC: Flags [ (0x30000406)
+
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -position-independent -mcpu=mips3 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS3-PIC %s
+# MIPS3-PIC: Flags [ (0x20000006)
+
+# RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux -position-independent -mcpu=mips3 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS3-NAN2008-PIC %s
+# MIPS3-NAN2008-PIC: Flags [ (0x20000406)
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips2 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-MIPS2 %s
 # MIPSEL-MIPS2: Flags [ (0x10001004)
@@ -103,7 +155,7 @@
 # RUN: llvm-mc -filetype=obj -triple mips-unknown-linux -mcpu=mips1 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS1 %s
 # MIPS1: Flags [ (0x1004)
 
- # RUN: llvm-mc -filetype=obj -triple mips-unknown-linux -mcpu=mips1 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS1-NAN2008 %s
+# RUN: llvm-mc -filetype=obj -triple mips-unknown-linux -mcpu=mips1 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS1-NAN2008 %s
 # MIPS1-NAN2008: Flags [ (0x1404)
 
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64 %s -target-abi o32 -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64-O32 %s
@@ -114,17 +166,31 @@
 
 # Default ABI for MIPS64 is N64 as opposed to GCC/GAS (N32)
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64r2 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2 %s
-# MIPS64EL-MIPS64R2: Flags [ (0x80000006)
+# MIPS64EL-MIPS64R2: Flags [ (0x80000000)
 
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64r2 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2-NAN2008 %s
-# MIPS64EL-MIPS64R2-NAN2008: Flags [ (0x80000406)
+# MIPS64EL-MIPS64R2-NAN2008: Flags [ (0x80000400)
 
 # Default ABI for MIPS64 is N64 as opposed to GCC/GAS (N32)
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64 %s
-# MIPS64EL-MIPS64: Flags [ (0x60000006)
+# MIPS64EL-MIPS64: Flags [ (0x60000000)
 
 # RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -mcpu=mips64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64-NAN2008 %s
-# MIPS64EL-MIPS64-NAN2008: Flags [ (0x60000406)
+# MIPS64EL-MIPS64-NAN2008: Flags [ (0x60000400)
+
+# Default ABI for MIPS64 is N64 as opposed to GCC/GAS (N32)
+# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -position-independent -mcpu=mips64r2 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2-PIC %s
+# MIPS64EL-MIPS64R2-PIC: Flags [ (0x80000006)
+
+# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -position-independent -mcpu=mips64r2 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64R2-NAN2008-PIC %s
+# MIPS64EL-MIPS64R2-NAN2008-PIC: Flags [ (0x80000406)
+
+# Default ABI for MIPS64 is N64 as opposed to GCC/GAS (N32)
+# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -position-independent -mcpu=mips64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64-PIC %s
+# MIPS64EL-MIPS64-PIC: Flags [ (0x60000006)
+
+# RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux -position-independent -mcpu=mips64 -mattr=+nan2008 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPS64EL-MIPS64-NAN2008-PIC %s
+# MIPS64EL-MIPS64-NAN2008-PIC: Flags [ (0x60000406)
 
 # RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=octeon -target-abi n64 %s -o -| llvm-readobj -h | FileCheck --check-prefix=MIPSEL-OCTEON %s
-# MIPSEL-OCTEON: Flags [ (0x808B0006)
+# MIPSEL-OCTEON: Flags [ (0x808B0000)