[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