[llvm] 11074bf - [mips] Fix sc, scs, ll, lld instructions expanding

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 26 13:44:09 PST 2019


Author: Simon Atanasyan
Date: 2019-11-27T00:43:25+03:00
New Revision: 11074bfffee022fbbdca177a96dc2eaf2df6d936

URL: https://github.com/llvm/llvm-project/commit/11074bfffee022fbbdca177a96dc2eaf2df6d936
DIFF: https://github.com/llvm/llvm-project/commit/11074bfffee022fbbdca177a96dc2eaf2df6d936.diff

LOG: [mips] Fix sc, scs, ll, lld instructions expanding

There are a couple of bugs with the sc, scs, ll, lld instructions expanding:

1. On R6 these instruction pack immediate offset into a 9-bit field. Now
if an immediate exceeds 9-bits assembler does not perform expansion and
just rejects such instruction.

2. On 64-bit non-PIC code if an operand is a symbol assembler generates
incorrect sequence of instructions. It uses R_MIPS_HI16 and R_MIPS_LO16
relocations and skips R_MIPS_HIGHEST and R_MIPS_HIGHER ones.

To solve these problems this patch:
- Introduces `mem_simm9_exp` to mark 9-bit memory immediate operands
which require expansion. Probably later all `mem_simm9` operands will be
able to migrate on `mem_simm9_exp` and we rename it to `mem_simm9`.

- Adds new `OPERAND_MEM_SIMM9` operand type and assigns it to the
`mem_simm9_exp`. That allows to know operand size in the `processInstruction`
method and decide whether we need to expand instruction.

- Adds `expandMem9Inst` method to expand instructions with 9-bit memory
immediate operand. This method just load immediate into a "base"
register used by origibal instruction:

   sc $2, 256($sp) => addiu  $1, $sp, 256
                      sc     $2, 0($1)

- Fix `expandMem16Inst` to support a correct set of relocations for
symbol loading in case of 64-bit non-PIC code.

   ll $12, symbol => lui    $12, 0
                         R_MIPS_HIGHEST symbol
                     daddiu $12, $12, 0
                         R_MIPS_HIGHER symbol
                     dsll   $12, $12, 16
                     daddiu $12, $12, 0
                         R_MIPS_HI16 symbol
                     dsll   $12, $12, 16
                     ll     $12, 0($12)
                         R_MIPS_LO16 symbol

- Fix `expandMem16Inst` to unify handling of 3 and 4 operands
instructions.

- Delete unused now `MipsTargetStreamer::emitSCWithSymOffset` method.

Task for next patches - implement expanding for other instructions use
`mem_simm9` operand and other `mem_simm##` operands.

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

Added: 
    llvm/test/MC/Mips/ll-expansion.s
    llvm/test/MC/Mips/lld-expansion.s
    llvm/test/MC/Mips/scd-expansion.s

Modified: 
    llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
    llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
    llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
    llvm/lib/Target/Mips/Mips32r6InstrInfo.td
    llvm/lib/Target/Mips/Mips64r6InstrInfo.td
    llvm/lib/Target/Mips/MipsInstrInfo.td
    llvm/lib/Target/Mips/MipsTargetStreamer.h
    llvm/test/MC/Mips/sc-expansion.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 7f5281217953..639ee2df96a9 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -252,8 +252,10 @@ class MipsAsmParser : public MCTargetAsmParser {
   bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
                                   const MCSubtargetInfo *STI);
 
-  void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
-                     const MCSubtargetInfo *STI, bool IsLoad);
+  void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+                       const MCSubtargetInfo *STI, bool IsLoad);
+  void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+                      const MCSubtargetInfo *STI, bool IsLoad);
 
   bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
                                const MCSubtargetInfo *STI);
@@ -1824,11 +1826,14 @@ static bool needsExpandMemInst(MCInst &Inst) {
 
   const MCOperandInfo &OpInfo = MCID.OpInfo[NumOp - 1];
   if (OpInfo.OperandType != MCOI::OPERAND_MEMORY &&
-      OpInfo.OperandType != MCOI::OPERAND_UNKNOWN)
+      OpInfo.OperandType != MCOI::OPERAND_UNKNOWN &&
+      OpInfo.OperandType != MipsII::OPERAND_MEM_SIMM9)
     return false;
 
   MCOperand &Op = Inst.getOperand(NumOp - 1);
   if (Op.isImm()) {
+    if (OpInfo.OperandType == MipsII::OPERAND_MEM_SIMM9)
+      return !isInt<9>(Op.getImm());
     // Offset can't exceed 16bit value.
     return !isInt<16>(Op.getImm());
   }
@@ -2133,7 +2138,15 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
     // Check the offset of memory operand, if it is a symbol
     // reference or immediate we may have to expand instructions.
     if (needsExpandMemInst(Inst)) {
-      expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
+      const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
+      switch (MCID.OpInfo[MCID.getNumOperands() - 1].OperandType) {
+      case MipsII::OPERAND_MEM_SIMM9:
+        expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
+        break;
+      default:
+        expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
+        break;
+      }
       return getParser().hasPendingError();
     }
   }
@@ -3631,20 +3644,26 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
   return false;
 }
 
-void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
-                                  const MCSubtargetInfo *STI, bool IsLoad) {
-  const MCOperand &DstRegOp = Inst.getOperand(0);
+void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+                                    const MCSubtargetInfo *STI, bool IsLoad) {
+  unsigned NumOp = Inst.getNumOperands();
+  assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
+  unsigned StartOp = NumOp == 3 ? 0 : 1;
+
+  const MCOperand &DstRegOp = Inst.getOperand(StartOp);
   assert(DstRegOp.isReg() && "expected register operand kind");
-  const MCOperand &BaseRegOp = Inst.getOperand(1);
+  const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
   assert(BaseRegOp.isReg() && "expected register operand kind");
+  const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
 
   MipsTargetStreamer &TOut = getTargetStreamer();
+  unsigned OpCode = Inst.getOpcode();
   unsigned DstReg = DstRegOp.getReg();
   unsigned BaseReg = BaseRegOp.getReg();
   unsigned TmpReg = DstReg;
 
-  const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
-  int16_t DstRegClass = Desc.OpInfo[0].RegClass;
+  const MCInstrDesc &Desc = getInstDesc(OpCode);
+  int16_t DstRegClass = Desc.OpInfo[StartOp].RegClass;
   unsigned DstRegClassID =
       getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
   bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
@@ -3658,25 +3677,12 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
       return;
   }
 
-  if (Inst.getNumOperands() > 3) {
-    const MCOperand &BaseRegOp = Inst.getOperand(2);
-    assert(BaseRegOp.isReg() && "expected register operand kind");
-    const MCOperand &ExprOp = Inst.getOperand(3);
-    assert(ExprOp.isExpr() && "expected expression oprand kind");
-
-    unsigned BaseReg = BaseRegOp.getReg();
-    const MCExpr *ExprOffset = ExprOp.getExpr();
-
-    MCOperand LoOperand = MCOperand::createExpr(
-        MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
-    MCOperand HiOperand = MCOperand::createExpr(
-        MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
-    TOut.emitSCWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
-                             LoOperand, TmpReg, IDLoc, STI);
-    return;
-  }
-
-  const MCOperand &OffsetOp = Inst.getOperand(2);
+  auto emitInstWithOffset = [&](const MCOperand &Off) {
+    if (NumOp == 3)
+      TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
+    else
+      TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
+  };
 
   if (OffsetOp.isImm()) {
     int64_t LoOffset = OffsetOp.getImm() & 0xffff;
@@ -3690,16 +3696,16 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
     bool IsLargeOffset = HiOffset != 0;
 
     if (IsLargeOffset) {
-      bool Is32BitImm = (HiOffset >> 32) == 0;
+      bool Is32BitImm = isInt<32>(OffsetOp.getImm());
       if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
                         IDLoc, Out, STI))
         return;
     }
 
     if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
-      TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
-                   BaseReg, IDLoc, STI);
-    TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
+      TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
+                   TmpReg, BaseReg, IDLoc, STI);
+    emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
     return;
   }
 
@@ -3723,26 +3729,41 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
 
       loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
                               !ABI.ArePtrs64bit(), IDLoc, Out, STI);
-      TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, Res.getConstant(), IDLoc,
-                   STI);
+      emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
     } else {
       // FIXME: Implement 64-bit case.
       // 1) lw $8, sym => lui $8,  %hi(sym)
       //                  lw  $8,  %lo(sym)($8)
       // 2) sw $8, sym => lui $at, %hi(sym)
       //                  sw  $8,  %lo(sym)($at)
-      const MCExpr *ExprOffset = OffsetOp.getExpr();
+      const MCExpr *OffExpr = OffsetOp.getExpr();
       MCOperand LoOperand = MCOperand::createExpr(
-          MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
+          MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext()));
       MCOperand HiOperand = MCOperand::createExpr(
-          MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
-
-      // Generate the base address in TmpReg.
-      TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
-      if (BaseReg != Mips::ZERO)
-        TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
-      // Emit the load or store with the adjusted base and offset.
-      TOut.emitRRX(Inst.getOpcode(), DstReg, TmpReg, LoOperand, IDLoc, STI);
+          MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext()));
+
+      if (ABI.IsN64()) {
+        MCOperand HighestOperand = MCOperand::createExpr(
+            MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext()));
+        MCOperand HigherOperand = MCOperand::createExpr(
+            MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext()));
+
+        TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
+        TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
+        TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
+        TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
+        TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
+        if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
+          TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
+        emitInstWithOffset(LoOperand);
+      } else {
+        // Generate the base address in TmpReg.
+        TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
+        if (BaseReg != Mips::ZERO)
+          TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
+        // Emit the load or store with the adjusted base and offset.
+        emitInstWithOffset(LoOperand);
+      }
     }
     return;
   }
@@ -3750,6 +3771,64 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
   llvm_unreachable("unexpected operand type");
 }
 
+void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+                                   const MCSubtargetInfo *STI, bool IsLoad) {
+  unsigned NumOp = Inst.getNumOperands();
+  assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
+  unsigned StartOp = NumOp == 3 ? 0 : 1;
+
+  const MCOperand &DstRegOp = Inst.getOperand(StartOp);
+  assert(DstRegOp.isReg() && "expected register operand kind");
+  const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
+  assert(BaseRegOp.isReg() && "expected register operand kind");
+  const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
+
+  MipsTargetStreamer &TOut = getTargetStreamer();
+  unsigned OpCode = Inst.getOpcode();
+  unsigned DstReg = DstRegOp.getReg();
+  unsigned BaseReg = BaseRegOp.getReg();
+  unsigned TmpReg = DstReg;
+
+  const MCInstrDesc &Desc = getInstDesc(OpCode);
+  int16_t DstRegClass = Desc.OpInfo[StartOp].RegClass;
+  unsigned DstRegClassID =
+      getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
+  bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
+               (DstRegClassID == Mips::GPR64RegClassID);
+
+  if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
+    // At this point we need AT to perform the expansions
+    // and we exit if it is not available.
+    TmpReg = getATReg(IDLoc);
+    if (!TmpReg)
+      return;
+  }
+
+  auto emitInst = [&]() {
+    if (NumOp == 3)
+      TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
+    else
+      TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
+                    IDLoc, STI);
+  };
+
+  if (OffsetOp.isImm()) {
+    loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
+                  IDLoc, Out, STI);
+    emitInst();
+    return;
+  }
+
+  if (OffsetOp.isExpr()) {
+    loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
+                            !ABI.ArePtrs64bit(), IDLoc, Out, STI);
+    emitInst();
+    return;
+  }
+
+  llvm_unreachable("unexpected operand type");
+}
+
 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
                                             MCStreamer &Out,
                                             const MCSubtargetInfo *STI) {

diff  --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
index 3c11edfc3fc7..02ab5ede2c1a 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
@@ -16,6 +16,7 @@
 #include "MipsFixupKinds.h"
 #include "MipsMCTargetDesc.h"
 #include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInstrDesc.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -127,6 +128,12 @@ namespace MipsII {
     HasFCCRegOperand = 1 << 6
 
   };
+
+  enum OperandType : unsigned {
+    OPERAND_FIRST_MIPS_MEM_IMM = MCOI::OPERAND_FIRST_TARGET,
+    OPERAND_MEM_SIMM9 = OPERAND_FIRST_MIPS_MEM_IMM,
+    OPERAND_LAST_MIPS_MEM_IMM = OPERAND_MEM_SIMM9
+  };
 }
 }
 

diff  --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index d84e4eada646..d0b3c204730f 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
@@ -12,6 +12,7 @@
 
 #include "MipsMCTargetDesc.h"
 #include "MipsAsmBackend.h"
+#include "MipsBaseInfo.h"
 #include "MipsELFStreamer.h"
 #include "MipsInstPrinter.h"
 #include "MipsMCAsmInfo.h"

diff  --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index b6dae9f6dea8..054dc79f4aa9 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -34,11 +34,6 @@ static cl::opt<bool> RoundSectionSizes(
     cl::desc("Round section sizes up to the section alignment"), cl::Hidden);
 } // end anonymous namespace
 
-static bool isMipsR6(const MCSubtargetInfo *STI) {
-  return STI->getFeatureBits()[Mips::FeatureMips32r6] ||
-         STI->getFeatureBits()[Mips::FeatureMips64r6];
-}
-
 static bool isMicroMips(const MCSubtargetInfo *STI) {
   return STI->getFeatureBits()[Mips::FeatureMicroMips];
 }
@@ -332,36 +327,6 @@ void MipsTargetStreamer::emitStoreWithImmOffset(
   emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI);
 }
 
-/// Emit a store instruction with an symbol offset.
-void MipsTargetStreamer::emitSCWithSymOffset(unsigned Opcode, unsigned SrcReg,
-                                             unsigned BaseReg,
-                                             MCOperand &HiOperand,
-                                             MCOperand &LoOperand,
-                                             unsigned ATReg, SMLoc IDLoc,
-                                             const MCSubtargetInfo *STI) {
-  // sc $8, sym => lui $at, %hi(sym)
-  //               sc $8, %lo(sym)($at)
-
-  // Generate the base address in ATReg.
-  emitRX(Mips::LUi, ATReg, HiOperand, IDLoc, STI);
-  if (!isMicroMips(STI) && isMipsR6(STI)) {
-    // For non-micromips r6 offset for 'sc' is not in the lower 16 bits so we
-    // put it in 'at'.
-    // sc $8, sym => lui $at, %hi(sym)
-    //               addiu $at, $at, %lo(sym)
-    //               sc $8, 0($at)
-    emitRRX(Mips::ADDiu, ATReg, ATReg, LoOperand, IDLoc, STI);
-    MCOperand Offset = MCOperand::createImm(0);
-    // Emit the store with the adjusted base and offset.
-    emitRRRX(Opcode, SrcReg, SrcReg, ATReg, Offset, IDLoc, STI);
-  } else {
-    if (BaseReg != Mips::ZERO)
-      emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
-    // Emit the store with the adjusted base and offset.
-    emitRRRX(Opcode, SrcReg, SrcReg, ATReg, LoOperand, IDLoc, STI);
-  }
-}
-
 /// Emit a load instruction with an immediate offset. DstReg and TmpReg are
 /// permitted to be the same register iff DstReg is distinct from BaseReg and
 /// DstReg is a GPR. It is the callers responsibility to identify such cases

diff  --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
index a735d45ddbfc..9607d008bc97 100644
--- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -765,12 +765,12 @@ class LL_R6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
   InstrItinClass Itinerary = itin;
 }
 
-class LL_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9, II_LL>;
+class LL_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9_exp, II_LL>;
 
 class SC_R6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
                       InstrItinClass itin> {
   dag OutOperandList = (outs GPROpnd:$dst);
-  dag InOperandList = (ins GPROpnd:$rt, mem_simm9:$addr);
+  dag InOperandList = (ins GPROpnd:$rt, mem_simm9_exp:$addr);
   string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
   list<dag> Pattern = [];
   bit mayStore = 1;

diff  --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
index efebd77e531f..33132d9ede92 100644
--- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
@@ -75,7 +75,7 @@ class DMUL_R6_DESC : MUL_R6_DESC_BASE<"dmul", GPR64Opnd, II_DMUL, mul>;
 class DMULU_DESC   : MUL_R6_DESC_BASE<"dmulu", GPR64Opnd, II_DMUL>;
 class LDPC_DESC    : PCREL_DESC_BASE<"ldpc", GPR64Opnd, simm18_lsl3, II_LDPC>;
 class LWUPC_DESC   : PCREL_DESC_BASE<"lwupc", GPR32Opnd, simm19_lsl2, II_LWUPC>;
-class LLD_R6_DESC   : LL_R6_DESC_BASE<"lld", GPR64Opnd, mem_simmptr, II_LLD>;
+class LLD_R6_DESC   : LL_R6_DESC_BASE<"lld", GPR64Opnd, mem_simm9_exp, II_LLD>;
 class SCD_R6_DESC   : SC_R6_DESC_BASE<"scd", GPR64Opnd, II_SCD>;
 class SELEQZ64_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR64Opnd>;
 class SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>;
@@ -106,7 +106,7 @@ class JIC64_DESC : JMP_IDX_COMPACT_DESC_BASE<"jic", jmpoffset16, GPR64Opnd,
   list<Register> Defs = [AT];
 }
 
-class LL64_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9, II_LL>;
+class LL64_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9_exp, II_LL>;
 class SC64_R6_DESC : SC_R6_DESC_BASE<"sc", GPR32Opnd, II_SC>;
 
 class JR_HB64_R6_DESC : JR_HB_DESC_BASE<"jr.hb", GPR64Opnd> {

diff  --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index da8be7c640b8..3b626383d1d5 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -1140,6 +1140,13 @@ def simm12 : Operand<i32> {
   let DecoderMethod = "DecodeSimm12";
 }
 
+def mem_simm9_exp : mem_generic {
+  let MIOperandInfo = (ops ptr_rc, simm9);
+  let ParserMatchClass = MipsMemSimmPtrAsmOperand;
+  let OperandNamespace = "MipsII";
+  let OperandType = "OPERAND_MEM_SIMM9";
+}
+
 foreach I = {9, 10, 11, 12, 16} in
   def mem_simm # I : mem_generic {
     let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm" # I));

diff  --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h
index 298d056ce2c3..b389ba8938c4 100644
--- a/llvm/lib/Target/Mips/MipsTargetStreamer.h
+++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h
@@ -156,10 +156,6 @@ class MipsTargetStreamer : public MCTargetStreamer {
                               unsigned BaseReg, int64_t Offset,
                               function_ref<unsigned()> GetATReg, SMLoc IDLoc,
                               const MCSubtargetInfo *STI);
-  void emitSCWithSymOffset(unsigned Opcode, unsigned SrcReg, unsigned BaseReg,
-                           MCOperand &HiOperand, MCOperand &LoOperand,
-                           unsigned ATReg, SMLoc IDLoc,
-                           const MCSubtargetInfo *STI);
   void emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg, unsigned BaseReg,
                              int64_t Offset, unsigned TmpReg, SMLoc IDLoc,
                              const MCSubtargetInfo *STI);

diff  --git a/llvm/test/MC/Mips/ll-expansion.s b/llvm/test/MC/Mips/ll-expansion.s
new file mode 100644
index 000000000000..4653a33d7e78
--- /dev/null
+++ b/llvm/test/MC/Mips/ll-expansion.s
@@ -0,0 +1,406 @@
+# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips2 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS32
+# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips32 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS32
+# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips32r2 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS32
+# RUN: llvm-mc -filetype=obj -triple mipsn32 -mcpu=mips3 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPSN32
+# RUN: llvm-mc -filetype=obj -triple mipsn32 -mcpu=mips64r6 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPSN32R6
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64r2 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64
+# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips32r6 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS32R6
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64r6 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64R6
+
+ll $2, 128($sp)
+# MIPS32:         c3 a2 00 80  ll     $2, 128($sp)
+# MIPS32R6:       7f a2 40 36  ll     $2, 128($sp)
+# MIPSN32:        c3 a2 00 80  ll     $2, 128($sp)
+# MIPSN32R6:      7f a2 40 36  ll     $2, 128($sp)
+# MIPS64:         c3 a2 00 80  ll     $2, 128($sp)
+# MIPS64R6:       7f a2 40 36  ll     $2, 128($sp)
+
+ll $2, -128($sp)
+# MIPS32:         c3 a2 ff 80  ll     $2, -128($sp)
+# MIPS32R6:       7f a2 c0 36  ll     $2, -128($sp)
+# MIPSN32:        c3 a2 ff 80  ll     $2, -128($sp)
+# MIPSN32R6:      7f a2 c0 36  ll     $2, -128($sp)
+# MIPS64:         c3 a2 ff 80  ll     $2, -128($sp)
+# MIPS64R6:       7f a2 c0 36  ll     $2, -128($sp)
+
+ll $2, 256($sp)
+# MIPS32:         c3 a2 01 00  ll     $2, 256($sp)
+
+# MIPS32R6:       27 a2 01 00  addiu  $2, $sp, 256
+# MIPS32R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+# MIPSN32:        c3 a2 01 00  ll     $2, 256($sp)
+
+# MIPSN32R6:      27 a2 01 00  addiu  $2, $sp, 256
+# MIPSN32R6-NEXT: 7c 42 00 36  ll     $2, 0($2)
+
+# MIPS64:         c3 a2 01 00  ll     $2, 256($sp)
+
+# MIPS64R6:       67 a2 01 00  daddiu $2, $sp, 256
+# MIPS64R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+ll $2, -257($sp)
+# MIPS32:         c3 a2 fe ff  ll     $2, -257($sp)
+
+# MIPS32R6:       27 a2 fe ff  addiu  $2, $sp, -257
+# MIPS32R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+# MIPSN32:        c3 a2 fe ff  ll     $2, -257($sp)
+
+# MIPSN32R6:      27 a2 fe ff  addiu  $2, $sp, -257
+# MIPSN32R6-NEXT: 7c 42 00 36  ll     $2, 0($2)
+
+# MIPS64:         c3 a2 fe ff  ll     $2, -257($sp)
+
+# MIPS64R6:       67 a2 fe ff  daddiu $2, $sp, -257
+# MIPS64R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+ll $2, 32767($sp)
+# MIPS32:         c3 a2 7f ff  ll     $2, 32767($sp)
+
+# MIPS32R6:       27 a2 7f ff  addiu  $2, $sp, 32767
+# MIPS32R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+# MIPSN32:        c3 a2 7f ff  ll     $2, 32767($sp)
+
+# MIPSN32R6:      27 a2 7f ff  addiu  $2, $sp, 32767
+# MIPSN32R6-NEXT: 7c 42 00 36  ll     $2, 0($2)
+
+# MIPS64:         c3 a2 7f ff  ll     $2, 32767($sp)
+
+# MIPS64R6:       67 a2 7f ff  daddiu $2, $sp, 32767
+# MIPS64R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+ll $2, 32768($sp)
+# MIPS32:         3c 02 00 01  lui    $2, 1
+# MIPS32-NEXT:    00 5d 10 21  addu   $2, $2, $sp
+# MIPS32-NEXT:    c0 42 80 00  ll     $2, -32768($2)
+
+# MIPS32R6:       34 02 80 00  ori    $2, $zero, 32768
+# MIPS32R6-NEXT:  00 5d 10 21  addu   $2, $2, $sp
+# MIPS32R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+# MIPSN32:        3c 02 00 01  lui    $2, 1
+# MIPSN32-NEXT:   00 5d 10 21  addu   $2, $2, $sp
+# MIPSN32-NEXT:   c0 42 80 00  ll     $2, -32768($2)
+
+# MIPSN32R6:      34 02 80 00  ori    $2, $zero, 32768
+# MIPSN32R6-NEXT: 00 5d 10 21  addu   $2, $2, $sp
+# MIPSN32R6-NEXT: 7c 42 00 36  ll     $2, 0($2)
+
+# MIPS64:         3c 02 00 01  lui    $2, 1
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    c0 42 80 00  ll     $2, -32768($2)
+
+# MIPS64R6:       34 02 80 00  ori    $2, $zero, 32768
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+ll $2, -32768($sp)
+# MIPS32:         c3 a2 80 00  ll     $2, -32768($sp)
+
+# MIPS32R6:       27 a2 80 00  addiu  $2, $sp, -32768
+# MIPS32R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+# MIPSN32:        c3 a2 80 00  ll     $2, -32768($sp)
+
+# MIPSN32R6:      27 a2 80 00  addiu  $2, $sp, -32768
+# MIPSN32R6-NEXT: 7c 42 00 36  ll     $2, 0($2)
+
+# MIPS64:         c3 a2 80 00  ll     $2, -32768($sp)
+
+# MIPS64R6:       67 a2 80 00  daddiu $2, $sp, -32768
+# MIPS64R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+ll $2, -32769($sp)
+# MIPS32:         3c 02 ff ff  lui    $2, 65535
+# MIPS32-NEXT:    00 5d 10 21  addu   $2, $2, $sp
+# MIPS32-NEXT:    c0 42 7f ff  ll     $2, 32767($2)
+
+# MIPS32R6:       3c 02 ff ff  aui    $2, $zero, 65535
+# MIPS32R6-NEXT:  34 42 7f ff  ori    $2, $2, 32767
+# MIPS32R6-NEXT:  00 5d 10 21  addu   $2, $2, $sp
+# MIPS32R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+# MIPSN32:        3c 02 ff ff  lui    $2, 65535
+# MIPSN32-NEXT:   00 5d 10 21  addu   $2, $2, $sp
+# MIPSN32-NEXT:   c0 42 7f ff  ll     $2, 32767($2)
+
+# MIPSN32R6:      3c 02 ff ff  aui    $2, $zero, 65535
+# MIPSN32R6-NEXT: 34 42 7f ff  ori    $2, $2, 32767
+# MIPSN32R6-NEXT: 00 5d 10 21  addu   $2, $2, $sp
+# MIPSN32R6-NEXT: 7c 42 00 36  ll     $2, 0($2)
+
+# MIPS64:         3c 02 ff ff  lui    $2, 65535
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    c0 42 7f ff  ll     $2, 32767($2)
+
+# MIPS64R6:       3c 02 ff ff  aui    $2, $zero, 65535
+# MIPS64R6-NEXT:  34 42 7f ff  ori    $2, $2, 32767
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+ll $2, 655987($sp)
+# MIPS32:         3c 02 00 0a  lui    $2, 10
+# MIPS32-NEXT:    00 5d 10 21  addu   $2, $2, $sp
+# MIPS32-NEXT:    c0 42 02 73  ll     $2, 627($2)
+
+# MIPS32R6:       3c 02 00 0a  aui    $2, $zero, 10
+# MIPS32R6-NEXT:  34 42 02 73  ori    $2, $2, 627
+# MIPS32R6-NEXT:  00 5d 10 21  addu   $2, $2, $sp
+# MIPS32R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+# MIPSN32:        3c 02 00 0a  lui    $2, 10
+# MIPSN32-NEXT:   00 5d 10 21  addu   $2, $2, $sp
+# MIPSN32-NEXT:   c0 42 02 73  ll     $2, 627($2)
+
+# MIPSN32R6:      3c 02 00 0a  aui    $2, $zero, 10
+# MIPSN32R6-NEXT: 34 42 02 73  ori    $2, $2, 627
+# MIPSN32R6-NEXT: 00 5d 10 21  addu   $2, $2, $sp
+# MIPSN32R6-NEXT: 7c 42 00 36  ll     $2, 0($2)
+
+# MIPS64:         3c 02 00 0a  lui    $2, 10
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    c0 42 02 73  ll     $2, 627($2)
+
+# MIPS64R6:       3c 02 00 0a  aui    $2, $zero, 10
+# MIPS64R6-NEXT:  34 42 02 73  ori    $2, $2, 627
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+ll $2, -655987($sp)
+# MIPS32:         3c 02 ff f6  lui    $2, 65526
+# MIPS32-NEXT:    00 5d 10 21  addu   $2, $2, $sp
+# MIPS32-NEXT:    c0 42 fd 8d  ll     $2, -627($2)
+
+# MIPS32R6:       3c 02 ff f5  aui    $2, $zero, 65525
+# MIPS32R6-NEXT:  34 42 fd 8d  ori    $2, $2, 64909
+# MIPS32R6-NEXT:  00 5d 10 21  addu   $2, $2, $sp
+# MIPS32R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+# MIPSN32:        3c 02 ff f6  lui    $2, 65526
+# MIPSN32-NEXT:   00 5d 10 21  addu   $2, $2, $sp
+# MIPSN32-NEXT:   c0 42 fd 8d  ll     $2, -627($2)
+
+# MIPSN32R6:      3c 02 ff f5  aui    $2, $zero, 65525
+# MIPSN32R6-NEXT: 34 42 fd 8d  ori    $2, $2, 64909
+# MIPSN32R6-NEXT: 00 5d 10 21  addu   $2, $2, $sp
+# MIPSN32R6-NEXT: 7c 42 00 36  ll     $2, 0($2)
+
+# MIPS64:         3c 02 ff f6  lui    $2, 65526
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    c0 42 fd 8d  ll     $2, -627($2)
+
+# MIPS64R6:       3c 02 ff f5  aui    $2, $zero, 65525
+# MIPS64R6-NEXT:  34 42 fd 8d  ori    $2, $2, 64909
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 36  ll     $2, 0($2)
+
+ll $12, symbol
+# MIPS32:         3c 0c 00 00  lui    $12, 0
+# MIPS32-NEXT:               R_MIPS_HI16  symbol
+# MIPS32-NEXT:    c1 8c 00 00  ll     $12, 0($12)
+# MIPS32-NEXT:               R_MIPS_LO16  symbol
+
+# MIPS32R6:       3c 0c 00 00  aui    $12, $zero, 0
+# MIPS32R6-NEXT:             R_MIPS_HI16 symbol
+# MIPS32R6-NEXT:  25 8c 00 00  addiu  $12, $12, 0
+# MIPS32R6-NEXT:             R_MIPS_LO16 symbol
+# MIPS32R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+# MIPSN32:        3c 0c 00 00  lui    $12, 0
+# MIPSN32-NEXT:              R_MIPS_HI16  symbol
+# MIPSN32-NEXT:   c1 8c 00 00  ll     $12, 0($12)
+# MIPSN32-NEXT:              R_MIPS_LO16  symbol
+
+# MIPSN32R6:      3c 0c 00 00  aui    $12, $zero, 0
+# MIPSN32R6-NEXT:            R_MIPS_HI16 symbol
+# MIPSN32R6-NEXT: 25 8c 00 00  addiu  $12, $12, 0
+# MIPSN32R6-NEXT:            R_MIPS_LO16 symbol
+# MIPSN32R6-NEXT: 7d 8c 00 36  ll     $12, 0($12)
+
+# MIPS64:         3c 0c 00 00  lui    $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    c1 8c 00 00  ll     $12, 0($12)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+
+# MIPS64R6:       3c 0c 00 00  aui    $12, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  65 8c 00 00  daddiu $12, $12, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 0c 60 3c  dsll32 $12, $12, 0
+# MIPS64R6-NEXT:  01 81 60 2d  daddu  $12, $12, $1
+# MIPS64R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+ll $12, symbol($3)
+# MIPS32:         3c 0c 00 00  lui    $12, 0
+# MIPS32-NEXT:               R_MIPS_HI16  symbol
+# MIPS32-NEXT:    01 83 60 21  addu   $12, $12, $3
+# MIPS32-NEXT:    c1 8c 00 00  ll     $12, 0($12)
+# MIPS32-NEXT:               R_MIPS_LO16  symbol
+
+# MIPS32R6:       3c 0c 00 00  aui    $12, $zero, 0
+# MIPS32R6-NEXT:             R_MIPS_HI16 symbol
+# MIPS32R6-NEXT:  25 8c 00 00  addiu  $12, $12, 0
+# MIPS32R6-NEXT:             R_MIPS_LO16 symbol
+# MIPS32R6-NEXT:  01 83 60 21  addu   $12, $12, $3
+# MIPS32R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+# MIPSN32:        3c 0c 00 00  lui    $12, 0
+# MIPSN32-NEXT:              R_MIPS_HI16  symbol
+# MIPSN32-NEXT:   01 83 60 21  addu   $12, $12, $3
+# MIPSN32-NEXT:   c1 8c 00 00  ll     $12, 0($12)
+# MIPSN32-NEXT:              R_MIPS_LO16  symbol
+
+# MIPSN32R6:      3c 0c 00 00  aui    $12, $zero, 0
+# MIPSN32R6-NEXT:            R_MIPS_HI16 symbol
+# MIPSN32R6-NEXT: 25 8c 00 00  addiu  $12, $12, 0
+# MIPSN32R6-NEXT:            R_MIPS_LO16 symbol
+# MIPSN32R6-NEXT: 01 83 60 21  addu   $12, $12, $3
+# MIPSN32R6-NEXT: 7d 8c 00 36  ll     $12, 0($12)
+
+# MIPS64:         3c 0c 00 00  lui    $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    01 83 60 2d  daddu  $12, $12, $3
+# MIPS64-NEXT:    c1 8c 00 00  ll     $12, 0($12)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+
+# MIPS64R6:       3c 0c 00 00  aui    $12, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  65 8c 00 00  daddiu $12, $12, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 0c 60 3c  dsll32 $12, $12, 0
+# MIPS64R6-NEXT:  01 81 60 2d  daddu  $12, $12, $1
+# MIPS64R6-NEXT:  01 83 60 2d  daddu  $12, $12, $3
+# MIPS64R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+ll $12, symbol+8
+# MIPS32:         3c 0c 00 00  lui    $12, 0
+# MIPS32-NEXT:               R_MIPS_HI16  symbol
+# MIPS32-NEXT:    c1 8c 00 08  ll     $12, 8($12)
+# MIPS32-NEXT:               R_MIPS_LO16  symbol
+
+# MIPS32R6:       3c 0c 00 00  aui    $12, $zero, 0
+# MIPS32R6-NEXT:             R_MIPS_HI16 symbol
+# MIPS32R6-NEXT:  25 8c 00 08  addiu  $12, $12, 8
+# MIPS32R6-NEXT:             R_MIPS_LO16 symbol
+# MIPS32R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+# MIPSN32:        3c 0c 00 00  lui    $12, 0
+# MIPSN32-NEXT:              R_MIPS_HI16  symbol+0x8
+# MIPSN32-NEXT:   c1 8c 00 00  ll     $12, 0($12)
+# MIPSN32-NEXT:              R_MIPS_LO16  symbol+0x8
+
+# MIPSN32R6:      3c 0c 00 00  aui    $12, $zero, 0
+# MIPSN32R6-NEXT:            R_MIPS_HI16 symbol+0x8
+# MIPSN32R6-NEXT: 25 8c 00 00  addiu  $12, $12, 0
+# MIPSN32R6-NEXT:            R_MIPS_LO16 symbol+0x8
+# MIPSN32R6-NEXT: 7d 8c 00 36  ll     $12, 0($12)
+
+# MIPS64:         3c 0c 00 00  lui    $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    c1 8c 00 00  ll     $12, 0($12)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+
+# MIPS64R6:       3c 0c 00 00  aui    $12, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  65 8c 00 00  daddiu $12, $12, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  00 0c 60 3c  dsll32 $12, $12, 0
+# MIPS64R6-NEXT:  01 81 60 2d  daddu  $12, $12, $1
+# MIPS64R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+.option pic2
+
+ll $12, symbol
+# MIPS32:         8f 8c 00 00  lw     $12, 0($gp)
+# MIPS32-NEXT:               R_MIPS_GOT16 symbol
+# MIPS32-NEXT:    c1 8c 00 00  ll     $12, 0($12)
+
+# MIPS32R6:       8f 8c 00 00  lw     $12, 0($gp)
+# MIPS32R6-NEXT:             R_MIPS_GOT16 symbol
+# MIPS32R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+# MIPSN32:        8f 8c 00 00  lw     $12, 0($gp)
+# MIPSN32-NEXT:              R_MIPS_GOT_DISP symbol
+# MIPSN32-NEXT:   c1 8c 00 00  ll     $12, 0($12)
+
+# MIPSN32R6:      8f 8c 00 00  lw     $12, 0($gp)
+# MIPSN32R6-NEXT:            R_MIPS_GOT_DISP symbol
+# MIPSN32R6-NEXT: 7d 8c 00 36  ll     $12, 0($12)
+
+# MIPS64:         df 8c 00 00  ld     $12, 0($gp)
+# MIPS64-NEXT:               R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64-NEXT:    c1 8c 00 00  ll     $12, 0($12)
+
+# MIPS64R6:       df 8c 00 00  ld     $12, 0($gp)
+# MIPS64R6-NEXT:             R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+ll $12, symbol+8
+# MIPS32:         8f 8c 00 00  lw     $12, 0($gp)
+# MIPS32-NEXT:               R_MIPS_GOT16 symbol
+# MIPS32-NEXT:    c1 8c 00 08  ll     $12, 8($12)
+
+# MIPS32R6:       8f 8c 00 00  lw     $12, 0($gp)
+# MIPS32R6-NEXT:             R_MIPS_GOT16 symbol
+# MIPS32R6-NEXT:  25 8c 00 08  addiu  $12, $12, 8
+# MIPS32R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)
+
+# MIPSN32:        8f 8c 00 00  lw     $12, 0($gp)
+# MIPSN32-NEXT:              R_MIPS_GOT_DISP symbol
+# MIPSN32-NEXT:   c1 8c 00 08  ll     $12, 8($12)
+
+# MIPSN32R6:      8f 8c 00 00  lw     $12, 0($gp)
+# MIPSN32R6-NEXT:            R_MIPS_GOT_DISP symbol
+# MIPSN32R6-NEXT: 25 8c 00 08  addiu  $12, $12, 8
+# MIPSN32R6-NEXT: 7d 8c 00 36  ll     $12, 0($12)
+
+# MIPS64:         df 8c 00 00  ld     $12, 0($gp)
+# MIPS64-NEXT:               R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64-NEXT:    c1 8c 00 08  ll     $12, 8($12)
+
+# MIPS64R6:       df 8c 00 00  ld     $12, 0($gp)
+# MIPS64R6-NEXT:             R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64R6-NEXT:  65 8c 00 08  daddiu $12, $12, 8
+# MIPS64R6-NEXT:  7d 8c 00 36  ll     $12, 0($12)

diff  --git a/llvm/test/MC/Mips/lld-expansion.s b/llvm/test/MC/Mips/lld-expansion.s
new file mode 100644
index 000000000000..48755d59a240
--- /dev/null
+++ b/llvm/test/MC/Mips/lld-expansion.s
@@ -0,0 +1,188 @@
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64r6 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64R6
+
+lld $2, 128($sp)
+# MIPS64:         d3 a2 00 80  lld    $2, 128($sp)
+# MIPS64R6:       7f a2 40 37  lld    $2, 128($sp)
+
+lld $2, -128($sp)
+# MIPS64:         d3 a2 ff 80  lld    $2, -128($sp)
+# MIPS64R6:       7f a2 c0 37  lld    $2, -128($sp)
+
+lld $2, 256($sp)
+# MIPS64:         d3 a2 01 00  lld    $2, 256($sp)
+
+# MIPS64R6:       67 a2 01 00  daddiu $2, $sp, 256
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $2, -257($sp)
+# MIPS64:         d3 a2 fe ff  lld    $2, -257($sp)
+
+# MIPS64R6:       67 a2 fe ff  daddiu $2, $sp, -257
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $2, 32767($sp)
+# MIPS64:         d3 a2 7f ff  lld    $2, 32767($sp)
+
+# MIPS64R6:       67 a2 7f ff  daddiu $2, $sp, 32767
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $2, 32768($sp)
+# MIPS64:         3c 02 00 01  lui    $2, 1
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    d0 42 80 00  lld    $2, -32768($2)
+
+# MIPS64R6:       34 02 80 00  ori    $2, $zero, 32768
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $2, -32768($sp)
+# MIPS64:         d3 a2 80 00  lld    $2, -32768($sp)
+
+# MIPS64R6:       67 a2 80 00  daddiu $2, $sp, -32768
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $2, -32769($sp)
+# MIPS64:         3c 02 ff ff  lui    $2, 65535
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    d0 42 7f ff  lld    $2, 32767($2)
+
+# MIPS64R6:       3c 02 ff ff  aui    $2, $zero, 65535
+# MIPS64R6-NEXT:  34 42 7f ff  ori    $2, $2, 32767
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $2, 2147483648($sp)
+# MIPS64:         34 02 80 00  ori    $2, $zero, 32768
+# MIPS64-NEXT:    00 02 14 38  dsll   $2, $2, 16
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    d0 42 00 00  lld    $2, 0($2)
+
+# MIPS64R6:       34 02 80 00  ori    $2, $zero, 32768
+# MIPS64R6-NEXT:  00 02 14 38  dsll   $2, $2, 16
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $2, -2147483648($sp)
+# MIPS64:         3c 02 80 00  lui    $2, 32768
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    d0 42 00 00  lld    $2, 0($2)
+
+# MIPS64R6:       3c 02 80 00  aui    $2, $zero, 32768
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $2, 9223372036853775808($sp)
+# MIPS64:         3c 02 7f ff  lui    $2, 32767
+# MIPS64-NEXT:    34 42 ff ff  ori    $2, $2, 65535
+# MIPS64-NEXT:    00 02 14 38  dsll   $2, $2, 16
+# MIPS64-NEXT:    34 42 ff f1  ori    $2, $2, 65521
+# MIPS64-NEXT:    00 02 14 38  dsll   $2, $2, 16
+# MIPS64-NEXT:    00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64-NEXT:    d0 42 bd c0  lld    $2, -16960($2)
+
+# MIPS64R6:       3c 02 7f ff  aui    $2, $zero, 32767
+# MIPS64R6-NEXT:  34 42 ff ff  ori    $2, $2, 65535
+# MIPS64R6-NEXT:  00 02 14 38  dsll   $2, $2, 16
+# MIPS64R6-NEXT:  34 42 ff f0  ori    $2, $2, 65520
+# MIPS64R6-NEXT:  00 02 14 38  dsll   $2, $2, 16
+# MIPS64R6-NEXT:  34 42 bd c0  ori    $2, $2, 48576
+# MIPS64R6-NEXT:  00 5d 10 2d  daddu  $2, $2, $sp
+# MIPS64R6-NEXT:  7c 42 00 37  lld    $2, 0($2)
+
+lld $12, symbol
+# MIPS64:         3c 0c 00 00  lui    $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    d1 8c 00 00  lld    $12, 0($12)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+
+# MIPS64R6:       3c 0c 00 00  aui    $12, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  65 8c 00 00  daddiu $12, $12, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 0c 60 3c  dsll32 $12, $12, 0
+# MIPS64R6-NEXT:  01 81 60 2d  daddu  $12, $12, $1
+# MIPS64R6-NEXT:  7d 8c 00 37  lld    $12, 0($12)
+
+lld $12, symbol($3)
+# MIPS64:         3c 0c 00 00  lui    $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    01 83 60 2d  daddu  $12, $12, $3
+# MIPS64-NEXT:    d1 8c 00 00  lld    $12, 0($12)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+
+# MIPS64R6-NEXT:  3c 0c 00 00  aui    $12, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  65 8c 00 00  daddiu $12, $12, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 0c 60 3c  dsll32 $12, $12, 0
+# MIPS64R6-NEXT:  01 81 60 2d  daddu  $12, $12, $1
+# MIPS64R6-NEXT:  01 83 60 2d  daddu  $12, $12, $3
+# MIPS64R6-NEXT:  7d 8c 00 37  lld    $12, 0($12)
+
+lld $12, symbol+8
+# MIPS64:         3c 0c 00 00  lui    $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    65 8c 00 00  daddiu $12, $12, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    00 0c 64 38  dsll   $12, $12, 16
+# MIPS64-NEXT:    d1 8c 00 00  lld    $12, 0($12)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+
+# MIPS64R6-NEXT:  3c 0c 00 00  aui    $12, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  65 8c 00 00  daddiu $12, $12, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  00 0c 60 3c  dsll32 $12, $12, 0
+# MIPS64R6-NEXT:  01 81 60 2d  daddu  $12, $12, $1
+# MIPS64R6-NEXT:  7d 8c 00 37  lld    $12, 0($12)
+
+.option pic2
+
+lld $12, symbol
+# MIPS64:         df 8c 00 00  ld     $12, 0($gp)
+# MIPS64-NEXT:               R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64-NEXT:    d1 8c 00 00  lld    $12, 0($12)
+
+# MIPS64R6:       df 8c 00 00  ld     $12, 0($gp)
+# MIPS64R6-NEXT:             R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64R6-NEXT:  7d 8c 00 37  lld    $12, 0($12)
+
+lld $12, symbol+8
+# MIPS64:         df 8c 00 00  ld     $12, 0($gp)
+# MIPS64-NEXT:               R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64-NEXT:    d1 8c 00 08  lld    $12, 8($12)
+
+# MIPS64R6:       df 8c 00 00  ld     $12, 0($gp)
+# MIPS64R6-NEXT:             R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64R6-NEXT:  65 8c 00 08  daddiu $12, $12, 8
+# MIPS64R6-NEXT:  7d 8c 00 37  lld    $12, 0($12)

diff  --git a/llvm/test/MC/Mips/sc-expansion.s b/llvm/test/MC/Mips/sc-expansion.s
index 76b30f174f9e..b407f7aaf570 100644
--- a/llvm/test/MC/Mips/sc-expansion.s
+++ b/llvm/test/MC/Mips/sc-expansion.s
@@ -1,48 +1,406 @@
 # RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips2 %s -o - \
-# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS32
 # RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips32 %s -o - \
-# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS32
 # RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips32r2 %s -o - \
-# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS
-# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips3 %s -o - \
-# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS
-# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips64 %s -o - \
-# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS
-# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips64r2 %s -o - \
-# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS32
+# RUN: llvm-mc -filetype=obj -triple mipsn32 -mcpu=mips3 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPSN32
+# RUN: llvm-mc -filetype=obj -triple mipsn32 -mcpu=mips64r6 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPSN32R6
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64r2 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64
 # RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips32r6 %s -o - \
-# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPSR6
-# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips64r6 %s -o - \
-# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPSR6
-
-# MIPS:         e0 6c 00 00    sc   $12, 0($3)
-# MIPSR6:       7c 6c 00 26    sc   $12, 0($3)
-sc $12, 0($3)
-
-# MIPS:         e0 6c 00 04    sc   $12, 4($3)
-# MIPSR6:       7c 6c 02 26    sc   $12, 4($3)
-sc $12, 4($3)
-
-# MIPS:         3c 01 00 00    lui  $1, 0
-# MIPS:                    R_MIPS_HI16  symbol
-# MIPS:         e0 2c 00 00    sc   $12, 0($1)
-# MIPS:                    R_MIPS_LO16  symbol
-
-# MIPSR6:       3c 01 00 00     aui    $1, $zero, 0
-# MIPSR6:			             R_MIPS_HI16	symbol
-# MIPSR6:       24 21 00 00     addiu  $1, $1, 0
-# MIPSR6:			             R_MIPS_LO16	symbol
-# MIPSR6:       7c 2c 00 26     sc     $12, 0($1)
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS32R6
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64r6 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64R6
+
+sc $2, 128($sp)
+# MIPS32:         e3 a2 00 80  sc     $2, 128($sp)
+# MIPS32R6:       7f a2 40 26  sc     $2, 128($sp)
+# MIPSN32:        e3 a2 00 80  sc     $2, 128($sp)
+# MIPSN32R6:      7f a2 40 26  sc     $2, 128($sp)
+# MIPS64:         e3 a2 00 80  sc     $2, 128($sp)
+# MIPS64R6:       7f a2 40 26  sc     $2, 128($sp)
+
+sc $2, -128($sp)
+# MIPS32:         e3 a2 ff 80  sc     $2, -128($sp)
+# MIPS32R6:       7f a2 c0 26  sc     $2, -128($sp)
+# MIPSN32:        e3 a2 ff 80  sc     $2, -128($sp)
+# MIPSN32R6:      7f a2 c0 26  sc     $2, -128($sp)
+# MIPS64:         e3 a2 ff 80  sc     $2, -128($sp)
+# MIPS64R6:       7f a2 c0 26  sc     $2, -128($sp)
+
+sc $2, 256($sp)
+# MIPS32:         e3 a2 01 00  sc     $2, 256($sp)
+
+# MIPS32R6:       27 a1 01 00  addiu  $1, $sp, 256
+# MIPS32R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+# MIPSN32:        e3 a2 01 00  sc     $2, 256($sp)
+
+# MIPSN32R6:      27 a1 01 00  addiu  $1, $sp, 256
+# MIPSN32R6-NEXT: 7c 22 00 26  sc     $2, 0($1)
+
+# MIPS64:         e3 a2 01 00  sc     $2, 256($sp)
+
+# MIPS64R6:       67 a1 01 00  daddiu $1, $sp, 256
+# MIPS64R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+sc $2, -257($sp)
+# MIPS32:         e3 a2 fe ff  sc     $2, -257($sp)
+
+# MIPS32R6:       27 a1 fe ff  addiu  $1, $sp, -257
+# MIPS32R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+# MIPSN32:        e3 a2 fe ff  sc     $2, -257($sp)
+
+# MIPSN32R6:      27 a1 fe ff  addiu  $1, $sp, -257
+# MIPSN32R6-NEXT: 7c 22 00 26  sc     $2, 0($1)
+
+# MIPS64:         e3 a2 fe ff  sc     $2, -257($sp)
+
+# MIPS64R6:       67 a1 fe ff  daddiu $1, $sp, -257
+# MIPS64R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+sc $2, 32767($sp)
+# MIPS32:         e3 a2 7f ff  sc     $2, 32767($sp)
+
+# MIPS32R6:       27 a1 7f ff  addiu  $1, $sp, 32767
+# MIPS32R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+# MIPSN32:        e3 a2 7f ff  sc     $2, 32767($sp)
+
+# MIPSN32R6:      27 a1 7f ff  addiu  $1, $sp, 32767
+# MIPSN32R6-NEXT: 7c 22 00 26  sc     $2, 0($1)
+
+# MIPS64:         e3 a2 7f ff  sc     $2, 32767($sp)
+
+# MIPS64R6:       67 a1 7f ff  daddiu $1, $sp, 32767
+# MIPS64R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+sc $2, 32768($sp)
+# MIPS32:         3c 01 00 01  lui    $1, 1
+# MIPS32-NEXT:    00 3d 08 21  addu   $1, $1, $sp
+# MIPS32-NEXT:    e0 22 80 00  sc     $2, -32768($1)
+
+# MIPS32R6:       34 01 80 00  ori    $1, $zero, 32768
+# MIPS32R6-NEXT:  00 3d 08 21  addu   $1, $1, $sp
+# MIPS32R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+# MIPSN32:        3c 01 00 01  lui    $1, 1
+# MIPSN32-NEXT:   00 3d 08 21  addu   $1, $1, $sp
+# MIPSN32-NEXT:   e0 22 80 00  sc     $2, -32768($1)
+
+# MIPSN32R6:      34 01 80 00  ori    $1, $zero, 32768
+# MIPSN32R6-NEXT: 00 3d 08 21  addu   $1, $1, $sp
+# MIPSN32R6-NEXT: 7c 22 00 26  sc     $2, 0($1)
+
+# MIPS64:         3c 01 00 01  lui    $1, 1
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    e0 22 80 00  sc     $2, -32768($1)
+
+# MIPS64R6:       34 01 80 00  ori    $1, $zero, 32768
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+sc $2, -32768($sp)
+# MIPS32:         e3 a2 80 00  sc     $2, -32768($sp)
+
+# MIPS32R6:       27 a1 80 00  addiu  $1, $sp, -32768
+# MIPS32R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+# MIPSN32:        e3 a2 80 00  sc     $2, -32768($sp)
+
+# MIPSN32R6:      27 a1 80 00  addiu  $1, $sp, -32768
+# MIPSN32R6-NEXT: 7c 22 00 26  sc     $2, 0($1)
+
+# MIPS64:         e3 a2 80 00  sc     $2, -32768($sp)
+
+# MIPS64R6:       67 a1 80 00  daddiu $1, $sp, -32768
+# MIPS64R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+sc $2, -32769($sp)
+# MIPS32:         3c 01 ff ff  lui    $1, 65535
+# MIPS32-NEXT:    00 3d 08 21  addu   $1, $1, $sp
+# MIPS32-NEXT:    e0 22 7f ff  sc     $2, 32767($1)
+
+# MIPS32R6:       3c 01 ff ff  aui    $1, $zero, 65535
+# MIPS32R6-NEXT:  34 21 7f ff  ori    $1, $1, 32767
+# MIPS32R6-NEXT:  00 3d 08 21  addu   $1, $1, $sp
+# MIPS32R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+# MIPSN32:        3c 01 ff ff  lui    $1, 65535
+# MIPSN32-NEXT:   00 3d 08 21  addu   $1, $1, $sp
+# MIPSN32-NEXT:   e0 22 7f ff  sc     $2, 32767($1)
+
+# MIPSN32R6:      3c 01 ff ff  aui    $1, $zero, 65535
+# MIPSN32R6-NEXT: 34 21 7f ff  ori    $1, $1, 32767
+# MIPSN32R6-NEXT: 00 3d 08 21  addu   $1, $1, $sp
+# MIPSN32R6-NEXT: 7c 22 00 26  sc     $2, 0($1)
+
+# MIPS64:         3c 01 ff ff  lui    $1, 65535
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    e0 22 7f ff  sc     $2, 32767($1)
+
+# MIPS64R6:       3c 01 ff ff  aui    $1, $zero, 65535
+# MIPS64R6-NEXT:  34 21 7f ff  ori    $1, $1, 32767
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+sc $2, 655987($sp)
+# MIPS32:         3c 01 00 0a  lui    $1, 10
+# MIPS32-NEXT:    00 3d 08 21  addu   $1, $1, $sp
+# MIPS32-NEXT:    e0 22 02 73  sc     $2, 627($1)
+
+# MIPS32R6:       3c 01 00 0a  aui    $1, $zero, 10
+# MIPS32R6-NEXT:  34 21 02 73  ori    $1, $1, 627
+# MIPS32R6-NEXT:  00 3d 08 21  addu   $1, $1, $sp
+# MIPS32R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+# MIPSN32:        3c 01 00 0a  lui    $1, 10
+# MIPSN32-NEXT:   00 3d 08 21  addu   $1, $1, $sp
+# MIPSN32-NEXT:   e0 22 02 73  sc     $2, 627($1)
+
+# MIPSN32R6:      3c 01 00 0a  aui    $1, $zero, 10
+# MIPSN32R6-NEXT: 34 21 02 73  ori    $1, $1, 627
+# MIPSN32R6-NEXT: 00 3d 08 21  addu   $1, $1, $sp
+# MIPSN32R6-NEXT: 7c 22 00 26  sc     $2, 0($1)
+
+# MIPS64:         3c 01 00 0a  lui    $1, 10
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    e0 22 02 73  sc     $2, 627($1)
+
+# MIPS64R6:       3c 01 00 0a  aui    $1, $zero, 10
+# MIPS64R6-NEXT:  34 21 02 73  ori    $1, $1, 627
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+sc $2, -655987($sp)
+# MIPS32:         3c 01 ff f6  lui    $1, 65526
+# MIPS32-NEXT:    00 3d 08 21  addu   $1, $1, $sp
+# MIPS32-NEXT:    e0 22 fd 8d  sc     $2, -627($1)
+
+# MIPS32R6:       3c 01 ff f5  aui    $1, $zero, 65525
+# MIPS32R6-NEXT:  34 21 fd 8d  ori    $1, $1, 64909
+# MIPS32R6-NEXT:  00 3d 08 21  addu   $1, $1, $sp
+# MIPS32R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+# MIPSN32:        3c 01 ff f6  lui    $1, 65526
+# MIPSN32-NEXT:   00 3d 08 21  addu   $1, $1, $sp
+# MIPSN32-NEXT:   e0 22 fd 8d  sc     $2, -627($1)
+
+# MIPSN32R6:      3c 01 ff f5  aui    $1, $zero, 65525
+# MIPSN32R6-NEXT: 34 21 fd 8d  ori    $1, $1, 64909
+# MIPSN32R6-NEXT: 00 3d 08 21  addu   $1, $1, $sp
+# MIPSN32R6-NEXT: 7c 22 00 26  sc     $2, 0($1)
+
+# MIPS64:         3c 01 ff f6  lui    $1, 65526
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    e0 22 fd 8d  sc     $2, -627($1)
+
+# MIPS64R6:       3c 01 ff f5  aui    $1, $zero, 65525
+# MIPS64R6-NEXT:  34 21 fd 8d  ori    $1, $1, 64909
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 26  sc     $2, 0($1)
+
+sc $12, symbol
+# MIPS32:         3c 01 00 00  lui    $1, 0
+# MIPS32-NEXT:               R_MIPS_HI16  symbol
+# MIPS32-NEXT:    e0 2c 00 00  sc     $12, 0($1)
+# MIPS32-NEXT:               R_MIPS_LO16  symbol
+
+# MIPS32R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS32R6-NEXT:             R_MIPS_HI16 symbol
+# MIPS32R6-NEXT:  24 21 00 00  addiu  $1, $1, 0
+# MIPS32R6-NEXT:             R_MIPS_LO16 symbol
+# MIPS32R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+# MIPSN32:        3c 01 00 00  lui    $1, 0
+# MIPSN32-NEXT:              R_MIPS_HI16  symbol
+# MIPSN32-NEXT:   e0 2c 00 00  sc     $12, 0($1)
+# MIPSN32-NEXT:              R_MIPS_LO16  symbol
+
+# MIPSN32R6:      3c 01 00 00  aui    $1, $zero, 0
+# MIPSN32R6-NEXT:            R_MIPS_HI16 symbol
+# MIPSN32R6-NEXT: 24 21 00 00  addiu  $1, $1, 0
+# MIPSN32R6-NEXT:            R_MIPS_LO16 symbol
+# MIPSN32R6-NEXT: 7c 2c 00 26  sc     $12, 0($1)
+
+# MIPS64:         3c 01 00 00  lui    $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    e0 2c 00 00  sc     $12, 0($1)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+
+# MIPS64R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+sc $12, symbol($3)
+# MIPS32:         3c 01 00 00  lui    $1, 0
+# MIPS32-NEXT:               R_MIPS_HI16  symbol
+# MIPS32-NEXT:    00 23 08 21  addu   $1, $1, $3
+# MIPS32-NEXT:    e0 2c 00 00  sc     $12, 0($1)
+# MIPS32-NEXT:               R_MIPS_LO16  symbol
+
+# MIPS32R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS32R6-NEXT:             R_MIPS_HI16 symbol
+# MIPS32R6-NEXT:  24 21 00 00  addiu  $1, $1, 0
+# MIPS32R6-NEXT:             R_MIPS_LO16 symbol
+# MIPS32R6-NEXT:  00 23 08 21  addu   $1, $1, $3
+# MIPS32R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+# MIPSN32:        3c 01 00 00  lui    $1, 0
+# MIPSN32-NEXT:              R_MIPS_HI16  symbol
+# MIPSN32-NEXT:   00 23 08 21  addu   $1, $1, $3
+# MIPSN32-NEXT:   e0 2c 00 00  sc     $12, 0($1)
+# MIPSN32-NEXT:              R_MIPS_LO16  symbol
+
+# MIPSN32R6:      3c 01 00 00  aui    $1, $zero, 0
+# MIPSN32R6-NEXT:            R_MIPS_HI16 symbol
+# MIPSN32R6-NEXT: 24 21 00 00  addiu  $1, $1, 0
+# MIPSN32R6-NEXT:            R_MIPS_LO16 symbol
+# MIPSN32R6-NEXT: 00 23 08 21  addu   $1, $1, $3
+# MIPSN32R6-NEXT: 7c 2c 00 26  sc     $12, 0($1)
+
+# MIPS64:         3c 01 00 00  lui    $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    00 23 08 2d  daddu  $1, $1, $3
+# MIPS64-NEXT:    e0 2c 00 00  sc     $12, 0($1)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+
+# MIPS64R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 23 08 2d  daddu  $1, $1, $3
+# MIPS64R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+sc $12, symbol+8
+# MIPS32:         3c 01 00 00  lui    $1, 0
+# MIPS32-NEXT:               R_MIPS_HI16  symbol
+# MIPS32-NEXT:    e0 2c 00 08  sc     $12, 8($1)
+# MIPS32-NEXT:               R_MIPS_LO16  symbol
+
+# MIPS32R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS32R6-NEXT:             R_MIPS_HI16 symbol
+# MIPS32R6-NEXT:  24 21 00 08  addiu  $1, $1, 8
+# MIPS32R6-NEXT:             R_MIPS_LO16 symbol
+# MIPS32R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+# MIPSN32:        3c 01 00 00  lui    $1, 0
+# MIPSN32-NEXT:              R_MIPS_HI16  symbol+0x8
+# MIPSN32-NEXT:   e0 2c 00 00  sc     $12, 0($1)
+# MIPSN32-NEXT:              R_MIPS_LO16  symbol+0x8
+
+# MIPSN32R6:      3c 01 00 00  aui    $1, $zero, 0
+# MIPSN32R6-NEXT:            R_MIPS_HI16 symbol+0x8
+# MIPSN32R6-NEXT: 24 21 00 00  addiu  $1, $1, 0
+# MIPSN32R6-NEXT:            R_MIPS_LO16 symbol+0x8
+# MIPSN32R6-NEXT: 7c 2c 00 26  sc     $12, 0($1)
+
+# MIPS64:         3c 01 00 00  lui    $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    e0 2c 00 00  sc     $12, 0($1)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+
+# MIPS64R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+.option pic2
+
 sc $12, symbol
+# MIPS32:         8f 81 00 00  lw     $1, 0($gp)
+# MIPS32-NEXT:               R_MIPS_GOT16 symbol
+# MIPS32-NEXT:    e0 2c 00 00  sc     $12, 0($1)
+
+# MIPS32R6:       8f 81 00 00  lw     $1, 0($gp)
+# MIPS32R6-NEXT:             R_MIPS_GOT16 symbol
+# MIPS32R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+# MIPSN32:        8f 81 00 00  lw     $1, 0($gp)
+# MIPSN32-NEXT:              R_MIPS_GOT_DISP symbol
+# MIPSN32-NEXT:   e0 2c 00 00  sc     $12, 0($1)
+
+# MIPSN32R6:      8f 81 00 00  lw     $1, 0($gp)
+# MIPSN32R6-NEXT:            R_MIPS_GOT_DISP symbol
+# MIPSN32R6-NEXT: 7c 2c 00 26  sc     $12, 0($1)
+
+# MIPS64:         df 81 00 00  ld     $1, 0($gp)
+# MIPS64-NEXT:               R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64-NEXT:    e0 2c 00 00  sc     $12, 0($1)
+
+# MIPS64R6:       df 81 00 00  ld     $1, 0($gp)
+# MIPS64R6-NEXT:             R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+sc $12, symbol+8
+# MIPS32:         8f 81 00 00  lw     $1, 0($gp)
+# MIPS32-NEXT:               R_MIPS_GOT16 symbol
+# MIPS32-NEXT:    e0 2c 00 08  sc     $12, 8($1)
+
+# MIPS32R6:       8f 81 00 00  lw     $1, 0($gp)
+# MIPS32R6-NEXT:             R_MIPS_GOT16 symbol
+# MIPS32R6-NEXT:  24 21 00 08  addiu  $1, $1, 8
+# MIPS32R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)
+
+# MIPSN32:        8f 81 00 00  lw     $1, 0($gp)
+# MIPSN32-NEXT:              R_MIPS_GOT_DISP symbol
+# MIPSN32-NEXT:   e0 2c 00 08  sc     $12, 8($1)
+
+# MIPSN32R6:      8f 81 00 00  lw     $1, 0($gp)
+# MIPSN32R6-NEXT:            R_MIPS_GOT_DISP symbol
+# MIPSN32R6-NEXT: 24 21 00 08  addiu  $1, $1, 8
+# MIPSN32R6-NEXT: 7c 2c 00 26  sc     $12, 0($1)
+
+# MIPS64:         df 81 00 00  ld     $1, 0($gp)
+# MIPS64-NEXT:               R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64-NEXT:    e0 2c 00 08  sc     $12, 8($1)
 
-# MIPS:         3c 01 00 00    lui  $1, 0
-# MIPS:                    R_MIPS_HI16  symbol
-# MIPS:         e0 2c 00 08    sc   $12, 8($1)
-# MIPS:                    R_MIPS_LO16  symbol
-
-# MIPSR6:       3c 01 00 00     aui    $1, $zero, 0
-# MIPSR6:                  R_MIPS_HI16	symbol
-# MIPSR6:       24 21 00 08     addiu  $1, $1, 8
-# MIPSR6:                  R_MIPS_LO16	symbol
-# MIPSR6:       7c 2c 00 26     sc     $12, 0($1)
-sc $12, symbol + 8
+# MIPS64R6:       df 81 00 00  ld     $1, 0($gp)
+# MIPS64R6-NEXT:             R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64R6-NEXT:  64 21 00 08  daddiu $1, $1, 8
+# MIPS64R6-NEXT:  7c 2c 00 26  sc     $12, 0($1)

diff  --git a/llvm/test/MC/Mips/scd-expansion.s b/llvm/test/MC/Mips/scd-expansion.s
new file mode 100644
index 000000000000..54a3baa5d68f
--- /dev/null
+++ b/llvm/test/MC/Mips/scd-expansion.s
@@ -0,0 +1,188 @@
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64
+# RUN: llvm-mc -filetype=obj -triple mips64 -mcpu=mips64r6 %s -o - \
+# RUN:   | llvm-objdump -d -r - | FileCheck %s --check-prefix=MIPS64R6
+
+scd $2, 128($sp)
+# MIPS64:         f3 a2 00 80  scd    $2, 128($sp)
+# MIPS64R6:       7f a2 40 27  scd    $2, 128($sp)
+
+scd $2, -128($sp)
+# MIPS64:         f3 a2 ff 80  scd    $2, -128($sp)
+# MIPS64R6:       7f a2 c0 27  scd    $2, -128($sp)
+
+scd $2, 256($sp)
+# MIPS64:         f3 a2 01 00  scd    $2, 256($sp)
+
+# MIPS64R6:       67 a1 01 00  daddiu $1, $sp, 256
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $2, -257($sp)
+# MIPS64:         f3 a2 fe ff  scd    $2, -257($sp)
+
+# MIPS64R6:       67 a1 fe ff  daddiu $1, $sp, -257
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $2, 32767($sp)
+# MIPS64:         f3 a2 7f ff  scd    $2, 32767($sp)
+
+# MIPS64R6:       67 a1 7f ff  daddiu $1, $sp, 32767
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $2, 32768($sp)
+# MIPS64:         3c 01 00 01  lui    $1, 1
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    f0 22 80 00  scd    $2, -32768($1)
+
+# MIPS64R6:       34 01 80 00  ori    $1, $zero, 32768
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $2, -32768($sp)
+# MIPS64:         f3 a2 80 00  scd    $2, -32768($sp)
+
+# MIPS64R6:       67 a1 80 00  daddiu $1, $sp, -32768
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $2, -32769($sp)
+# MIPS64:         3c 01 ff ff  lui    $1, 65535
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    f0 22 7f ff  scd    $2, 32767($1)
+
+# MIPS64R6:       3c 01 ff ff  aui    $1, $zero, 65535
+# MIPS64R6-NEXT:  34 21 7f ff  ori    $1, $1, 32767
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $2, 2147483648($sp)
+# MIPS64:         34 01 80 00  ori    $1, $zero, 32768
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    f0 22 00 00  scd    $2, 0($1)
+
+# MIPS64R6:       34 01 80 00  ori    $1, $zero, 32768
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $2, -2147483648($sp)
+# MIPS64:         3c 01 80 00  lui    $1, 32768
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    f0 22 00 00  scd    $2, 0($1)
+
+# MIPS64R6:       3c 01 80 00  aui    $1, $zero, 32768
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $2, 9223372036853775808($sp)
+# MIPS64:         3c 01 7f ff  lui    $1, 32767
+# MIPS64-NEXT:    34 21 ff ff  ori    $1, $1, 65535
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    34 21 ff f1  ori    $1, $1, 65521
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64-NEXT:    f0 22 bd c0  scd    $2, -16960($1)
+
+# MIPS64R6:       3c 01 7f ff  aui    $1, $zero, 32767
+# MIPS64R6-NEXT:  34 21 ff ff  ori    $1, $1, 65535
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  34 21 ff f0  ori    $1, $1, 65520
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  34 21 bd c0  ori    $1, $1, 48576
+# MIPS64R6-NEXT:  00 3d 08 2d  daddu  $1, $1, $sp
+# MIPS64R6-NEXT:  7c 22 00 27  scd    $2, 0($1)
+
+scd $12, symbol
+# MIPS64:         3c 01 00 00  lui    $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    f0 2c 00 00  scd    $12, 0($1)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+
+# MIPS64R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  7c 2c 00 27  scd    $12, 0($1)
+
+scd $12, symbol($3)
+# MIPS64:         3c 01 00 00  lui    $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    00 23 08 2d  daddu  $1, $1, $3
+# MIPS64-NEXT:    f0 2c 00 00  scd    $12, 0($1)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+
+# MIPS64R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol
+# MIPS64R6-NEXT:  00 23 08 2d  daddu  $1, $1, $3
+# MIPS64R6-NEXT:  7c 2c 00 27  scd    $12, 0($1)
+
+scd $12, symbol+8
+# MIPS64:         3c 01 00 00  lui    $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    64 21 00 00  daddiu $1, $1, 0
+# MIPS64-NEXT:               R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64-NEXT:    00 01 0c 38  dsll   $1, $1, 16
+# MIPS64-NEXT:    f0 2c 00 00  scd    $12, 0($1)
+# MIPS64-NEXT:               R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+
+# MIPS64R6:       3c 01 00 00  aui    $1, $zero, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHEST/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HIGHER/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_HI16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  00 01 0c 38  dsll   $1, $1, 16
+# MIPS64R6-NEXT:  64 21 00 00  daddiu $1, $1, 0
+# MIPS64R6-NEXT:             R_MIPS_LO16/R_MIPS_NONE/R_MIPS_NONE  symbol+0x8
+# MIPS64R6-NEXT:  7c 2c 00 27  scd    $12, 0($1)
+
+.option pic2
+
+scd $12, symbol
+# MIPS64:         df 81 00 00  ld     $1, 0($gp)
+# MIPS64-NEXT:               R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64-NEXT:    f0 2c 00 00  scd    $12, 0($1)
+
+# MIPS64R6:       df 81 00 00  ld     $1, 0($gp)
+# MIPS64R6-NEXT:             R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64R6-NEXT:  7c 2c 00 27  scd    $12, 0($1)
+
+scd $12, symbol+8
+# MIPS64:         df 81 00 00  ld     $1, 0($gp)
+# MIPS64-NEXT:               R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64-NEXT:    f0 2c 00 08  scd    $12, 8($1)
+
+# MIPS64R6:       df 81 00 00  ld     $1, 0($gp)
+# MIPS64R6-NEXT:             R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE symbol
+# MIPS64R6-NEXT:  64 21 00 08  daddiu $1, $1, 8
+# MIPS64R6-NEXT:  7c 2c 00 27  scd    $12, 0($1)


        


More information about the llvm-commits mailing list