summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches')
-rw-r--r--contrib/llvm/patches/README.TXT8
-rw-r--r--contrib/llvm/patches/patch-01-freebsd-kprintf.diff10
-rw-r--r--contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff10
-rw-r--r--contrib/llvm/patches/patch-08-llvm-r227089-fix-mips-i128.diff1950
-rw-r--r--contrib/llvm/patches/patch-08-llvm-r230348-arm-fix-bad-ha.diff (renamed from contrib/llvm/patches/patch-10-llvm-r230348-arm-fix-bad-ha.diff)8
-rw-r--r--contrib/llvm/patches/patch-09-clang-r227115-constantarraytype.diff (renamed from contrib/llvm/patches/patch-12-clang-r227115-constantarraytype.diff)0
-rw-r--r--contrib/llvm/patches/patch-09-llvm-r230058-indirectbrs-assert.diff55
-rw-r--r--contrib/llvm/patches/patch-11-llvm-r231227-aarch64-tls-relocs.diff811
-rw-r--r--contrib/llvm/patches/patch-13-llvm-r229911-uleb128-commas.diff77
9 files changed, 18 insertions, 2911 deletions
diff --git a/contrib/llvm/patches/README.TXT b/contrib/llvm/patches/README.TXT
index f3fc208..7bc26d2 100644
--- a/contrib/llvm/patches/README.TXT
+++ b/contrib/llvm/patches/README.TXT
@@ -1,11 +1,11 @@
This is a set of individual patches, which contain all the customizations to
llvm/clang currently in the FreeBSD base system. These can be applied in
-alphabetical order to a pristine llvm/clang 3.6.0 source tree, for example by
+alphabetical order to a pristine llvm/clang 3.6.1 source tree, for example by
doing:
-svn co https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_360/final llvm-3.6.0
-svn co https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_360/final llvm-3.6.0/tools/clang
-cd llvm-3.6.0
+svn co https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_361/final llvm-3.6.1
+svn co https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_361/final llvm-3.6.1/tools/clang
+cd llvm-3.6.1
for p in /usr/src/contrib/llvm/patches/patch-*.diff; do
patch -p0 -f -F0 -E -i $p -s || break
done
diff --git a/contrib/llvm/patches/patch-01-freebsd-kprintf.diff b/contrib/llvm/patches/patch-01-freebsd-kprintf.diff
index cccfedf..252b4cd 100644
--- a/contrib/llvm/patches/patch-01-freebsd-kprintf.diff
+++ b/contrib/llvm/patches/patch-01-freebsd-kprintf.diff
@@ -44,7 +44,7 @@ Index: tools/clang/include/clang/Sema/Sema.h
===================================================================
--- tools/clang/include/clang/Sema/Sema.h
+++ tools/clang/include/clang/Sema/Sema.h
-@@ -8566,6 +8566,7 @@ class Sema {
+@@ -8567,6 +8567,7 @@ class Sema {
FST_Strftime,
FST_Strfmon,
FST_Kprintf,
@@ -230,7 +230,7 @@ Index: tools/clang/lib/Sema/SemaChecking.cpp
===================================================================
--- tools/clang/lib/Sema/SemaChecking.cpp
+++ tools/clang/lib/Sema/SemaChecking.cpp
-@@ -2584,6 +2584,7 @@ Sema::FormatStringType Sema::GetFormatStringType(c
+@@ -2603,6 +2603,7 @@ Sema::FormatStringType Sema::GetFormatStringType(c
.Case("strftime", FST_Strftime)
.Case("strfmon", FST_Strfmon)
.Cases("kprintf", "cmn_err", "vcmn_err", "zcmn_err", FST_Kprintf)
@@ -238,7 +238,7 @@ Index: tools/clang/lib/Sema/SemaChecking.cpp
.Default(FST_Unknown);
}
-@@ -3365,6 +3366,43 @@ CheckPrintfHandler::HandlePrintfSpecifier(const an
+@@ -3384,6 +3385,43 @@ CheckPrintfHandler::HandlePrintfSpecifier(const an
CoveredArgs.set(argIndex);
}
@@ -282,7 +282,7 @@ Index: tools/clang/lib/Sema/SemaChecking.cpp
// Check for using an Objective-C specific conversion specifier
// in a non-ObjC literal.
if (!ObjCContext && CS.isObjCArg()) {
-@@ -3988,7 +4026,8 @@ void Sema::CheckFormatString(const StringLiteral *
+@@ -4007,7 +4045,8 @@ void Sema::CheckFormatString(const StringLiteral *
return;
}
@@ -292,7 +292,7 @@ Index: tools/clang/lib/Sema/SemaChecking.cpp
CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
numDataArgs, (Type == FST_NSString),
Str, HasVAListArg, Args, format_idx,
-@@ -3996,7 +4035,8 @@ void Sema::CheckFormatString(const StringLiteral *
+@@ -4015,7 +4054,8 @@ void Sema::CheckFormatString(const StringLiteral *
if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen,
getLangOpts(),
diff --git a/contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff b/contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff
index d5650f7..57e16d7 100644
--- a/contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff
+++ b/contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff
@@ -596,7 +596,7 @@ Index: lib/Target/X86/X86FrameLowering.cpp
static unsigned getLEArOpcode(unsigned IsLP64) {
return IsLP64 ? X86::LEA64r : X86::LEA32r;
}
-@@ -1848,100 +1865,6 @@ void X86FrameLowering::adjustForHiPEPrologue(Machi
+@@ -1882,100 +1899,6 @@ void X86FrameLowering::adjustForHiPEPrologue(Machi
#endif
}
@@ -697,7 +697,7 @@ Index: lib/Target/X86/X86FrameLowering.cpp
void X86FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
-@@ -1956,7 +1879,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF,
+@@ -1990,7 +1913,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF,
bool IsLP64 = STI.isTarget64BitLP64();
DebugLoc DL = I->getDebugLoc();
uint64_t Amount = !reserveCallFrame ? I->getOperand(0).getImm() : 0;
@@ -706,7 +706,7 @@ Index: lib/Target/X86/X86FrameLowering.cpp
I = MBB.erase(I);
if (!reserveCallFrame) {
-@@ -1976,24 +1899,18 @@ eliminateCallFramePseudoInstr(MachineFunction &MF,
+@@ -2010,24 +1933,18 @@ eliminateCallFramePseudoInstr(MachineFunction &MF,
Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign;
MachineInstr *New = nullptr;
@@ -740,7 +740,7 @@ Index: lib/Target/X86/X86FrameLowering.cpp
unsigned Opc = getADDriOpcode(IsLP64, Amount);
New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
.addReg(StackPtr).addImm(Amount);
-@@ -2011,13 +1928,13 @@ eliminateCallFramePseudoInstr(MachineFunction &MF,
+@@ -2045,13 +1962,13 @@ eliminateCallFramePseudoInstr(MachineFunction &MF,
return;
}
@@ -761,7 +761,7 @@ Index: lib/Target/X86/X86FrameLowering.h
===================================================================
--- lib/Target/X86/X86FrameLowering.h
+++ lib/Target/X86/X86FrameLowering.h
-@@ -64,6 +64,8 @@ class X86FrameLowering : public TargetFrameLowerin
+@@ -66,6 +66,8 @@ class X86FrameLowering : public TargetFrameLowerin
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
diff --git a/contrib/llvm/patches/patch-08-llvm-r227089-fix-mips-i128.diff b/contrib/llvm/patches/patch-08-llvm-r227089-fix-mips-i128.diff
deleted file mode 100644
index 00a44f5..0000000
--- a/contrib/llvm/patches/patch-08-llvm-r227089-fix-mips-i128.diff
+++ /dev/null
@@ -1,1950 +0,0 @@
-Pull in r227087 from upstream llvm trunk (by Vasileios Kalintiris):
-
- [mips] Add tests for bitwise binary and integer arithmetic operators.
-
- Reviewers: dsanders
-
- Subscribers: llvm-commits
-
- Differential Revision: http://reviews.llvm.org/D7125
-
-Pull in r227089 from upstream llvm trunk (by Vasileios Kalintiris):
-
- [mips] Enable arithmetic and binary operations for the i128 data type.
-
- Summary:
- This patch adds support for some operations that were missing from
- 128-bit integer types (add/sub/mul/sdiv/udiv... etc.). With these
- changes we can support the __int128_t and __uint128_t data types
- from C/C++.
-
- Depends on D7125
-
- Reviewers: dsanders
-
- Subscribers: llvm-commits
-
- Differential Revision: http://reviews.llvm.org/D7143
-
-This fixes "error in backend" messages, when compiling parts of
-compiler-rt using 128-bit integer types for mips64.
-
-Reported by: sbruno
-PR: 197259
-
-Introduced here: http://svnweb.freebsd.org/changeset/base/278367
-
-Index: lib/Target/Mips/Mips64InstrInfo.td
-===================================================================
---- lib/Target/Mips/Mips64InstrInfo.td
-+++ lib/Target/Mips/Mips64InstrInfo.td
-@@ -440,6 +440,16 @@ def : MipsPat<(i64 (sext_inreg GPR64:$src, i32)),
- // bswap MipsPattern
- def : MipsPat<(bswap GPR64:$rt), (DSHD (DSBH GPR64:$rt))>;
-
-+// Carry pattern
-+def : MipsPat<(subc GPR64:$lhs, GPR64:$rhs),
-+ (DSUBu GPR64:$lhs, GPR64:$rhs)>;
-+let AdditionalPredicates = [NotDSP] in {
-+ def : MipsPat<(addc GPR64:$lhs, GPR64:$rhs),
-+ (DADDu GPR64:$lhs, GPR64:$rhs)>;
-+ def : MipsPat<(addc GPR64:$lhs, immSExt16:$imm),
-+ (DADDiu GPR64:$lhs, imm:$imm)>;
-+}
-+
- //===----------------------------------------------------------------------===//
- // Instruction aliases
- //===----------------------------------------------------------------------===//
-Index: lib/Target/Mips/MipsISelLowering.cpp
-===================================================================
---- lib/Target/Mips/MipsISelLowering.cpp
-+++ lib/Target/Mips/MipsISelLowering.cpp
-@@ -261,6 +261,9 @@ MipsTargetLowering::MipsTargetLowering(const MipsT
- setOperationAction(ISD::LOAD, MVT::i64, Custom);
- setOperationAction(ISD::STORE, MVT::i64, Custom);
- setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
-+ setOperationAction(ISD::SHL_PARTS, MVT::i64, Custom);
-+ setOperationAction(ISD::SRA_PARTS, MVT::i64, Custom);
-+ setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom);
- }
-
- if (!Subtarget.isGP64bit()) {
-@@ -2017,10 +2020,11 @@ SDValue MipsTargetLowering::lowerATOMIC_FENCE(SDVa
- SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op,
- SelectionDAG &DAG) const {
- SDLoc DL(Op);
-+ MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;
-+
- SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
- SDValue Shamt = Op.getOperand(2);
--
-- // if shamt < 32:
-+ // if shamt < (VT.bits):
- // lo = (shl lo, shamt)
- // hi = (or (shl hi, shamt) (srl (srl lo, 1), ~shamt))
- // else:
-@@ -2028,18 +2032,17 @@ SDValue MipsTargetLowering::lowerShiftLeftParts(SD
- // hi = (shl lo, shamt[4:0])
- SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
- DAG.getConstant(-1, MVT::i32));
-- SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo,
-- DAG.getConstant(1, MVT::i32));
-- SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, ShiftRight1Lo,
-- Not);
-- SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi, Shamt);
-- SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo);
-- SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, MVT::i32, Lo, Shamt);
-+ SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo,
-+ DAG.getConstant(1, VT));
-+ SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, Not);
-+ SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt);
-+ SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
-+ SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
- SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
- DAG.getConstant(0x20, MVT::i32));
-- Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond,
-- DAG.getConstant(0, MVT::i32), ShiftLeftLo);
-- Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftLeftLo, Or);
-+ Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond,
-+ DAG.getConstant(0, VT), ShiftLeftLo);
-+ Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftLeftLo, Or);
-
- SDValue Ops[2] = {Lo, Hi};
- return DAG.getMergeValues(Ops, DL);
-@@ -2050,8 +2053,9 @@ SDValue MipsTargetLowering::lowerShiftRightParts(S
- SDLoc DL(Op);
- SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
- SDValue Shamt = Op.getOperand(2);
-+ MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;
-
-- // if shamt < 32:
-+ // if shamt < (VT.bits):
- // lo = (or (shl (shl hi, 1), ~shamt) (srl lo, shamt))
- // if isSRA:
- // hi = (sra hi, shamt)
-@@ -2066,21 +2070,19 @@ SDValue MipsTargetLowering::lowerShiftRightParts(S
- // hi = 0
- SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
- DAG.getConstant(-1, MVT::i32));
-- SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi,
-- DAG.getConstant(1, MVT::i32));
-- SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, ShiftLeft1Hi, Not);
-- SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo, Shamt);
-- SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo);
-- SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL, DL, MVT::i32,
-- Hi, Shamt);
-+ SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, VT, Hi,
-+ DAG.getConstant(1, VT));
-+ SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, ShiftLeft1Hi, Not);
-+ SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt);
-+ SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
-+ SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL,
-+ DL, VT, Hi, Shamt);
- SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
- DAG.getConstant(0x20, MVT::i32));
-- SDValue Shift31 = DAG.getNode(ISD::SRA, DL, MVT::i32, Hi,
-- DAG.getConstant(31, MVT::i32));
-- Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftRightHi, Or);
-- Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond,
-- IsSRA ? Shift31 : DAG.getConstant(0, MVT::i32),
-- ShiftRightHi);
-+ SDValue Shift31 = DAG.getNode(ISD::SRA, DL, VT, Hi, DAG.getConstant(31, VT));
-+ Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftRightHi, Or);
-+ Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond,
-+ IsSRA ? Shift31 : DAG.getConstant(0, VT), ShiftRightHi);
-
- SDValue Ops[2] = {Lo, Hi};
- return DAG.getMergeValues(Ops, DL);
-Index: lib/Target/Mips/MipsSEISelDAGToDAG.cpp
-===================================================================
---- lib/Target/Mips/MipsSEISelDAGToDAG.cpp
-+++ lib/Target/Mips/MipsSEISelDAGToDAG.cpp
-@@ -236,13 +236,31 @@ SDNode *MipsSEDAGToDAGISel::selectAddESubE(unsigne
- (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
- "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
-
-+ unsigned SLTuOp = Mips::SLTu, ADDuOp = Mips::ADDu;
-+ if (Subtarget->isGP64bit()) {
-+ SLTuOp = Mips::SLTu64;
-+ ADDuOp = Mips::DADDu;
-+ }
-+
- SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
- SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1);
- EVT VT = LHS.getValueType();
-
-- SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, DL, VT, Ops);
-- SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, DL, VT,
-+ SDNode *Carry = CurDAG->getMachineNode(SLTuOp, DL, VT, Ops);
-+
-+ if (Subtarget->isGP64bit()) {
-+ // On 64-bit targets, sltu produces an i64 but our backend currently says
-+ // that SLTu64 produces an i32. We need to fix this in the long run but for
-+ // now, just make the DAG type-correct by asserting the upper bits are zero.
-+ Carry = CurDAG->getMachineNode(Mips::SUBREG_TO_REG, DL, VT,
-+ CurDAG->getTargetConstant(0, VT),
-+ SDValue(Carry, 0),
-+ CurDAG->getTargetConstant(Mips::sub_32, VT));
-+ }
-+
-+ SDNode *AddCarry = CurDAG->getMachineNode(ADDuOp, DL, VT,
- SDValue(Carry, 0), RHS);
-+
- return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS,
- SDValue(AddCarry, 0));
- }
-@@ -641,7 +659,8 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selec
-
- case ISD::SUBE: {
- SDValue InFlag = Node->getOperand(2);
-- Result = selectAddESubE(Mips::SUBu, InFlag, InFlag.getOperand(0), DL, Node);
-+ unsigned Opc = Subtarget->isGP64bit() ? Mips::DSUBu : Mips::SUBu;
-+ Result = selectAddESubE(Opc, InFlag, InFlag.getOperand(0), DL, Node);
- return std::make_pair(true, Result);
- }
-
-@@ -649,7 +668,8 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selec
- if (Subtarget->hasDSP()) // Select DSP instructions, ADDSC and ADDWC.
- break;
- SDValue InFlag = Node->getOperand(2);
-- Result = selectAddESubE(Mips::ADDu, InFlag, InFlag.getValue(0), DL, Node);
-+ unsigned Opc = Subtarget->isGP64bit() ? Mips::DADDu : Mips::ADDu;
-+ Result = selectAddESubE(Opc, InFlag, InFlag.getValue(0), DL, Node);
- return std::make_pair(true, Result);
- }
-
-Index: lib/Target/Mips/MipsSEISelLowering.cpp
-===================================================================
---- lib/Target/Mips/MipsSEISelLowering.cpp
-+++ lib/Target/Mips/MipsSEISelLowering.cpp
-@@ -122,6 +122,8 @@ MipsSETargetLowering::MipsSETargetLowering(const M
- setOperationAction(ISD::MUL, MVT::i64, Custom);
-
- if (Subtarget.isGP64bit()) {
-+ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Custom);
-+ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Custom);
- setOperationAction(ISD::MULHS, MVT::i64, Custom);
- setOperationAction(ISD::MULHU, MVT::i64, Custom);
- setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
-@@ -200,6 +202,8 @@ MipsSETargetLowering::MipsSETargetLowering(const M
- if (Subtarget.hasMips64r6()) {
- // MIPS64r6 replaces the accumulator-based multiplies with a three register
- // instruction
-+ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
-+ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
- setOperationAction(ISD::MUL, MVT::i64, Legal);
- setOperationAction(ISD::MULHS, MVT::i64, Legal);
- setOperationAction(ISD::MULHU, MVT::i64, Legal);
-Index: test/CodeGen/Mips/llvm-ir/add.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/add.ll
-+++ test/CodeGen/Mips/llvm-ir/add.ll
-@@ -0,0 +1,115 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP64
-+
-+define signext i1 @add_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: add_i1:
-+
-+ ; ALL: addu $[[T0:[0-9]+]], $4, $5
-+ ; ALL: sll $[[T0]], $[[T0]], 31
-+ ; ALL: sra $2, $[[T0]], 31
-+
-+ %r = add i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @add_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: add_i8:
-+
-+ ; NOT-R2-R6: addu $[[T0:[0-9]+]], $4, $5
-+ ; NOT-R2-R6: sll $[[T0]], $[[T0]], 24
-+ ; NOT-R2-R6: sra $2, $[[T0]], 24
-+
-+ ; R2-R6: addu $[[T0:[0-9]+]], $4, $5
-+ ; R2-R6: seb $2, $[[T0:[0-9]+]]
-+
-+ %r = add i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @add_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: add_i16:
-+
-+ ; NOT-R2-R6: addu $[[T0:[0-9]+]], $4, $5
-+ ; NOT-R2-R6: sll $[[T0]], $[[T0]], 16
-+ ; NOT-R2-R6: sra $2, $[[T0]], 16
-+
-+ ; R2-R6: addu $[[T0:[0-9]+]], $4, $5
-+ ; R2-R6: seh $2, $[[T0:[0-9]+]]
-+
-+ %r = add i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @add_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: add_i32:
-+
-+ ; ALL: addu $2, $4, $5
-+
-+ %r = add i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @add_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: add_i64:
-+
-+ ; GP32: addu $3, $5, $7
-+ ; GP32: sltu $[[T0:[0-9]+]], $3, $7
-+ ; GP32: addu $[[T1:[0-9]+]], $[[T0]], $6
-+ ; GP32: addu $2, $4, $[[T1]]
-+
-+ ; GP64: daddu $2, $4, $5
-+
-+ %r = add i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @add_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: add_i128:
-+
-+ ; GP32: lw $[[T0:[0-9]+]], 28($sp)
-+ ; GP32: addu $[[T1:[0-9]+]], $7, $[[T0]]
-+ ; GP32: sltu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
-+ ; GP32: lw $[[T3:[0-9]+]], 24($sp)
-+ ; GP32: addu $[[T4:[0-9]+]], $[[T2]], $[[T3]]
-+ ; GP32: addu $[[T5:[0-9]+]], $6, $[[T4]]
-+ ; GP32: sltu $[[T6:[0-9]+]], $[[T5]], $[[T3]]
-+ ; GP32: lw $[[T7:[0-9]+]], 20($sp)
-+ ; GP32: addu $[[T8:[0-9]+]], $[[T6]], $[[T7]]
-+ ; GP32: lw $[[T9:[0-9]+]], 16($sp)
-+ ; GP32: addu $3, $5, $[[T8]]
-+ ; GP32: sltu $[[T10:[0-9]+]], $3, $[[T7]]
-+ ; GP32: addu $[[T11:[0-9]+]], $[[T10]], $[[T9]]
-+ ; GP32: addu $2, $4, $[[T11]]
-+ ; GP32: move $4, $[[T5]]
-+ ; GP32: move $5, $[[T1]]
-+
-+ ; GP64: daddu $3, $5, $7
-+ ; GP64: sltu $[[T0:[0-9]+]], $3, $7
-+ ; GP64: daddu $[[T1:[0-9]+]], $[[T0]], $6
-+ ; GP64: daddu $2, $4, $[[T1]]
-+
-+ %r = add i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/and.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/and.ll
-+++ test/CodeGen/Mips/llvm-ir/and.ll
-@@ -0,0 +1,94 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+
-+define signext i1 @and_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: and_i1:
-+
-+ ; ALL: and $2, $4, $5
-+
-+ %r = and i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @and_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: and_i8:
-+
-+ ; ALL: and $2, $4, $5
-+
-+ %r = and i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @and_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: and_i16:
-+
-+ ; ALL: and $2, $4, $5
-+
-+ %r = and i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @and_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: and_i32:
-+
-+ ; GP32: and $2, $4, $5
-+
-+ ; GP64: and $[[T0:[0-9]+]], $4, $5
-+ ; GP64: sll $2, $[[T0]], 0
-+
-+ %r = and i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @and_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: and_i64:
-+
-+ ; GP32: and $2, $4, $6
-+ ; GP32: and $3, $5, $7
-+
-+ ; GP64: and $2, $4, $5
-+
-+ %r = and i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @and_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: and_i128:
-+
-+ ; GP32: lw $[[T0:[0-9]+]], 24($sp)
-+ ; GP32: lw $[[T1:[0-9]+]], 20($sp)
-+ ; GP32: lw $[[T2:[0-9]+]], 16($sp)
-+ ; GP32: and $2, $4, $[[T2]]
-+ ; GP32: and $3, $5, $[[T1]]
-+ ; GP32: and $4, $6, $[[T0]]
-+ ; GP32: lw $[[T3:[0-9]+]], 28($sp)
-+ ; GP32: and $5, $7, $[[T3]]
-+
-+ ; GP64: and $2, $4, $6
-+ ; GP64: and $3, $5, $7
-+
-+ %r = and i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/ashr.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/ashr.ll
-+++ test/CodeGen/Mips/llvm-ir/ashr.ll
-@@ -0,0 +1,188 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=M2 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 -check-prefix=NOT-R2-R6 \
-+; RUN: -check-prefix=32R1-R2
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=32R1-R2 -check-prefix=R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=32R6 -check-prefix=R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=M3 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=64R6 -check-prefix=R2-R6
-+
-+define signext i1 @ashr_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: ashr_i1:
-+
-+ ; ALL: move $2, $4
-+
-+ %r = ashr i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @ashr_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: ashr_i8:
-+
-+ ; FIXME: The andi instruction is redundant.
-+ ; ALL: andi $[[T0:[0-9]+]], $5, 255
-+ ; ALL: srav $2, $4, $[[T0]]
-+
-+ %r = ashr i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @ashr_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: ashr_i16:
-+
-+ ; FIXME: The andi instruction is redundant.
-+ ; ALL: andi $[[T0:[0-9]+]], $5, 65535
-+ ; ALL: srav $2, $4, $[[T0]]
-+
-+ %r = ashr i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @ashr_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: ashr_i32:
-+
-+ ; ALL: srav $2, $4, $5
-+
-+ %r = ashr i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: ashr_i64:
-+
-+ ; M2: srav $[[T0:[0-9]+]], $4, $7
-+ ; M2: andi $[[T1:[0-9]+]], $7, 32
-+ ; M2: bnez $[[T1]], $[[BB0:BB[0-9_]+]]
-+ ; M2: move $3, $[[T0]]
-+ ; M2: srlv $[[T2:[0-9]+]], $5, $7
-+ ; M2: not $[[T3:[0-9]+]], $7
-+ ; M2: sll $[[T4:[0-9]+]], $4, 1
-+ ; M2: sllv $[[T5:[0-9]+]], $[[T4]], $[[T3]]
-+ ; M2: or $3, $[[T3]], $[[T2]]
-+ ; M2: $[[BB0]]:
-+ ; M2: beqz $[[T1]], $[[BB1:BB[0-9_]+]]
-+ ; M2: nop
-+ ; M2: sra $2, $4, 31
-+ ; M2: $[[BB1]]:
-+ ; M2: jr $ra
-+ ; M2: nop
-+
-+ ; 32R1-R2: srlv $[[T0:[0-9]+]], $5, $7
-+ ; 32R1-R2: not $[[T1:[0-9]+]], $7
-+ ; 32R1-R2: sll $[[T2:[0-9]+]], $4, 1
-+ ; 32R1-R2: sllv $[[T3:[0-9]+]], $[[T2]], $[[T1]]
-+ ; 32R1-R2: or $3, $[[T3]], $[[T0]]
-+ ; 32R1-R2: srav $[[T4:[0-9]+]], $4, $7
-+ ; 32R1-R2: andi $[[T5:[0-9]+]], $7, 32
-+ ; 32R1-R2: movn $3, $[[T4]], $[[T5]]
-+ ; 32R1-R2: sra $4, $4, 31
-+ ; 32R1-R2: jr $ra
-+ ; 32R1-R2: movn $2, $4, $[[T5]]
-+
-+ ; 32R6: srav $[[T0:[0-9]+]], $4, $7
-+ ; 32R6: andi $[[T1:[0-9]+]], $7, 32
-+ ; 32R6: seleqz $[[T2:[0-9]+]], $[[T0]], $[[T1]]
-+ ; 32R6: sra $[[T3:[0-9]+]], $4, 31
-+ ; 32R6: selnez $[[T4:[0-9]+]], $[[T3]], $[[T1]]
-+ ; 32R6: or $[[T5:[0-9]+]], $[[T4]], $[[T2]]
-+ ; 32R6: srlv $[[T6:[0-9]+]], $5, $7
-+ ; 32R6: not $[[T7:[0-9]+]], $7
-+ ; 32R6: sll $[[T8:[0-9]+]], $4, 1
-+ ; 32R6: sllv $[[T9:[0-9]+]], $[[T8]], $[[T7]]
-+ ; 32R6: or $[[T10:[0-9]+]], $[[T9]], $[[T6]]
-+ ; 32R6: seleqz $[[T11:[0-9]+]], $[[T10]], $[[T1]]
-+ ; 32R6: selnez $[[T12:[0-9]+]], $[[T0]], $[[T1]]
-+ ; 32R6: jr $ra
-+ ; 32R6: or $3, $[[T0]], $[[T11]]
-+
-+ ; FIXME: The sll instruction below is redundant.
-+ ; GP64: sll $[[T0:[0-9]+]], $5, 0
-+ ; GP64: dsrav $2, $4, $[[T0]]
-+
-+ %r = ashr i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @ashr_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: ashr_i128:
-+
-+ ; GP32: lw $25, %call16(__ashrti3)($gp)
-+
-+ ; M3: sll $[[T0:[0-9]+]], $7, 0
-+ ; M3: dsrav $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; M3: andi $[[T2:[0-9]+]], $[[T0]], 32
-+ ; M3: bnez $[[T3:[0-9]+]], $[[BB0:BB[0-9_]+]]
-+ ; M3: move $3, $[[T1]]
-+ ; M3: dsrlv $[[T4:[0-9]+]], $5, $[[T0]]
-+ ; M3: dsll $[[T5:[0-9]+]], $4, 1
-+ ; M3: not $[[T6:[0-9]+]], $[[T0]]
-+ ; M3: dsllv $[[T7:[0-9]+]], $[[T5]], $[[T6]]
-+ ; M3: or $3, $[[T7]], $[[T4]]
-+ ; M3: $[[BB0]]:
-+ ; M3: beqz $[[T3]], $[[BB1:BB[0-9_]+]]
-+ ; M3: nop
-+ ; M3: dsra $2, $4, 31
-+ ; M3: $[[BB1]]:
-+ ; M3: jr $ra
-+ ; M3: nop
-+
-+ ; GP64-NOT-R6: sll $[[T0:[0-9]+]], $7, 0
-+ ; GP64-NOT-R6: dsrlv $[[T1:[0-9]+]], $5, $[[T0]]
-+ ; GP64-NOT-R6: dsll $[[T2:[0-9]+]], $4, 1
-+ ; GP64-NOT-R6: not $[[T3:[0-9]+]], $[[T0]]
-+ ; GP64-NOT-R6: dsllv $[[T4:[0-9]+]], $[[T2]], $[[T3]]
-+ ; GP64-NOT-R6: or $3, $[[T4]], $[[T1]]
-+ ; GP64-NOT-R6: dsrav $2, $4, $[[T0]]
-+ ; GP64-NOT-R6: andi $[[T5:[0-9]+]], $[[T0]], 32
-+
-+ ; GP64-NOT-R6: movn $3, $2, $[[T5]]
-+ ; GP64-NOT-R6: dsra $[[T6:[0-9]+]], $4, 31
-+ ; GP64-NOT-R6: jr $ra
-+ ; GP64-NOT-R6: movn $2, $[[T6]], $[[T5]]
-+
-+ ; 64R6: sll $[[T0:[0-9]+]], $7, 0
-+ ; 64R6: dsrav $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; 64R6: andi $[[T2:[0-9]+]], $[[T0]], 32
-+ ; 64R6: sll $[[T3:[0-9]+]], $[[T2]], 0
-+ ; 64R6: seleqz $[[T4:[0-9]+]], $[[T1]], $[[T3]]
-+ ; 64R6: dsra $[[T5:[0-9]+]], $4, 31
-+ ; 64R6: selnez $[[T6:[0-9]+]], $[[T5]], $[[T3]]
-+ ; 64R6: or $2, $[[T6]], $[[T4]]
-+ ; 64R6: dsrlv $[[T7:[0-9]+]], $5, $[[T0]]
-+ ; 64R6: dsll $[[T8:[0-9]+]], $4, 1
-+ ; 64R6: not $[[T9:[0-9]+]], $[[T0]]
-+ ; 64R6: dsllv $[[T10:[0-9]+]], $[[T8]], $[[T9]]
-+ ; 64R6: or $[[T11:[0-9]+]], $[[T10]], $[[T7]]
-+ ; 64R6: seleqz $[[T12:[0-9]+]], $[[T11]], $[[T3]]
-+ ; 64R6: selnez $[[T13:[0-9]+]], $[[T1]], $[[T3]]
-+ ; 64R6: jr $ra
-+ ; 64R6: or $3, $[[T13]], $[[T12]]
-+
-+ %r = ashr i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/lshr.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/lshr.ll
-+++ test/CodeGen/Mips/llvm-ir/lshr.ll
-@@ -0,0 +1,176 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=M2 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 -check-prefix=NOT-R2-R6 \
-+; RUN: -check-prefix=32R1-R2
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=32R1-R2 -check-prefix=R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=32R6 -check-prefix=R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=M3 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=64R6 -check-prefix=R2-R6
-+
-+define signext i1 @lshr_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: lshr_i1:
-+
-+ ; ALL: move $2, $4
-+
-+ %r = lshr i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define zeroext i8 @lshr_i8(i8 zeroext %a, i8 zeroext %b) {
-+entry:
-+; ALL-LABEL: lshr_i8:
-+
-+ ; ALL: srlv $[[T0:[0-9]+]], $4, $5
-+ ; ALL: andi $2, $[[T0]], 255
-+
-+ %r = lshr i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define zeroext i16 @lshr_i16(i16 zeroext %a, i16 zeroext %b) {
-+entry:
-+; ALL-LABEL: lshr_i16:
-+
-+ ; ALL: srlv $[[T0:[0-9]+]], $4, $5
-+ ; ALL: andi $2, $[[T0]], 65535
-+
-+ %r = lshr i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @lshr_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: lshr_i32:
-+
-+ ; ALL: srlv $2, $4, $5
-+
-+ %r = lshr i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: lshr_i64:
-+
-+ ; M2: srlv $[[T0:[0-9]+]], $4, $7
-+ ; M2: andi $[[T1:[0-9]+]], $7, 32
-+ ; M2: bnez $[[T1]], $[[BB0:BB[0-9_]+]]
-+ ; M2: move $3, $[[T0]]
-+ ; M2: srlv $[[T2:[0-9]+]], $5, $7
-+ ; M2: not $[[T3:[0-9]+]], $7
-+ ; M2: sll $[[T4:[0-9]+]], $4, 1
-+ ; M2: sllv $[[T5:[0-9]+]], $[[T4]], $[[T3]]
-+ ; M2: or $3, $[[T3]], $[[T2]]
-+ ; M2: $[[BB0]]:
-+ ; M2: bnez $[[T1]], $[[BB1:BB[0-9_]+]]
-+ ; M2: addiu $2, $zero, 0
-+ ; M2: move $2, $[[T0]]
-+ ; M2: $[[BB1]]:
-+ ; M2: jr $ra
-+ ; M2: nop
-+
-+ ; 32R1-R2: srlv $[[T0:[0-9]+]], $5, $7
-+ ; 32R1-R2: not $[[T1:[0-9]+]], $7
-+ ; 32R1-R2: sll $[[T2:[0-9]+]], $4, 1
-+ ; 32R1-R2: sllv $[[T3:[0-9]+]], $[[T2]], $[[T1]]
-+ ; 32R1-R2: or $3, $[[T3]], $[[T0]]
-+ ; 32R1-R2: srlv $[[T4:[0-9]+]], $4, $7
-+ ; 32R1-R2: andi $[[T5:[0-9]+]], $7, 32
-+ ; 32R1-R2: movn $3, $[[T4]], $[[T5]]
-+ ; 32R1-R2: jr $ra
-+ ; 32R1-R2: movn $2, $zero, $[[T5]]
-+
-+ ; 32R6: srlv $[[T0:[0-9]+]], $5, $7
-+ ; 32R6: not $[[T1:[0-9]+]], $7
-+ ; 32R6: sll $[[T2:[0-9]+]], $4, 1
-+ ; 32R6: sllv $[[T3:[0-9]+]], $[[T2]], $[[T1]]
-+ ; 32R6: or $[[T4:[0-9]+]], $[[T3]], $[[T0]]
-+ ; 32R6: andi $[[T5:[0-9]+]], $7, 32
-+ ; 32R6: seleqz $[[T6:[0-9]+]], $[[T4]], $[[T3]]
-+ ; 32R6: srlv $[[T7:[0-9]+]], $4, $7
-+ ; 32R6: selnez $[[T8:[0-9]+]], $[[T7]], $[[T5]]
-+ ; 32R6: or $3, $[[T8]], $[[T6]]
-+ ; 32R6: jr $ra
-+ ; 32R6: seleqz $2, $[[T7]], $[[T5]]
-+
-+ ; GP64: sll $[[T0:[0-9]+]], $5, 0
-+ ; GP64: dsrlv $2, $4, $[[T0]]
-+
-+ %r = lshr i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @lshr_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: lshr_i128:
-+
-+ ; GP32: lw $25, %call16(__lshrti3)($gp)
-+
-+ ; M3: sll $[[T0:[0-9]+]], $7, 0
-+ ; M3: dsrlv $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; M3: andi $[[T2:[0-9]+]], $[[T0]], 32
-+ ; M3: bnez $[[T3:[0-9]+]], $[[BB0:BB[0-9_]+]]
-+ ; M3: move $3, $[[T1]]
-+ ; M3: dsrlv $[[T4:[0-9]+]], $5, $[[T0]]
-+ ; M3: dsll $[[T5:[0-9]+]], $4, 1
-+ ; M3: not $[[T6:[0-9]+]], $[[T0]]
-+ ; M3: dsllv $[[T7:[0-9]+]], $[[T5]], $[[T6]]
-+ ; M3: or $3, $[[T7]], $[[T4]]
-+ ; M3: $[[BB0]]:
-+ ; M3: bnez $[[T3]], $[[BB1:BB[0-9_]+]]
-+ ; M3: daddiu $2, $zero, 0
-+ ; M3: move $2, $[[T1]]
-+ ; M3: $[[BB1]]:
-+ ; M3: jr $ra
-+ ; M3: nop
-+
-+ ; GP64-NOT-R6: sll $[[T0:[0-9]+]], $7, 0
-+ ; GP64-NOT-R6: dsrlv $[[T1:[0-9]+]], $5, $[[T0]]
-+ ; GP64-NOT-R6: dsll $[[T2:[0-9]+]], $4, 1
-+ ; GP64-NOT-R6: not $[[T3:[0-9]+]], $[[T0]]
-+ ; GP64-NOT-R6: dsllv $[[T4:[0-9]+]], $[[T2]], $[[T3]]
-+ ; GP64-NOT-R6: or $3, $[[T4]], $[[T1]]
-+ ; GP64-NOT-R6: dsrlv $2, $4, $[[T0]]
-+ ; GP64-NOT-R6: andi $[[T5:[0-9]+]], $[[T0]], 32
-+ ; GP64-NOT-R6: movn $3, $2, $[[T5]]
-+ ; GP64-NOT-R6: jr $ra
-+ ; GP64-NOT-R6: movn $2, $zero, $1
-+
-+ ; 64R6: sll $[[T0:[0-9]+]], $7, 0
-+ ; 64R6: dsrlv $[[T1:[0-9]+]], $5, $[[T0]]
-+ ; 64R6: dsll $[[T2:[0-9]+]], $4, 1
-+ ; 64R6: not $[[T3:[0-9]+]], $[[T0]]
-+ ; 64R6: dsllv $[[T4:[0-9]+]], $[[T2]], $[[T3]]
-+ ; 64R6: or $[[T5:[0-9]+]], $[[T4]], $[[T1]]
-+ ; 64R6: andi $[[T6:[0-9]+]], $[[T0]], 32
-+ ; 64R6: sll $[[T7:[0-9]+]], $[[T6]], 0
-+ ; 64R6: seleqz $[[T8:[0-9]+]], $[[T5]], $[[T7]]
-+ ; 64R6: dsrlv $[[T9:[0-9]+]], $4, $[[T0]]
-+ ; 64R6: selnez $[[T10:[0-9]+]], $[[T9]], $[[T7]]
-+ ; 64R6: or $3, $[[T10]], $[[T8]]
-+ ; 64R6: jr $ra
-+ ; 64R6: seleqz $2, $[[T0]], $[[T7]]
-+
-+ %r = lshr i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/mul.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/mul.ll
-+++ test/CodeGen/Mips/llvm-ir/mul.ll
-@@ -1,19 +1,19 @@
--; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
--; RUN: -check-prefix=ALL -check-prefix=M2
--; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
--; RUN: -check-prefix=ALL -check-prefix=32R1-R2 -check-prefix=32R1
--; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
--; RUN: -check-prefix=ALL -check-prefix=32R1-R2 -check-prefix=32R2
--; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
--; RUN: -check-prefix=ALL -check-prefix=32R6
--; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
--; RUN: -check-prefix=ALL -check-prefix=M4
--; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
--; RUN: -check-prefix=ALL -check-prefix=64R1-R2
--; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
--; RUN: -check-prefix=ALL -check-prefix=64R1-R2
--; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
--; RUN: -check-prefix=ALL -check-prefix=64R6
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s -check-prefix=ALL \
-+; RUN: -check-prefix=M2 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s -check-prefix=ALL \
-+; RUN: -check-prefix=32R1-R2 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL \
-+; RUN: -check-prefix=32R1-R2 -check-prefix=32R2 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL \
-+; RUN: -check-prefix=32R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s -check-prefix=ALL \
-+; RUN: -check-prefix=M4 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s -check-prefix=ALL \
-+; RUN: -check-prefix=64R1-R2 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL \
-+; RUN: -check-prefix=64R1-R2 -check-prefix=GP64 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL \
-+; RUN: -check-prefix=64R6
-
- define signext i1 @mul_i1(i1 signext %a, i1 signext %b) {
- entry:
-@@ -179,3 +179,30 @@ entry:
- %r = mul i64 %a, %b
- ret i64 %r
- }
-+
-+define signext i128 @mul_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: mul_i128:
-+
-+ ; GP32: lw $25, %call16(__multi3)($gp)
-+
-+ ; GP64-NOT-R6: dmult $4, $7
-+ ; GP64-NOT-R6: mflo $[[T0:[0-9]+]]
-+ ; GP64-NOT-R6: dmult $5, $6
-+ ; GP64-NOT-R6: mflo $[[T1:[0-9]+]]
-+ ; GP64-NOT-R6: dmultu $5, $7
-+ ; GP64-NOT-R6: mflo $3
-+ ; GP64-NOT-R6: mfhi $[[T2:[0-9]+]]
-+ ; GP64-NOT-R6: daddu $[[T3:[0-9]+]], $[[T2]], $[[T1]]
-+ ; GP64-NOT-R6: daddu $2, $[[T3:[0-9]+]], $[[T0]]
-+
-+ ; 64R6: dmul $[[T0:[0-9]+]], $5, $6
-+ ; 64R6: dmuhu $[[T1:[0-9]+]], $5, $7
-+ ; 64R6: daddu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
-+ ; 64R6: dmul $[[T3:[0-9]+]], $4, $7
-+ ; 64R6: daddu $2, $[[T2]], $[[T3]]
-+ ; 64R6: dmul $3, $5, $7
-+
-+ %r = mul i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/or.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/or.ll
-+++ test/CodeGen/Mips/llvm-ir/or.ll
-@@ -0,0 +1,95 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+
-+define signext i1 @or_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: or_i1:
-+
-+ ; ALL: or $2, $4, $5
-+
-+ %r = or i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @or_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: or_i8:
-+
-+ ; ALL: or $2, $4, $5
-+
-+ %r = or i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @or_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: or_i16:
-+
-+ ; ALL: or $2, $4, $5
-+
-+ %r = or i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @or_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: or_i32:
-+
-+ ; GP32: or $2, $4, $5
-+
-+ ; GP64: or $[[T0:[0-9]+]], $4, $5
-+ ; FIXME: The sll instruction below is redundant.
-+ ; GP64: sll $2, $[[T0]], 0
-+
-+ %r = or i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @or_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: or_i64:
-+
-+ ; GP32: or $2, $4, $6
-+ ; GP32: or $3, $5, $7
-+
-+ ; GP64: or $2, $4, $5
-+
-+ %r = or i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @or_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: or_i128:
-+
-+ ; GP32: lw $[[T0:[0-9]+]], 24($sp)
-+ ; GP32: lw $[[T1:[0-9]+]], 20($sp)
-+ ; GP32: lw $[[T2:[0-9]+]], 16($sp)
-+ ; GP32: or $2, $4, $[[T2]]
-+ ; GP32: or $3, $5, $[[T1]]
-+ ; GP32: or $4, $6, $[[T0]]
-+ ; GP32: lw $[[T3:[0-9]+]], 28($sp)
-+ ; GP32: or $5, $7, $[[T3]]
-+
-+ ; GP64: or $2, $4, $6
-+ ; GP64: or $3, $5, $7
-+
-+ %r = or i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/sdiv.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/sdiv.ll
-+++ test/CodeGen/Mips/llvm-ir/sdiv.ll
-@@ -0,0 +1,136 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=R2 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=R2 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=R6 -check-prefix=64R6
-+
-+define signext i1 @sdiv_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: sdiv_i1:
-+
-+ ; NOT-R6: div $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mflo $[[T0:[0-9]+]]
-+ ; FIXME: The sll/sra instructions are redundant since div is signed.
-+ ; NOT-R6: sll $[[T1:[0-9]+]], $[[T0]], 31
-+ ; NOT-R6: sra $2, $[[T1]], 31
-+
-+ ; R6: div $[[T0:[0-9]+]], $4, $5
-+ ; R6: teq $5, $zero, 7
-+ ; FIXME: The sll/sra instructions are redundant since div is signed.
-+ ; R6: sll $[[T1:[0-9]+]], $[[T0]], 31
-+ ; R6: sra $2, $[[T1]], 31
-+
-+ %r = sdiv i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @sdiv_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: sdiv_i8:
-+
-+ ; NOT-R2-R6: div $zero, $4, $5
-+ ; NOT-R2-R6: teq $5, $zero, 7
-+ ; NOT-R2-R6: mflo $[[T0:[0-9]+]]
-+ ; FIXME: The sll/sra instructions are redundant since div is signed.
-+ ; NOT-R2-R6: sll $[[T1:[0-9]+]], $[[T0]], 24
-+ ; NOT-R2-R6: sra $2, $[[T1]], 24
-+
-+ ; R2: div $zero, $4, $5
-+ ; R2: teq $5, $zero, 7
-+ ; R2: mflo $[[T0:[0-9]+]]
-+ ; FIXME: This instruction is redundant.
-+ ; R2: seb $2, $[[T0]]
-+
-+ ; R6: div $[[T0:[0-9]+]], $4, $5
-+ ; R6: teq $5, $zero, 7
-+ ; FIXME: This instruction is redundant.
-+ ; R6: seb $2, $[[T0]]
-+
-+ %r = sdiv i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @sdiv_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: sdiv_i16:
-+
-+ ; NOT-R2-R6: div $zero, $4, $5
-+ ; NOT-R2-R6: teq $5, $zero, 7
-+ ; NOT-R2-R6: mflo $[[T0:[0-9]+]]
-+ ; FIXME: The sll/sra instructions are redundant since div is signed.
-+ ; NOT-R2-R6: sll $[[T1:[0-9]+]], $[[T0]], 16
-+ ; NOT-R2-R6: sra $2, $[[T1]], 16
-+
-+ ; R2: div $zero, $4, $5
-+ ; R2: teq $5, $zero, 7
-+ ; R2: mflo $[[T0:[0-9]+]]
-+ ; FIXME: This is instruction is redundant since div is signed.
-+ ; R2: seh $2, $[[T0]]
-+
-+ ; R6: div $[[T0:[0-9]+]], $4, $5
-+ ; R6: teq $5, $zero, 7
-+ ; FIXME: This is instruction is redundant since div is signed.
-+ ; R6: seh $2, $[[T0]]
-+
-+ %r = sdiv i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @sdiv_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: sdiv_i32:
-+
-+ ; NOT-R6: div $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mflo $2
-+
-+ ; R6: div $2, $4, $5
-+ ; R6: teq $5, $zero, 7
-+
-+ %r = sdiv i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @sdiv_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: sdiv_i64:
-+
-+ ; GP32: lw $25, %call16(__divdi3)($gp)
-+
-+ ; GP64-NOT-R6: ddiv $zero, $4, $5
-+ ; GP64-NOT-R6: teq $5, $zero, 7
-+ ; GP64-NOT-R6: mflo $2
-+
-+ ; 64R6: ddiv $2, $4, $5
-+ ; 64R6: teq $5, $zero, 7
-+
-+ %r = sdiv i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @sdiv_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+ ; ALL-LABEL: sdiv_i128:
-+
-+ ; GP32: lw $25, %call16(__divti3)($gp)
-+
-+ ; GP64-NOT-R6: ld $25, %call16(__divti3)($gp)
-+ ; 64R6: ld $25, %call16(__divti3)($gp)
-+
-+ %r = sdiv i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/shl.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/shl.ll
-+++ test/CodeGen/Mips/llvm-ir/shl.ll
-@@ -0,0 +1,188 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=M2 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 -check-prefix=NOT-R2-R6 \
-+; RUN: -check-prefix=32R1-R2
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=32R1-R2 -check-prefix=R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32 \
-+; RUN: -check-prefix=32R6 -check-prefix=R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=M3 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64 \
-+; RUN: -check-prefix=64R6 -check-prefix=R2-R6
-+
-+define signext i1 @shl_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: shl_i1:
-+
-+ ; ALL: move $2, $4
-+
-+ %r = shl i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @shl_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: shl_i8:
-+
-+ ; NOT-R2-R6: andi $[[T0:[0-9]+]], $5, 255
-+ ; NOT-R2-R6: sllv $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; NOT-R2-R6: sll $[[T2:[0-9]+]], $[[T1]], 24
-+ ; NOT-R2-R6: sra $2, $[[T2]], 24
-+
-+ ; R2-R6: andi $[[T0:[0-9]+]], $5, 255
-+ ; R2-R6: sllv $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; R2-R6: seb $2, $[[T1]]
-+
-+ %r = shl i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @shl_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: shl_i16:
-+
-+ ; NOT-R2-R6: andi $[[T0:[0-9]+]], $5, 65535
-+ ; NOT-R2-R6: sllv $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; NOT-R2-R6: sll $[[T2:[0-9]+]], $[[T1]], 16
-+ ; NOT-R2-R6: sra $2, $[[T2]], 16
-+
-+ ; R2-R6: andi $[[T0:[0-9]+]], $5, 65535
-+ ; R2-R6: sllv $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; R2-R6: seh $2, $[[T1]]
-+
-+ %r = shl i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @shl_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: shl_i32:
-+
-+ ; ALL: sllv $2, $4, $5
-+
-+ %r = shl i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @shl_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: shl_i64:
-+
-+ ; M2: sllv $[[T0:[0-9]+]], $5, $7
-+ ; M2: andi $[[T1:[0-9]+]], $7, 32
-+ ; M2: bnez $[[T1]], $[[BB0:BB[0-9_]+]]
-+ ; M2: move $2, $[[T0]]
-+ ; M2: sllv $[[T2:[0-9]+]], $4, $7
-+ ; M2: not $[[T3:[0-9]+]], $7
-+ ; M2: srl $[[T4:[0-9]+]], $5, 1
-+ ; M2: srlv $[[T5:[0-9]+]], $[[T4]], $[[T3]]
-+ ; M2: or $2, $[[T2]], $[[T3]]
-+ ; M2: $[[BB0]]:
-+ ; M2: bnez $[[T1]], $[[BB1:BB[0-9_]+]]
-+ ; M2: addiu $3, $zero, 0
-+ ; M2: move $3, $[[T0]]
-+ ; M2: $[[BB1]]:
-+ ; M2: jr $ra
-+ ; M2: nop
-+
-+ ; 32R1-R2: sllv $[[T0:[0-9]+]], $4, $7
-+ ; 32R1-R2: not $[[T1:[0-9]+]], $7
-+ ; 32R1-R2: srl $[[T2:[0-9]+]], $5, 1
-+ ; 32R1-R2: srlv $[[T3:[0-9]+]], $[[T2]], $[[T1]]
-+ ; 32R1-R2: or $2, $[[T0]], $[[T3]]
-+ ; 32R1-R2: sllv $[[T4:[0-9]+]], $5, $7
-+ ; 32R1-R2: andi $[[T5:[0-9]+]], $7, 32
-+ ; 32R1-R2: movn $2, $[[T4]], $[[T5]]
-+ ; 32R1-R2: jr $ra
-+ ; 32R1-R2: movn $3, $zero, $[[T5]]
-+
-+ ; 32R6: sllv $[[T0:[0-9]+]], $4, $7
-+ ; 32R6: not $[[T1:[0-9]+]], $7
-+ ; 32R6: srl $[[T2:[0-9]+]], $5, 1
-+ ; 32R6: srlv $[[T3:[0-9]+]], $[[T2]], $[[T1]]
-+ ; 32R6: or $[[T4:[0-9]+]], $[[T0]], $[[T3]]
-+ ; 32R6: andi $[[T5:[0-9]+]], $7, 32
-+ ; 32R6: seleqz $[[T6:[0-9]+]], $[[T4]], $[[T2]]
-+ ; 32R6: sllv $[[T7:[0-9]+]], $5, $7
-+ ; 32R6: selnez $[[T8:[0-9]+]], $[[T7]], $[[T5]]
-+ ; 32R6: or $2, $[[T8]], $[[T6]]
-+ ; 32R6: jr $ra
-+ ; 32R6: seleqz $3, $[[T7]], $[[T5]]
-+
-+ ; GP64: sll $[[T0:[0-9]+]], $5, 0
-+ ; GP64: dsllv $2, $4, $1
-+
-+ %r = shl i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @shl_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: shl_i128:
-+
-+ ; GP32: lw $25, %call16(__ashlti3)($gp)
-+
-+ ; M3: sll $[[T0:[0-9]+]], $7, 0
-+ ; M3: dsllv $[[T1:[0-9]+]], $5, $[[T0]]
-+ ; M3: andi $[[T2:[0-9]+]], $[[T0]], 32
-+ ; M3: bnez $[[T3:[0-9]+]], $[[BB0:BB[0-9_]+]]
-+ ; M3: move $2, $[[T1]]
-+ ; M3: dsllv $[[T4:[0-9]+]], $4, $[[T0]]
-+ ; M3: dsrl $[[T5:[0-9]+]], $5, 1
-+ ; M3: not $[[T6:[0-9]+]], $[[T0]]
-+ ; M3: dsrlv $[[T7:[0-9]+]], $[[T5]], $[[T6]]
-+ ; M3: or $2, $[[T4]], $[[T7]]
-+ ; M3: $[[BB0]]:
-+ ; M3: bnez $[[T3]], $[[BB1:BB[0-9_]+]]
-+ ; M3: daddiu $3, $zero, 0
-+ ; M3: move $3, $[[T1]]
-+ ; M3: $[[BB1]]:
-+ ; M3: jr $ra
-+ ; M3: nop
-+
-+ ; GP64-NOT-R6: sll $[[T0:[0-9]+]], $7, 0
-+ ; GP64-NOT-R6: dsllv $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; GP64-NOT-R6: dsrl $[[T2:[0-9]+]], $5, 1
-+ ; GP64-NOT-R6: not $[[T3:[0-9]+]], $[[T0]]
-+ ; GP64-NOT-R6: dsrlv $[[T4:[0-9]+]], $[[T2]], $[[T3]]
-+ ; GP64-NOT-R6: or $2, $[[T1]], $[[T4]]
-+ ; GP64-NOT-R6: dsllv $3, $5, $[[T0]]
-+ ; GP64-NOT-R6: andi $[[T5:[0-9]+]], $[[T0]], 32
-+ ; GP64-NOT-R6: movn $2, $3, $[[T5]]
-+ ; GP64-NOT-R6: jr $ra
-+ ; GP64-NOT-R6: movn $3, $zero, $1
-+
-+ ; 64R6: sll $[[T0:[0-9]+]], $7, 0
-+ ; 64R6: dsllv $[[T1:[0-9]+]], $4, $[[T0]]
-+ ; 64R6: dsrl $[[T2:[0-9]+]], $5, 1
-+ ; 64R6: not $[[T3:[0-9]+]], $[[T0]]
-+ ; 64R6: dsrlv $[[T4:[0-9]+]], $[[T2]], $[[T3]]
-+ ; 64R6: or $[[T5:[0-9]+]], $[[T1]], $[[T4]]
-+ ; 64R6: andi $[[T6:[0-9]+]], $[[T0]], 32
-+ ; 64R6: sll $[[T7:[0-9]+]], $[[T6]], 0
-+ ; 64R6: seleqz $[[T8:[0-9]+]], $[[T5]], $[[T7]]
-+ ; 64R6: dsllv $[[T9:[0-9]+]], $5, $[[T0]]
-+ ; 64R6: selnez $[[T10:[0-9]+]], $[[T9]], $[[T7]]
-+ ; 64R6: or $2, $[[T10]], $[[T8]]
-+ ; 64R6: jr $ra
-+ ; 64R6: seleqz $3, $[[T0]], $[[T7]]
-+
-+ %r = shl i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/srem.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/srem.ll
-+++ test/CodeGen/Mips/llvm-ir/srem.ll
-@@ -0,0 +1,129 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=GP32 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=GP32 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s -check-prefix=GP32 \
-+; RUN: -check-prefix=R2 -check-prefix=R2-R6 -check-prefix=NOT-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=GP32 -check-prefix=R6 -check-prefix=R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=R2 -check-prefix=R2-R6 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=64R6 -check-prefix=R6 -check-prefix=R2-R6
-+
-+define signext i1 @srem_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: srem_i1:
-+
-+ ; NOT-R6: div $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mfhi $[[T0:[0-9]+]]
-+ ; NOT-R6: sll $[[T1:[0-9]+]], $[[T0]], 31
-+ ; NOT-R6: sra $2, $[[T1]], 31
-+
-+ ; R6: mod $[[T0:[0-9]+]], $4, $5
-+ ; R6: teq $5, $zero, 7
-+ ; R6: sll $[[T3:[0-9]+]], $[[T0]], 31
-+ ; R6: sra $2, $[[T3]], 31
-+
-+ %r = srem i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @srem_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: srem_i8:
-+
-+ ; NOT-R2-R6: div $zero, $4, $5
-+ ; NOT-R2-R6: teq $5, $zero, 7
-+ ; NOT-R2-R6: mfhi $[[T0:[0-9]+]]
-+ ; NOT-R2-R6: sll $[[T1:[0-9]+]], $[[T0]], 24
-+ ; NOT-R2-R6: sra $2, $[[T1]], 24
-+
-+ ; R2: div $zero, $4, $5
-+ ; R2: teq $5, $zero, 7
-+ ; R2: mfhi $[[T0:[0-9]+]]
-+ ; R2: seb $2, $[[T0]]
-+
-+ ; R6: mod $[[T0:[0-9]+]], $4, $5
-+ ; R6: teq $5, $zero, 7
-+ ; R6: seb $2, $[[T0]]
-+
-+ %r = srem i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @srem_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: srem_i16:
-+
-+ ; NOT-R2-R6: div $zero, $4, $5
-+ ; NOT-R2-R6: teq $5, $zero, 7
-+ ; NOT-R2-R6: mfhi $[[T0:[0-9]+]]
-+ ; NOT-R2-R6: sll $[[T1:[0-9]+]], $[[T0]], 16
-+ ; NOT-R2-R6: sra $2, $[[T1]], 16
-+
-+ ; R2: div $zero, $4, $5
-+ ; R2: teq $5, $zero, 7
-+ ; R2: mfhi $[[T0:[0-9]+]]
-+ ; R2: seh $2, $[[T1]]
-+
-+ ; R6: mod $[[T0:[0-9]+]], $4, $5
-+ ; R6: teq $5, $zero, 7
-+ ; R6: seh $2, $[[T0]]
-+
-+ %r = srem i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @srem_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: srem_i32:
-+
-+ ; NOT-R6: div $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mfhi $2
-+
-+ ; R6: mod $2, $4, $5
-+ ; R6: teq $5, $zero, 7
-+
-+ %r = srem i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @srem_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: srem_i64:
-+
-+ ; GP32: lw $25, %call16(__moddi3)($gp)
-+
-+ ; GP64-NOT-R6: ddiv $zero, $4, $5
-+ ; GP64-NOT-R6: teq $5, $zero, 7
-+ ; GP64-NOT-R6: mfhi $2
-+
-+ ; 64R6: dmod $2, $4, $5
-+ ; 64R6: teq $5, $zero, 7
-+
-+ %r = srem i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @srem_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: srem_i128:
-+
-+ ; GP32: lw $25, %call16(__modti3)($gp)
-+
-+ ; GP64-NOT-R6: ld $25, %call16(__modti3)($gp)
-+ ; 64-R6: ld $25, %call16(__modti3)($gp)
-+
-+ %r = srem i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/sub.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/sub.ll
-+++ test/CodeGen/Mips/llvm-ir/sub.ll
-@@ -0,0 +1,114 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP64
-+
-+define signext i1 @sub_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: sub_i1:
-+
-+ ; ALL: subu $[[T0:[0-9]+]], $4, $5
-+ ; ALL: sll $[[T0]], $[[T0]], 31
-+ ; ALL: sra $2, $[[T0]], 31
-+
-+ %r = sub i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @sub_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: sub_i8:
-+
-+ ; NOT-R2-R6: subu $[[T0:[0-9]+]], $4, $5
-+ ; NOT-R2-R6: sll $[[T0]], $[[T0]], 24
-+ ; NOT-R2-R6: sra $2, $[[T0]], 24
-+
-+ ; R2-R6: subu $[[T0:[0-9]+]], $4, $5
-+ ; R2-R6: seb $2, $[[T0:[0-9]+]]
-+
-+ %r = sub i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @sub_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: sub_i16:
-+
-+ ; NOT-R2-R6: subu $[[T0:[0-9]+]], $4, $5
-+ ; NOT-R2-R6: sll $[[T0]], $[[T0]], 16
-+ ; NOT-R2-R6: sra $2, $[[T0]], 16
-+
-+ ; R2-R6: subu $[[T0:[0-9]+]], $4, $5
-+ ; R2-R6: seh $2, $[[T0:[0-9]+]]
-+
-+ %r = sub i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @sub_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: sub_i32:
-+
-+ ; ALL: subu $2, $4, $5
-+
-+ %r = sub i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @sub_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: sub_i64:
-+
-+ ; GP32: subu $3, $5, $7
-+ ; GP32: sltu $[[T0:[0-9]+]], $5, $7
-+ ; GP32: addu $[[T1:[0-9]+]], $[[T0]], $6
-+ ; GP32: subu $2, $4, $[[T1]]
-+
-+ ; GP64: dsubu $2, $4, $5
-+
-+ %r = sub i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @sub_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: sub_i128:
-+
-+ ; GP32: lw $[[T0:[0-9]+]], 20($sp)
-+ ; GP32: sltu $[[T1:[0-9]+]], $5, $[[T0]]
-+ ; GP32: lw $[[T2:[0-9]+]], 16($sp)
-+ ; GP32: addu $[[T3:[0-9]+]], $[[T1]], $[[T2]]
-+ ; GP32: lw $[[T4:[0-9]+]], 24($sp)
-+ ; GP32: lw $[[T5:[0-9]+]], 28($sp)
-+ ; GP32: subu $[[T6:[0-9]+]], $7, $[[T5]]
-+ ; GP32: subu $2, $4, $[[T3]]
-+ ; GP32: sltu $[[T8:[0-9]+]], $6, $[[T4]]
-+ ; GP32: addu $[[T9:[0-9]+]], $[[T8]], $[[T0]]
-+ ; GP32: subu $3, $5, $[[T9]]
-+ ; GP32: sltu $[[T10:[0-9]+]], $7, $[[T5]]
-+ ; GP32: addu $[[T11:[0-9]+]], $[[T10]], $[[T4]]
-+ ; GP32: subu $4, $6, $[[T11]]
-+ ; GP32: move $5, $[[T6]]
-+
-+ ; GP64: dsubu $3, $5, $7
-+ ; GP64: sltu $[[T0:[0-9]+]], $5, $7
-+ ; GP64: daddu $[[T1:[0-9]+]], $[[T0]], $6
-+ ; GP64: dsubu $2, $4, $[[T1]]
-+
-+ %r = sub i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/udiv.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/udiv.ll
-+++ test/CodeGen/Mips/llvm-ir/udiv.ll
-@@ -0,0 +1,108 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=R6 -check-prefix=GP32
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=R6 -check-prefix=64R6
-+
-+define zeroext i1 @udiv_i1(i1 zeroext %a, i1 zeroext %b) {
-+entry:
-+; ALL-LABEL: udiv_i1:
-+
-+ ; NOT-R6: divu $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mflo $2
-+
-+ ; R6: divu $2, $4, $5
-+ ; R6: teq $5, $zero, 7
-+
-+ %r = udiv i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define zeroext i8 @udiv_i8(i8 zeroext %a, i8 zeroext %b) {
-+entry:
-+; ALL-LABEL: udiv_i8:
-+
-+ ; NOT-R6: divu $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mflo $2
-+
-+ ; R6: divu $2, $4, $5
-+ ; R6: teq $5, $zero, 7
-+
-+ %r = udiv i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define zeroext i16 @udiv_i16(i16 zeroext %a, i16 zeroext %b) {
-+entry:
-+; ALL-LABEL: udiv_i16:
-+
-+ ; NOT-R6: divu $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mflo $2
-+
-+ ; R6: divu $2, $4, $5
-+ ; R6: teq $5, $zero, 7
-+
-+ %r = udiv i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @udiv_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: udiv_i32:
-+
-+ ; NOT-R6: divu $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mflo $2
-+
-+ ; R6: divu $2, $4, $5
-+ ; R6: teq $5, $zero, 7
-+
-+ %r = udiv i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @udiv_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: udiv_i64:
-+
-+ ; GP32: lw $25, %call16(__udivdi3)($gp)
-+
-+ ; GP64-NOT-R6: ddivu $zero, $4, $5
-+ ; GP64-NOT-R6: teq $5, $zero, 7
-+ ; GP64-NOT-R6: mflo $2
-+
-+ ; 64R6: ddivu $2, $4, $5
-+ ; 64R6: teq $5, $zero, 7
-+
-+ %r = udiv i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @udiv_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: udiv_i128:
-+
-+ ; GP32: lw $25, %call16(__udivti3)($gp)
-+
-+ ; GP64-NOT-R6: ld $25, %call16(__udivti3)($gp)
-+ ; 64-R6: ld $25, %call16(__udivti3)($gp)
-+
-+ %r = udiv i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/urem.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/urem.ll
-+++ test/CodeGen/Mips/llvm-ir/urem.ll
-@@ -0,0 +1,145 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=GP32 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=GP32 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s -check-prefix=GP32 \
-+; RUN: -check-prefix=R2 -check-prefix=R2-R6 -check-prefix=NOT-R6
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=GP32 -check-prefix=R6 -check-prefix=R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=R2 -check-prefix=R2-R6 \
-+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=64R6 -check-prefix=R6 -check-prefix=R2-R6
-+
-+define signext i1 @urem_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: urem_i1:
-+
-+ ; NOT-R6: andi $[[T0:[0-9]+]], $5, 1
-+ ; NOT-R6: andi $[[T1:[0-9]+]], $4, 1
-+ ; NOT-R6: divu $zero, $[[T1]], $[[T0]]
-+ ; NOT-R6: teq $[[T0]], $zero, 7
-+ ; NOT-R6: mfhi $[[T2:[0-9]+]]
-+ ; NOT-R6: sll $[[T3:[0-9]+]], $[[T2]], 31
-+ ; NOT-R6: sra $2, $[[T3]], 31
-+
-+ ; R6: andi $[[T0:[0-9]+]], $5, 1
-+ ; R6: andi $[[T1:[0-9]+]], $4, 1
-+ ; R6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
-+ ; R6: teq $[[T0]], $zero, 7
-+ ; R6: sll $[[T3:[0-9]+]], $[[T2]], 31
-+ ; R6: sra $2, $[[T3]], 31
-+
-+ %r = urem i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @urem_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: urem_i8:
-+
-+ ; NOT-R2-R6: andi $[[T0:[0-9]+]], $5, 255
-+ ; NOT-R2-R6: andi $[[T1:[0-9]+]], $4, 255
-+ ; NOT-R2-R6: divu $zero, $[[T1]], $[[T0]]
-+ ; NOT-R2-R6: teq $[[T0]], $zero, 7
-+ ; NOT-R2-R6: mfhi $[[T2:[0-9]+]]
-+ ; NOT-R2-R6: sll $[[T3:[0-9]+]], $[[T2]], 24
-+ ; NOT-R2-R6: sra $2, $[[T3]], 24
-+
-+ ; R2: andi $[[T0:[0-9]+]], $5, 255
-+ ; R2: andi $[[T1:[0-9]+]], $4, 255
-+ ; R2: divu $zero, $[[T1]], $[[T0]]
-+ ; R2: teq $[[T0]], $zero, 7
-+ ; R2: mfhi $[[T2:[0-9]+]]
-+ ; R2: seb $2, $[[T2]]
-+
-+ ; R6: andi $[[T0:[0-9]+]], $5, 255
-+ ; R6: andi $[[T1:[0-9]+]], $4, 255
-+ ; R6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
-+ ; R6: teq $[[T0]], $zero, 7
-+ ; R6: seb $2, $[[T2]]
-+
-+ %r = urem i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @urem_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: urem_i16:
-+
-+ ; NOT-R2-R6: andi $[[T0:[0-9]+]], $5, 65535
-+ ; NOT-R2-R6: andi $[[T1:[0-9]+]], $4, 65535
-+ ; NOT-R2-R6: divu $zero, $[[T1]], $[[T0]]
-+ ; NOT-R2-R6: teq $[[T0]], $zero, 7
-+ ; NOT-R2-R6: mfhi $[[T2:[0-9]+]]
-+ ; NOT-R2-R6: sll $[[T3:[0-9]+]], $[[T2]], 16
-+ ; NOT-R2-R6: sra $2, $[[T3]], 16
-+
-+ ; R2: andi $[[T0:[0-9]+]], $5, 65535
-+ ; R2: andi $[[T1:[0-9]+]], $4, 65535
-+ ; R2: divu $zero, $[[T1]], $[[T0]]
-+ ; R2: teq $[[T0]], $zero, 7
-+ ; R2: mfhi $[[T3:[0-9]+]]
-+ ; R2: seh $2, $[[T2]]
-+
-+ ; R6: andi $[[T0:[0-9]+]], $5, 65535
-+ ; R6: andi $[[T1:[0-9]+]], $4, 65535
-+ ; R6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
-+ ; R6: teq $[[T0]], $zero, 7
-+ ; R6: seh $2, $[[T2]]
-+
-+ %r = urem i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @urem_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: urem_i32:
-+
-+ ; NOT-R6: divu $zero, $4, $5
-+ ; NOT-R6: teq $5, $zero, 7
-+ ; NOT-R6: mfhi $2
-+
-+ ; R6: modu $2, $4, $5
-+ ; R6: teq $5, $zero, 7
-+
-+ %r = urem i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @urem_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: urem_i64:
-+
-+ ; GP32: lw $25, %call16(__umoddi3)($gp)
-+
-+ ; GP64-NOT-R6: ddivu $zero, $4, $5
-+ ; GP64-NOT-R6: teq $5, $zero, 7
-+ ; GP64-NOT-R6: mfhi $2
-+
-+ ; 64R6: dmodu $2, $4, $5
-+ ; 64R6: teq $5, $zero, 7
-+
-+ %r = urem i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @urem_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+ ; ALL-LABEL: urem_i128:
-+
-+ ; GP32: lw $25, %call16(__umodti3)($gp)
-+
-+ ; GP64-NOT-R6: ld $25, %call16(__umodti3)($gp)
-+ ; 64-R6: ld $25, %call16(__umodti3)($gp)
-+
-+ %r = urem i128 %a, %b
-+ ret i128 %r
-+}
-Index: test/CodeGen/Mips/llvm-ir/xor.ll
-===================================================================
---- test/CodeGen/Mips/llvm-ir/xor.ll
-+++ test/CodeGen/Mips/llvm-ir/xor.ll
-@@ -0,0 +1,94 @@
-+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP32
-+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
-+; RUN: -check-prefix=ALL -check-prefix=GP64
-+
-+define signext i1 @xor_i1(i1 signext %a, i1 signext %b) {
-+entry:
-+; ALL-LABEL: xor_i1:
-+
-+ ; ALL: xor $2, $4, $5
-+
-+ %r = xor i1 %a, %b
-+ ret i1 %r
-+}
-+
-+define signext i8 @xor_i8(i8 signext %a, i8 signext %b) {
-+entry:
-+; ALL-LABEL: xor_i8:
-+
-+ ; ALL: xor $2, $4, $5
-+
-+ %r = xor i8 %a, %b
-+ ret i8 %r
-+}
-+
-+define signext i16 @xor_i16(i16 signext %a, i16 signext %b) {
-+entry:
-+; ALL-LABEL: xor_i16:
-+
-+ ; ALL: xor $2, $4, $5
-+
-+ %r = xor i16 %a, %b
-+ ret i16 %r
-+}
-+
-+define signext i32 @xor_i32(i32 signext %a, i32 signext %b) {
-+entry:
-+; ALL-LABEL: xor_i32:
-+
-+ ; GP32: xor $2, $4, $5
-+
-+ ; GP64: xor $[[T0:[0-9]+]], $4, $5
-+ ; GP64: sll $2, $[[T0]], 0
-+
-+ %r = xor i32 %a, %b
-+ ret i32 %r
-+}
-+
-+define signext i64 @xor_i64(i64 signext %a, i64 signext %b) {
-+entry:
-+; ALL-LABEL: xor_i64:
-+
-+ ; GP32: xor $2, $4, $6
-+ ; GP32: xor $3, $5, $7
-+
-+ ; GP64: xor $2, $4, $5
-+
-+ %r = xor i64 %a, %b
-+ ret i64 %r
-+}
-+
-+define signext i128 @xor_i128(i128 signext %a, i128 signext %b) {
-+entry:
-+; ALL-LABEL: xor_i128:
-+
-+ ; GP32: lw $[[T0:[0-9]+]], 24($sp)
-+ ; GP32: lw $[[T1:[0-9]+]], 20($sp)
-+ ; GP32: lw $[[T2:[0-9]+]], 16($sp)
-+ ; GP32: xor $2, $4, $[[T2]]
-+ ; GP32: xor $3, $5, $[[T1]]
-+ ; GP32: xor $4, $6, $[[T0]]
-+ ; GP32: lw $[[T3:[0-9]+]], 28($sp)
-+ ; GP32: xor $5, $7, $[[T3]]
-+
-+ ; GP64: xor $2, $4, $6
-+ ; GP64: xor $3, $5, $7
-+
-+ %r = xor i128 %a, %b
-+ ret i128 %r
-+}
diff --git a/contrib/llvm/patches/patch-10-llvm-r230348-arm-fix-bad-ha.diff b/contrib/llvm/patches/patch-08-llvm-r230348-arm-fix-bad-ha.diff
index 64c558e..2896899 100644
--- a/contrib/llvm/patches/patch-10-llvm-r230348-arm-fix-bad-ha.diff
+++ b/contrib/llvm/patches/patch-08-llvm-r230348-arm-fix-bad-ha.diff
@@ -67,7 +67,7 @@ Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
}
}
-@@ -7696,11 +7696,8 @@ void SelectionDAGISel::LowerArguments(const Functi
+@@ -7697,11 +7697,8 @@ void SelectionDAGISel::LowerArguments(const Functi
}
if (F.getAttributes().hasAttribute(Idx, Attribute::Nest))
Flags.setNest();
@@ -80,7 +80,7 @@ Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Flags.setOrigAlign(OriginalAlignment);
MVT RegisterVT = TLI->getRegisterType(*CurDAG->getContext(), VT);
-@@ -7715,6 +7712,8 @@ void SelectionDAGISel::LowerArguments(const Functi
+@@ -7716,6 +7713,8 @@ void SelectionDAGISel::LowerArguments(const Functi
MyFlags.Flags.setOrigAlign(1);
Ins.push_back(MyFlags);
}
@@ -287,7 +287,7 @@ Index: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- lib/Target/ARM/ARMISelLowering.cpp
+++ lib/Target/ARM/ARMISelLowering.cpp
-@@ -11280,7 +11280,9 @@ static bool isHomogeneousAggregate(Type *Ty, HABas
+@@ -11285,7 +11285,9 @@ static bool isHomogeneousAggregate(Type *Ty, HABas
return (Members > 0 && Members <= 4);
}
@@ -298,7 +298,7 @@ Index: lib/Target/ARM/ARMISelLowering.cpp
bool ARMTargetLowering::functionArgumentNeedsConsecutiveRegisters(
Type *Ty, CallingConv::ID CallConv, bool isVarArg) const {
if (getEffectiveCallingConv(CallConv, isVarArg) !=
-@@ -11289,7 +11291,9 @@ bool ARMTargetLowering::functionArgumentNeedsConse
+@@ -11294,7 +11296,9 @@ bool ARMTargetLowering::functionArgumentNeedsConse
HABaseType Base = HA_UNKNOWN;
uint64_t Members = 0;
diff --git a/contrib/llvm/patches/patch-12-clang-r227115-constantarraytype.diff b/contrib/llvm/patches/patch-09-clang-r227115-constantarraytype.diff
index 33ca358..33ca358 100644
--- a/contrib/llvm/patches/patch-12-clang-r227115-constantarraytype.diff
+++ b/contrib/llvm/patches/patch-09-clang-r227115-constantarraytype.diff
diff --git a/contrib/llvm/patches/patch-09-llvm-r230058-indirectbrs-assert.diff b/contrib/llvm/patches/patch-09-llvm-r230058-indirectbrs-assert.diff
deleted file mode 100644
index 1d31c28..0000000
--- a/contrib/llvm/patches/patch-09-llvm-r230058-indirectbrs-assert.diff
+++ /dev/null
@@ -1,55 +0,0 @@
-Pull in r230058 from upstream llvm trunk (by Benjamin Kramer):
-
- LoopRotate: When reconstructing loop simplify form don't split edges
- from indirectbrs.
-
- Yet another chapter in the endless story. While this looks like we
- leave the loop in a non-canonical state this replicates the logic in
- LoopSimplify so it doesn't diverge from the canonical form in any way.
-
- PR21968
-
-This fixes a "Cannot split critical edge from IndirectBrInst" assertion
-failure when building the devel/radare2 port.
-
-Introduced here: https://svnweb.freebsd.org/changeset/base/279161
-
-Index: lib/Transforms/Scalar/LoopRotation.cpp
-===================================================================
---- lib/Transforms/Scalar/LoopRotation.cpp
-+++ lib/Transforms/Scalar/LoopRotation.cpp
-@@ -535,6 +535,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool Simplifi
- Loop *PredLoop = LI->getLoopFor(*PI);
- if (!PredLoop || PredLoop->contains(Exit))
- continue;
-+ if (isa<IndirectBrInst>((*PI)->getTerminator()))
-+ continue;
- SplitLatchEdge |= L->getLoopLatch() == *PI;
- BasicBlock *ExitSplit = SplitCriticalEdge(*PI, Exit, this);
- ExitSplit->moveBefore(Exit);
-Index: test/Transforms/LoopRotate/crash.ll
-===================================================================
---- test/Transforms/LoopRotate/crash.ll
-+++ test/Transforms/LoopRotate/crash.ll
-@@ -153,3 +153,21 @@ entry:
- "5": ; preds = %"3", %entry
- ret void
- }
-+
-+; PR21968
-+define void @test8(i1 %C, i8* %P) #0 {
-+entry:
-+ br label %for.cond
-+
-+for.cond: ; preds = %for.inc, %entry
-+ br i1 %C, label %l_bad, label %for.body
-+
-+for.body: ; preds = %for.cond
-+ indirectbr i8* %P, [label %for.inc, label %l_bad]
-+
-+for.inc: ; preds = %for.body
-+ br label %for.cond
-+
-+l_bad: ; preds = %for.body, %for.cond
-+ ret void
-+}
diff --git a/contrib/llvm/patches/patch-11-llvm-r231227-aarch64-tls-relocs.diff b/contrib/llvm/patches/patch-11-llvm-r231227-aarch64-tls-relocs.diff
deleted file mode 100644
index 5c0edca..0000000
--- a/contrib/llvm/patches/patch-11-llvm-r231227-aarch64-tls-relocs.diff
+++ /dev/null
@@ -1,811 +0,0 @@
-Pull in r231227 from upstream llvm trunk (by Kristof Beyls):
-
- Fix PR22408 - LLVM producing AArch64 TLS relocations that GNU linkers
- cannot handle yet.
-
- As is described at http://llvm.org/bugs/show_bug.cgi?id=22408, the
- GNU linkers ld.bfd and ld.gold currently only support a subset of the
- whole range of AArch64 ELF TLS relocations. Furthermore, they assume
- that some of the code sequences to access thread-local variables are
- produced in a very specific sequence. When the sequence is not as the
- linker expects, it can silently mis-relaxe/mis-optimize the
- instructions.
- Even if that wouldn't be the case, it's good to produce the exact
- sequence, as that ensures that linkers can perform optimizing
- relaxations.
-
- This patch:
-
- * implements support for 16MiB TLS area size instead of 4GiB TLS area
- size. Ideally clang would grow an -mtls-size option to allow
- support for both, but that's not part of this patch.
- * by default doesn't produce local dynamic access patterns, as even
- modern ld.bfd and ld.gold linkers do not support the associated
- relocations. An option (-aarch64-elf-ldtls-generation) is added to
- enable generation of local dynamic code sequence, but is off by
- default.
- * makes sure that the exact expected code sequence for local dynamic
- and general dynamic accesses is produced, by making use of a new
- pseudo instruction. The patch also removes two
- (AArch64ISD::TLSDESC_BLR, AArch64ISD::TLSDESC_CALL) pre-existing
- AArch64-specific pseudo SDNode instructions that are superseded by
- the new one (TLSDESC_CALLSEQ).
-
-Introduced here: https://svnweb.freebsd.org/changeset/base/280865
-
-Index: lib/Target/AArch64/AArch64AsmPrinter.cpp
-===================================================================
---- lib/Target/AArch64/AArch64AsmPrinter.cpp
-+++ lib/Target/AArch64/AArch64AsmPrinter.cpp
-@@ -12,6 +12,8 @@
- //
- //===----------------------------------------------------------------------===//
-
-+#include "MCTargetDesc/AArch64AddressingModes.h"
-+#include "MCTargetDesc/AArch64MCExpr.h"
- #include "AArch64.h"
- #include "AArch64MCInstLower.h"
- #include "AArch64MachineFunctionInfo.h"
-@@ -494,12 +496,47 @@ void AArch64AsmPrinter::EmitInstruction(const Mach
- EmitToStreamer(OutStreamer, TmpInst);
- return;
- }
-- case AArch64::TLSDESC_BLR: {
-- MCOperand Callee, Sym;
-- MCInstLowering.lowerOperand(MI->getOperand(0), Callee);
-- MCInstLowering.lowerOperand(MI->getOperand(1), Sym);
-+ case AArch64::TLSDESC_CALLSEQ: {
-+ /// lower this to:
-+ /// adrp x0, :tlsdesc:var
-+ /// ldr x1, [x0, #:tlsdesc_lo12:var]
-+ /// add x0, x0, #:tlsdesc_lo12:var
-+ /// .tlsdesccall var
-+ /// blr x1
-+ /// (TPIDR_EL0 offset now in x0)
-+ const MachineOperand &MO_Sym = MI->getOperand(0);
-+ MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
-+ MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
-+ MO_TLSDESC_LO12.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGEOFF |
-+ AArch64II::MO_NC);
-+ MO_TLSDESC.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGE);
-+ MCInstLowering.lowerOperand(MO_Sym, Sym);
-+ MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
-+ MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
-
-- // First emit a relocation-annotation. This expands to no code, but requests
-+ MCInst Adrp;
-+ Adrp.setOpcode(AArch64::ADRP);
-+ Adrp.addOperand(MCOperand::CreateReg(AArch64::X0));
-+ Adrp.addOperand(SymTLSDesc);
-+ EmitToStreamer(OutStreamer, Adrp);
-+
-+ MCInst Ldr;
-+ Ldr.setOpcode(AArch64::LDRXui);
-+ Ldr.addOperand(MCOperand::CreateReg(AArch64::X1));
-+ Ldr.addOperand(MCOperand::CreateReg(AArch64::X0));
-+ Ldr.addOperand(SymTLSDescLo12);
-+ Ldr.addOperand(MCOperand::CreateImm(0));
-+ EmitToStreamer(OutStreamer, Ldr);
-+
-+ MCInst Add;
-+ Add.setOpcode(AArch64::ADDXri);
-+ Add.addOperand(MCOperand::CreateReg(AArch64::X0));
-+ Add.addOperand(MCOperand::CreateReg(AArch64::X0));
-+ Add.addOperand(SymTLSDescLo12);
-+ Add.addOperand(MCOperand::CreateImm(AArch64_AM::getShiftValue(0)));
-+ EmitToStreamer(OutStreamer, Add);
-+
-+ // Emit a relocation-annotation. This expands to no code, but requests
- // the following instruction gets an R_AARCH64_TLSDESC_CALL.
- MCInst TLSDescCall;
- TLSDescCall.setOpcode(AArch64::TLSDESCCALL);
-@@ -506,12 +543,10 @@ void AArch64AsmPrinter::EmitInstruction(const Mach
- TLSDescCall.addOperand(Sym);
- EmitToStreamer(OutStreamer, TLSDescCall);
-
-- // Other than that it's just a normal indirect call to the function loaded
-- // from the descriptor.
-- MCInst BLR;
-- BLR.setOpcode(AArch64::BLR);
-- BLR.addOperand(Callee);
-- EmitToStreamer(OutStreamer, BLR);
-+ MCInst Blr;
-+ Blr.setOpcode(AArch64::BLR);
-+ Blr.addOperand(MCOperand::CreateReg(AArch64::X1));
-+ EmitToStreamer(OutStreamer, Blr);
-
- return;
- }
-Index: lib/Target/AArch64/AArch64CleanupLocalDynamicTLSPass.cpp
-===================================================================
---- lib/Target/AArch64/AArch64CleanupLocalDynamicTLSPass.cpp
-+++ lib/Target/AArch64/AArch64CleanupLocalDynamicTLSPass.cpp
-@@ -62,10 +62,10 @@ struct LDTLSCleanup : public MachineFunctionPass {
- for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;
- ++I) {
- switch (I->getOpcode()) {
-- case AArch64::TLSDESC_BLR:
-+ case AArch64::TLSDESC_CALLSEQ:
- // Make sure it's a local dynamic access.
-- if (!I->getOperand(1).isSymbol() ||
-- strcmp(I->getOperand(1).getSymbolName(), "_TLS_MODULE_BASE_"))
-+ if (!I->getOperand(0).isSymbol() ||
-+ strcmp(I->getOperand(0).getSymbolName(), "_TLS_MODULE_BASE_"))
- break;
-
- if (TLSBaseAddrReg)
-Index: lib/Target/AArch64/AArch64ISelLowering.cpp
-===================================================================
---- lib/Target/AArch64/AArch64ISelLowering.cpp
-+++ lib/Target/AArch64/AArch64ISelLowering.cpp
-@@ -64,10 +64,18 @@ EnableAArch64ExtrGeneration("aarch64-extr-generati
-
- static cl::opt<bool>
- EnableAArch64SlrGeneration("aarch64-shift-insert-generation", cl::Hidden,
-- cl::desc("Allow AArch64 SLI/SRI formation"),
-- cl::init(false));
-+ cl::desc("Allow AArch64 SLI/SRI formation"),
-+ cl::init(false));
-
-+// FIXME: The necessary dtprel relocations don't seem to be supported
-+// well in the GNU bfd and gold linkers at the moment. Therefore, by
-+// default, for now, fall back to GeneralDynamic code generation.
-+cl::opt<bool> EnableAArch64ELFLocalDynamicTLSGeneration(
-+ "aarch64-elf-ldtls-generation", cl::Hidden,
-+ cl::desc("Allow AArch64 Local Dynamic TLS code generation"),
-+ cl::init(false));
-
-+
- AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM)
- : TargetLowering(TM) {
- Subtarget = &TM.getSubtarget<AArch64Subtarget>();
-@@ -760,7 +768,7 @@ const char *AArch64TargetLowering::getTargetNodeNa
- case AArch64ISD::CSNEG: return "AArch64ISD::CSNEG";
- case AArch64ISD::CSINC: return "AArch64ISD::CSINC";
- case AArch64ISD::THREAD_POINTER: return "AArch64ISD::THREAD_POINTER";
-- case AArch64ISD::TLSDESC_CALL: return "AArch64ISD::TLSDESC_CALL";
-+ case AArch64ISD::TLSDESC_CALLSEQ: return "AArch64ISD::TLSDESC_CALLSEQ";
- case AArch64ISD::ADC: return "AArch64ISD::ADC";
- case AArch64ISD::SBC: return "AArch64ISD::SBC";
- case AArch64ISD::ADDS: return "AArch64ISD::ADDS";
-@@ -3049,61 +3057,34 @@ AArch64TargetLowering::LowerDarwinGlobalTLSAddress
- /// When accessing thread-local variables under either the general-dynamic or
- /// local-dynamic system, we make a "TLS-descriptor" call. The variable will
- /// have a descriptor, accessible via a PC-relative ADRP, and whose first entry
--/// is a function pointer to carry out the resolution. This function takes the
--/// address of the descriptor in X0 and returns the TPIDR_EL0 offset in X0. All
--/// other registers (except LR, NZCV) are preserved.
-+/// is a function pointer to carry out the resolution.
- ///
--/// Thus, the ideal call sequence on AArch64 is:
-+/// The sequence is:
-+/// adrp x0, :tlsdesc:var
-+/// ldr x1, [x0, #:tlsdesc_lo12:var]
-+/// add x0, x0, #:tlsdesc_lo12:var
-+/// .tlsdesccall var
-+/// blr x1
-+/// (TPIDR_EL0 offset now in x0)
- ///
--/// adrp x0, :tlsdesc:thread_var
--/// ldr x8, [x0, :tlsdesc_lo12:thread_var]
--/// add x0, x0, :tlsdesc_lo12:thread_var
--/// .tlsdesccall thread_var
--/// blr x8
--/// (TPIDR_EL0 offset now in x0).
--///
--/// The ".tlsdesccall" directive instructs the assembler to insert a particular
--/// relocation to help the linker relax this sequence if it turns out to be too
--/// conservative.
--///
--/// FIXME: we currently produce an extra, duplicated, ADRP instruction, but this
--/// is harmless.
--SDValue AArch64TargetLowering::LowerELFTLSDescCall(SDValue SymAddr,
-- SDValue DescAddr, SDLoc DL,
-- SelectionDAG &DAG) const {
-+/// The above sequence must be produced unscheduled, to enable the linker to
-+/// optimize/relax this sequence.
-+/// Therefore, a pseudo-instruction (TLSDESC_CALLSEQ) is used to represent the
-+/// above sequence, and expanded really late in the compilation flow, to ensure
-+/// the sequence is produced as per above.
-+SDValue AArch64TargetLowering::LowerELFTLSDescCallSeq(SDValue SymAddr, SDLoc DL,
-+ SelectionDAG &DAG) const {
- EVT PtrVT = getPointerTy();
-
-- // The function we need to call is simply the first entry in the GOT for this
-- // descriptor, load it in preparation.
-- SDValue Func = DAG.getNode(AArch64ISD::LOADgot, DL, PtrVT, SymAddr);
-+ SDValue Chain = DAG.getEntryNode();
-+ SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
-
-- // TLS calls preserve all registers except those that absolutely must be
-- // trashed: X0 (it takes an argument), LR (it's a call) and NZCV (let's not be
-- // silly).
-- const TargetRegisterInfo *TRI =
-- getTargetMachine().getSubtargetImpl()->getRegisterInfo();
-- const AArch64RegisterInfo *ARI =
-- static_cast<const AArch64RegisterInfo *>(TRI);
-- const uint32_t *Mask = ARI->getTLSCallPreservedMask();
--
-- // The function takes only one argument: the address of the descriptor itself
-- // in X0.
-- SDValue Glue, Chain;
-- Chain = DAG.getCopyToReg(DAG.getEntryNode(), DL, AArch64::X0, DescAddr, Glue);
-- Glue = Chain.getValue(1);
--
-- // We're now ready to populate the argument list, as with a normal call:
-- SmallVector<SDValue, 6> Ops;
-+ SmallVector<SDValue, 2> Ops;
- Ops.push_back(Chain);
-- Ops.push_back(Func);
- Ops.push_back(SymAddr);
-- Ops.push_back(DAG.getRegister(AArch64::X0, PtrVT));
-- Ops.push_back(DAG.getRegisterMask(Mask));
-- Ops.push_back(Glue);
-
-- SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
-- Chain = DAG.getNode(AArch64ISD::TLSDESC_CALL, DL, NodeTys, Ops);
-- Glue = Chain.getValue(1);
-+ Chain = DAG.getNode(AArch64ISD::TLSDESC_CALLSEQ, DL, NodeTys, Ops);
-+ SDValue Glue = Chain.getValue(1);
-
- return DAG.getCopyFromReg(Chain, DL, AArch64::X0, PtrVT, Glue);
- }
-@@ -3114,9 +3095,18 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD
- assert(Subtarget->isTargetELF() && "This function expects an ELF target");
- assert(getTargetMachine().getCodeModel() == CodeModel::Small &&
- "ELF TLS only supported in small memory model");
-+ // Different choices can be made for the maximum size of the TLS area for a
-+ // module. For the small address model, the default TLS size is 16MiB and the
-+ // maximum TLS size is 4GiB.
-+ // FIXME: add -mtls-size command line option and make it control the 16MiB
-+ // vs. 4GiB code sequence generation.
- const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
-
- TLSModel::Model Model = getTargetMachine().getTLSModel(GA->getGlobal());
-+ if (!EnableAArch64ELFLocalDynamicTLSGeneration) {
-+ if (Model == TLSModel::LocalDynamic)
-+ Model = TLSModel::GeneralDynamic;
-+ }
-
- SDValue TPOff;
- EVT PtrVT = getPointerTy();
-@@ -3127,17 +3117,20 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD
-
- if (Model == TLSModel::LocalExec) {
- SDValue HiVar = DAG.getTargetGlobalAddress(
-- GV, DL, PtrVT, 0, AArch64II::MO_TLS | AArch64II::MO_G1);
-+ GV, DL, PtrVT, 0, AArch64II::MO_TLS | AArch64II::MO_HI12);
- SDValue LoVar = DAG.getTargetGlobalAddress(
- GV, DL, PtrVT, 0,
-- AArch64II::MO_TLS | AArch64II::MO_G0 | AArch64II::MO_NC);
-+ AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
-
-- TPOff = SDValue(DAG.getMachineNode(AArch64::MOVZXi, DL, PtrVT, HiVar,
-- DAG.getTargetConstant(16, MVT::i32)),
-- 0);
-- TPOff = SDValue(DAG.getMachineNode(AArch64::MOVKXi, DL, PtrVT, TPOff, LoVar,
-- DAG.getTargetConstant(0, MVT::i32)),
-- 0);
-+ SDValue TPWithOff_lo =
-+ SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, ThreadBase,
-+ HiVar, DAG.getTargetConstant(0, MVT::i32)),
-+ 0);
-+ SDValue TPWithOff =
-+ SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPWithOff_lo,
-+ LoVar, DAG.getTargetConstant(0, MVT::i32)),
-+ 0);
-+ return TPWithOff;
- } else if (Model == TLSModel::InitialExec) {
- TPOff = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, AArch64II::MO_TLS);
- TPOff = DAG.getNode(AArch64ISD::LOADgot, DL, PtrVT, TPOff);
-@@ -3152,19 +3145,6 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD
- DAG.getMachineFunction().getInfo<AArch64FunctionInfo>();
- MFI->incNumLocalDynamicTLSAccesses();
-
-- // Accesses used in this sequence go via the TLS descriptor which lives in
-- // the GOT. Prepare an address we can use to handle this.
-- SDValue HiDesc = DAG.getTargetExternalSymbol(
-- "_TLS_MODULE_BASE_", PtrVT, AArch64II::MO_TLS | AArch64II::MO_PAGE);
-- SDValue LoDesc = DAG.getTargetExternalSymbol(
-- "_TLS_MODULE_BASE_", PtrVT,
-- AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
--
-- // First argument to the descriptor call is the address of the descriptor
-- // itself.
-- SDValue DescAddr = DAG.getNode(AArch64ISD::ADRP, DL, PtrVT, HiDesc);
-- DescAddr = DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, DescAddr, LoDesc);
--
- // The call needs a relocation too for linker relaxation. It doesn't make
- // sense to call it MO_PAGE or MO_PAGEOFF though so we need another copy of
- // the address.
-@@ -3173,40 +3153,23 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD
-
- // Now we can calculate the offset from TPIDR_EL0 to this module's
- // thread-local area.
-- TPOff = LowerELFTLSDescCall(SymAddr, DescAddr, DL, DAG);
-+ TPOff = LowerELFTLSDescCallSeq(SymAddr, DL, DAG);
-
- // Now use :dtprel_whatever: operations to calculate this variable's offset
- // in its thread-storage area.
- SDValue HiVar = DAG.getTargetGlobalAddress(
-- GV, DL, MVT::i64, 0, AArch64II::MO_TLS | AArch64II::MO_G1);
-+ GV, DL, MVT::i64, 0, AArch64II::MO_TLS | AArch64II::MO_HI12);
- SDValue LoVar = DAG.getTargetGlobalAddress(
- GV, DL, MVT::i64, 0,
-- AArch64II::MO_TLS | AArch64II::MO_G0 | AArch64II::MO_NC);
-+ AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
-
-- SDValue DTPOff =
-- SDValue(DAG.getMachineNode(AArch64::MOVZXi, DL, PtrVT, HiVar,
-- DAG.getTargetConstant(16, MVT::i32)),
-- 0);
-- DTPOff =
-- SDValue(DAG.getMachineNode(AArch64::MOVKXi, DL, PtrVT, DTPOff, LoVar,
-- DAG.getTargetConstant(0, MVT::i32)),
-- 0);
--
-- TPOff = DAG.getNode(ISD::ADD, DL, PtrVT, TPOff, DTPOff);
-+ TPOff = SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPOff, HiVar,
-+ DAG.getTargetConstant(0, MVT::i32)),
-+ 0);
-+ TPOff = SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPOff, LoVar,
-+ DAG.getTargetConstant(0, MVT::i32)),
-+ 0);
- } else if (Model == TLSModel::GeneralDynamic) {
-- // Accesses used in this sequence go via the TLS descriptor which lives in
-- // the GOT. Prepare an address we can use to handle this.
-- SDValue HiDesc = DAG.getTargetGlobalAddress(
-- GV, DL, PtrVT, 0, AArch64II::MO_TLS | AArch64II::MO_PAGE);
-- SDValue LoDesc = DAG.getTargetGlobalAddress(
-- GV, DL, PtrVT, 0,
-- AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
--
-- // First argument to the descriptor call is the address of the descriptor
-- // itself.
-- SDValue DescAddr = DAG.getNode(AArch64ISD::ADRP, DL, PtrVT, HiDesc);
-- DescAddr = DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, DescAddr, LoDesc);
--
- // The call needs a relocation too for linker relaxation. It doesn't make
- // sense to call it MO_PAGE or MO_PAGEOFF though so we need another copy of
- // the address.
-@@ -3214,7 +3177,7 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD
- DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, AArch64II::MO_TLS);
-
- // Finally we can make a call to calculate the offset from tpidr_el0.
-- TPOff = LowerELFTLSDescCall(SymAddr, DescAddr, DL, DAG);
-+ TPOff = LowerELFTLSDescCallSeq(SymAddr, DL, DAG);
- } else
- llvm_unreachable("Unsupported ELF TLS access model");
-
-Index: lib/Target/AArch64/AArch64ISelLowering.h
-===================================================================
---- lib/Target/AArch64/AArch64ISelLowering.h
-+++ lib/Target/AArch64/AArch64ISelLowering.h
-@@ -29,9 +29,9 @@ enum {
- WrapperLarge, // 4-instruction MOVZ/MOVK sequence for 64-bit addresses.
- CALL, // Function call.
-
-- // Almost the same as a normal call node, except that a TLSDesc relocation is
-- // needed so the linker can relax it correctly if possible.
-- TLSDESC_CALL,
-+ // Produces the full sequence of instructions for getting the thread pointer
-+ // offset of a variable into X0, using the TLSDesc model.
-+ TLSDESC_CALLSEQ,
- ADRP, // Page address of a TargetGlobalAddress operand.
- ADDlow, // Add the low 12 bits of a TargetGlobalAddress operand.
- LOADgot, // Load from automatically generated descriptor (e.g. Global
-@@ -399,8 +399,8 @@ class AArch64TargetLowering : public TargetLowerin
- SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerDarwinGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerELFGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
-- SDValue LowerELFTLSDescCall(SDValue SymAddr, SDValue DescAddr, SDLoc DL,
-- SelectionDAG &DAG) const;
-+ SDValue LowerELFTLSDescCallSeq(SDValue SymAddr, SDLoc DL,
-+ SelectionDAG &DAG) const;
- SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
-Index: lib/Target/AArch64/AArch64InstrInfo.td
-===================================================================
---- lib/Target/AArch64/AArch64InstrInfo.td
-+++ lib/Target/AArch64/AArch64InstrInfo.td
-@@ -96,6 +96,19 @@ def SDT_AArch64ITOF : SDTypeProfile<1, 1, [SDTCis
-
- def SDT_AArch64TLSDescCall : SDTypeProfile<0, -2, [SDTCisPtrTy<0>,
- SDTCisPtrTy<1>]>;
-+
-+// Generates the general dynamic sequences, i.e.
-+// adrp x0, :tlsdesc:var
-+// ldr x1, [x0, #:tlsdesc_lo12:var]
-+// add x0, x0, #:tlsdesc_lo12:var
-+// .tlsdesccall var
-+// blr x1
-+
-+// (the TPIDR_EL0 offset is put directly in X0, hence no "result" here)
-+// number of operands (the variable)
-+def SDT_AArch64TLSDescCallSeq : SDTypeProfile<0,1,
-+ [SDTCisPtrTy<0>]>;
-+
- def SDT_AArch64WrapperLarge : SDTypeProfile<1, 4,
- [SDTCisVT<0, i64>, SDTCisVT<1, i32>,
- SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>,
-@@ -229,11 +242,12 @@ def AArch64Prefetch : SDNode<"AArch64ISD::P
- def AArch64sitof: SDNode<"AArch64ISD::SITOF", SDT_AArch64ITOF>;
- def AArch64uitof: SDNode<"AArch64ISD::UITOF", SDT_AArch64ITOF>;
-
--def AArch64tlsdesc_call : SDNode<"AArch64ISD::TLSDESC_CALL",
-- SDT_AArch64TLSDescCall,
-- [SDNPInGlue, SDNPOutGlue, SDNPHasChain,
-- SDNPVariadic]>;
-+def AArch64tlsdesc_callseq : SDNode<"AArch64ISD::TLSDESC_CALLSEQ",
-+ SDT_AArch64TLSDescCallSeq,
-+ [SDNPInGlue, SDNPOutGlue, SDNPHasChain,
-+ SDNPVariadic]>;
-
-+
- def AArch64WrapperLarge : SDNode<"AArch64ISD::WrapperLarge",
- SDT_AArch64WrapperLarge>;
-
-@@ -1049,15 +1063,16 @@ def TLSDESCCALL : Pseudo<(outs), (ins i64imm:$sym)
- let AsmString = ".tlsdesccall $sym";
- }
-
--// Pseudo-instruction representing a BLR with attached TLSDESC relocation. It
--// gets expanded to two MCInsts during lowering.
--let isCall = 1, Defs = [LR] in
--def TLSDESC_BLR
-- : Pseudo<(outs), (ins GPR64:$dest, i64imm:$sym),
-- [(AArch64tlsdesc_call GPR64:$dest, tglobaltlsaddr:$sym)]>;
-+// FIXME: maybe the scratch register used shouldn't be fixed to X1?
-+// FIXME: can "hasSideEffects be dropped?
-+let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1,
-+ isCodeGenOnly = 1 in
-+def TLSDESC_CALLSEQ
-+ : Pseudo<(outs), (ins i64imm:$sym),
-+ [(AArch64tlsdesc_callseq tglobaltlsaddr:$sym)]>;
-+def : Pat<(AArch64tlsdesc_callseq texternalsym:$sym),
-+ (TLSDESC_CALLSEQ texternalsym:$sym)>;
-
--def : Pat<(AArch64tlsdesc_call GPR64:$dest, texternalsym:$sym),
-- (TLSDESC_BLR GPR64:$dest, texternalsym:$sym)>;
- //===----------------------------------------------------------------------===//
- // Conditional branch (immediate) instruction.
- //===----------------------------------------------------------------------===//
-Index: lib/Target/AArch64/AArch64MCInstLower.cpp
-===================================================================
---- lib/Target/AArch64/AArch64MCInstLower.cpp
-+++ lib/Target/AArch64/AArch64MCInstLower.cpp
-@@ -22,9 +22,12 @@
- #include "llvm/MC/MCExpr.h"
- #include "llvm/MC/MCInst.h"
- #include "llvm/Support/CodeGen.h"
-+#include "llvm/Support/CommandLine.h"
- #include "llvm/Target/TargetMachine.h"
- using namespace llvm;
-
-+extern cl::opt<bool> EnableAArch64ELFLocalDynamicTLSGeneration;
-+
- AArch64MCInstLower::AArch64MCInstLower(MCContext &ctx, AsmPrinter &printer)
- : Ctx(ctx), Printer(printer), TargetTriple(printer.getTargetTriple()) {}
-
-@@ -84,10 +87,16 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandEL
- if (MO.isGlobal()) {
- const GlobalValue *GV = MO.getGlobal();
- Model = Printer.TM.getTLSModel(GV);
-+ if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
-+ Model == TLSModel::LocalDynamic)
-+ Model = TLSModel::GeneralDynamic;
-+
- } else {
- assert(MO.isSymbol() &&
- StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
- "unexpected external TLS symbol");
-+ // The general dynamic access sequence is used to get the
-+ // address of _TLS_MODULE_BASE_.
- Model = TLSModel::GeneralDynamic;
- }
- switch (Model) {
-@@ -123,6 +132,8 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandEL
- RefFlags |= AArch64MCExpr::VK_G1;
- else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
- RefFlags |= AArch64MCExpr::VK_G0;
-+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_HI12)
-+ RefFlags |= AArch64MCExpr::VK_HI12;
-
- if (MO.getTargetFlags() & AArch64II::MO_NC)
- RefFlags |= AArch64MCExpr::VK_NC;
-Index: lib/Target/AArch64/Utils/AArch64BaseInfo.h
-===================================================================
---- lib/Target/AArch64/Utils/AArch64BaseInfo.h
-+++ lib/Target/AArch64/Utils/AArch64BaseInfo.h
-@@ -1229,7 +1229,7 @@ namespace AArch64II {
-
- MO_NO_FLAG,
-
-- MO_FRAGMENT = 0x7,
-+ MO_FRAGMENT = 0xf,
-
- /// MO_PAGE - A symbol operand with this flag represents the pc-relative
- /// offset of the 4K page containing the symbol. This is used with the
-@@ -1257,26 +1257,31 @@ namespace AArch64II {
- /// 0-15 of a 64-bit address, used in a MOVZ or MOVK instruction
- MO_G0 = 6,
-
-+ /// MO_HI12 - This flag indicates that a symbol operand represents the bits
-+ /// 13-24 of a 64-bit address, used in a arithmetic immediate-shifted-left-
-+ /// by-12-bits instruction.
-+ MO_HI12 = 7,
-+
- /// MO_GOT - This flag indicates that a symbol operand represents the
- /// address of the GOT entry for the symbol, rather than the address of
- /// the symbol itself.
-- MO_GOT = 8,
-+ MO_GOT = 0x10,
-
- /// MO_NC - Indicates whether the linker is expected to check the symbol
- /// reference for overflow. For example in an ADRP/ADD pair of relocations
- /// the ADRP usually does check, but not the ADD.
-- MO_NC = 0x10,
-+ MO_NC = 0x20,
-
- /// MO_TLS - Indicates that the operand being accessed is some kind of
- /// thread-local symbol. On Darwin, only one type of thread-local access
- /// exists (pre linker-relaxation), but on ELF the TLSModel used for the
- /// referee will affect interpretation.
-- MO_TLS = 0x20,
-+ MO_TLS = 0x40,
-
- /// MO_CONSTPOOL - This flag indicates that a symbol operand represents
- /// the address of a constant pool entry for the symbol, rather than the
- /// address of the symbol itself.
-- MO_CONSTPOOL = 0x40
-+ MO_CONSTPOOL = 0x80
- };
- } // end namespace AArch64II
-
-Index: test/CodeGen/AArch64/arm64-tls-dynamics.ll
-===================================================================
---- test/CodeGen/AArch64/arm64-tls-dynamics.ll
-+++ test/CodeGen/AArch64/arm64-tls-dynamics.ll
-@@ -1,5 +1,7 @@
--; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s
--; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s
-+; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -verify-machineinstrs < %s | FileCheck %s
-+; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s
-+; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-NOLD %s
-+; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-NOLD-RELOC %s
-
- @general_dynamic_var = external thread_local global i32
-
-@@ -9,22 +11,34 @@ define i32 @test_generaldynamic() {
- %val = load i32* @general_dynamic_var
- ret i32 %val
-
-- ; FIXME: the adrp instructions are redundant (if harmless).
--; CHECK: adrp [[TLSDESC_HI:x[0-9]+]], :tlsdesc:general_dynamic_var
--; CHECK: add x0, [[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var
- ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var
--; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var]
--; CHECK: .tlsdesccall general_dynamic_var
-+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var]
-+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var
-+; CHECK-NEXT: .tlsdesccall general_dynamic_var
- ; CHECK-NEXT: blr [[CALLEE]]
-
-+; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var
-+; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var]
-+; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var
-+; CHECK-NOLD-NEXT: .tlsdesccall general_dynamic_var
-+; CHECK-NOLD-NEXT: blr [[CALLEE]]
-+
-+
- ; CHECK: mrs x[[TP:[0-9]+]], TPIDR_EL0
- ; CHECK: ldr w0, [x[[TP]], x0]
-+; CHECK-NOLD: mrs x[[TP:[0-9]+]], TPIDR_EL0
-+; CHECK-NOLD: ldr w0, [x[[TP]], x0]
-
- ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
-+; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
- ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
--; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
- ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
-
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL
-+
- }
-
- define i32* @test_generaldynamic_addr() {
-@@ -32,12 +46,10 @@ define i32* @test_generaldynamic_addr() {
-
- ret i32* @general_dynamic_var
-
-- ; FIXME: the adrp instructions are redundant (if harmless).
--; CHECK: adrp [[TLSDESC_HI:x[0-9]+]], :tlsdesc:general_dynamic_var
--; CHECK: add x0, [[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var
- ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var
--; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var]
--; CHECK: .tlsdesccall general_dynamic_var
-+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var]
-+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var
-+; CHECK-NEXT: .tlsdesccall general_dynamic_var
- ; CHECK-NEXT: blr [[CALLEE]]
-
- ; CHECK: mrs [[TP:x[0-9]+]], TPIDR_EL0
-@@ -44,9 +56,15 @@ define i32* @test_generaldynamic_addr() {
- ; CHECK: add x0, [[TP]], x0
-
- ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
-+; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
- ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
--; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
- ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
-+
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL
-+
- }
-
- @local_dynamic_var = external thread_local(localdynamic) global i32
-@@ -58,54 +76,71 @@ define i32 @test_localdynamic() {
- ret i32 %val
-
- ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
--; CHECK: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_
--; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
--; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
--; CHECK: .tlsdesccall _TLS_MODULE_BASE_
-+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
-+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_
-+; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_
- ; CHECK-NEXT: blr [[CALLEE]]
-+; CHECK-NEXT: add x[[TPOFF:[0-9]+]], x0, :dtprel_hi12:local_dynamic_var
-+; CHECK-NEXT: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var
-+; CHECK: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
-+; CHECK: ldr w0, [x[[TPIDR]], x[[TPOFF]]]
-
--; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var
--; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var
-+; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:local_dynamic_var
-+; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var]
-+; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var
-+; CHECK-NOLD-NEXT: .tlsdesccall local_dynamic_var
-+; CHECK-NOLD-NEXT: blr [[CALLEE]]
-+; CHECK-NOLD: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
-+; CHECK-NOLD: ldr w0, [x[[TPIDR]], x0]
-
--; CHECK: add x[[TPREL:[0-9]+]], x0, [[DTP_OFFSET]]
-
--; CHECK: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
--
--; CHECK: ldr w0, [x[[TPIDR]], x[[TPREL]]]
--
- ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
-+; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
- ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
--; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
- ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
-+; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_HI12
-+; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
-
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL
-+
- }
-
- define i32* @test_localdynamic_addr() {
- ; CHECK-LABEL: test_localdynamic_addr:
-
-- ret i32* @local_dynamic_var
--
- ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
--; CHECK: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_
--; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
--; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
--; CHECK: .tlsdesccall _TLS_MODULE_BASE_
-+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
-+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_
-+; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_
- ; CHECK-NEXT: blr [[CALLEE]]
-+; CHECK-NEXT: add x[[TPOFF:[0-9]+]], x0, :dtprel_hi12:local_dynamic_var
-+; CHECK-NEXT: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var
-+; CHECK: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
-+; CHECK: add x0, x[[TPIDR]], x[[TPOFF]]
-
--; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var
--; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var
-+; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:local_dynamic_var
-+; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var]
-+; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var
-+; CHECK-NOLD-NEXT: .tlsdesccall local_dynamic_var
-+; CHECK-NOLD-NEXT: blr [[CALLEE]]
-+; CHECK-NOLD: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
-+; CHECK-NOLD: add x0, x[[TPIDR]], x0
-+ ret i32* @local_dynamic_var
-
--; CHECK: add [[TPREL:x[0-9]+]], x0, [[DTP_OFFSET]]
--
--; CHECK: mrs [[TPIDR:x[0-9]+]], TPIDR_EL0
--
--; CHECK: add x0, [[TPIDR]], [[TPREL]]
--
- ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
-+; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
- ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
--; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
- ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
-+; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_HI12
-+; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
-
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
-+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL
- }
-
- ; The entire point of the local-dynamic access model is to have a single call to
-@@ -122,11 +157,10 @@ define i32 @test_localdynamic_deduplicate() {
- %sum = add i32 %val, %val2
- ret i32 %sum
-
--; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
--; CHECK: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_
--; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
--; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
--; CHECK: .tlsdesccall _TLS_MODULE_BASE_
-+; CHECK: adrp x[[DTPREL_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
-+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[DTPREL_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
-+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE
-+; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_
- ; CHECK-NEXT: blr [[CALLEE]]
-
- ; CHECK-NOT: _TLS_MODULE_BASE_
-Index: test/CodeGen/AArch64/arm64-tls-execs.ll
-===================================================================
---- test/CodeGen/AArch64/arm64-tls-execs.ll
-+++ test/CodeGen/AArch64/arm64-tls-execs.ll
-@@ -38,14 +38,13 @@ define i32 @test_local_exec() {
- ; CHECK-LABEL: test_local_exec:
- %val = load i32* @local_exec_var
-
--; CHECK: movz [[TP_OFFSET:x[0-9]+]], #:tprel_g1:local_exec_var // encoding: [0bAAA{{[01]+}},A,0b101AAAAA,0x92]
--; CHECK: movk [[TP_OFFSET]], #:tprel_g0_nc:local_exec_var
--; CHECK: mrs x[[TP:[0-9]+]], TPIDR_EL0
--; CHECK: ldr w0, [x[[TP]], [[TP_OFFSET]]]
-+; CHECK: mrs x[[R1:[0-9]+]], TPIDR_EL0
-+; CHECK: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var
-+; CHECK: add x[[R3:[0-9]+]], x[[R2]], :tprel_lo12_nc:local_exec_var
-+; CHECK: ldr w0, [x[[R3]]]
-
--; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G1
--; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G0_NC
--
-+; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12
-+; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- ret i32 %val
- }
-
-@@ -53,11 +52,11 @@ define i32* @test_local_exec_addr() {
- ; CHECK-LABEL: test_local_exec_addr:
- ret i32* @local_exec_var
-
--; CHECK: movz [[TP_OFFSET:x[0-9]+]], #:tprel_g1:local_exec_var
--; CHECK: movk [[TP_OFFSET]], #:tprel_g0_nc:local_exec_var
--; CHECK: mrs [[TP:x[0-9]+]], TPIDR_EL0
--; CHECK: add x0, [[TP]], [[TP_OFFSET]]
-+; CHECK: mrs x[[R1:[0-9]+]], TPIDR_EL0
-+; CHECK: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var
-+; CHECK: add x0, x[[R2]], :tprel_lo12_nc:local_exec_var
-+; CHECK: ret
-
--; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G1
--; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G0_NC
-+; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12
-+; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
- }
diff --git a/contrib/llvm/patches/patch-13-llvm-r229911-uleb128-commas.diff b/contrib/llvm/patches/patch-13-llvm-r229911-uleb128-commas.diff
deleted file mode 100644
index bf13463..0000000
--- a/contrib/llvm/patches/patch-13-llvm-r229911-uleb128-commas.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-Pull in r229911 from upstream llvm trunk (by Benjamin Kramer):
-
- MC: Allow multiple comma-separated expressions on the .uleb128 directive.
-
- For compatiblity with GNU as. Binutils documents this as
- '.uleb128 expressions'. Subtle, isn't it?
-
-Introduced here: http://svnweb.freebsd.org/changeset/base/281775
-
-Index: lib/MC/MCParser/AsmParser.cpp
-===================================================================
---- lib/MC/MCParser/AsmParser.cpp
-+++ lib/MC/MCParser/AsmParser.cpp
-@@ -3636,22 +3636,28 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVa
- }
-
- /// parseDirectiveLEB128
--/// ::= (.sleb128 | .uleb128) expression
-+/// ::= (.sleb128 | .uleb128) [ expression (, expression)* ]
- bool AsmParser::parseDirectiveLEB128(bool Signed) {
- checkForValidSection();
- const MCExpr *Value;
-
-- if (parseExpression(Value))
-- return true;
-+ for (;;) {
-+ if (parseExpression(Value))
-+ return true;
-
-- if (getLexer().isNot(AsmToken::EndOfStatement))
-- return TokError("unexpected token in directive");
-+ if (Signed)
-+ getStreamer().EmitSLEB128Value(Value);
-+ else
-+ getStreamer().EmitULEB128Value(Value);
-
-- if (Signed)
-- getStreamer().EmitSLEB128Value(Value);
-- else
-- getStreamer().EmitULEB128Value(Value);
-+ if (getLexer().is(AsmToken::EndOfStatement))
-+ break;
-
-+ if (getLexer().isNot(AsmToken::Comma))
-+ return TokError("unexpected token in directive");
-+ Lex();
-+ }
-+
- return false;
- }
-
-Index: test/MC/ELF/uleb.s
-===================================================================
---- test/MC/ELF/uleb.s
-+++ test/MC/ELF/uleb.s
-@@ -11,16 +11,17 @@ foo:
- .uleb128 128
- .uleb128 16383
- .uleb128 16384
-+ .uleb128 23, 42
-
- // ELF_32: Name: .text
- // ELF_32: SectionData (
--// ELF_32: 0000: 00017F80 01FF7F80 8001
-+// ELF_32: 0000: 00017F80 01FF7F80 8001172A
- // ELF_32: )
- // ELF_64: Name: .text
- // ELF_64: SectionData (
--// ELF_64: 0000: 00017F80 01FF7F80 8001
-+// ELF_64: 0000: 00017F80 01FF7F80 8001172A
- // ELF_64: )
- // MACHO_32: ('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
--// MACHO_32: ('_section_data', '00017f80 01ff7f80 8001')
-+// MACHO_32: ('_section_data', '00017f80 01ff7f80 8001172a')
- // MACHO_64: ('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
--// MACHO_64: ('_section_data', '00017f80 01ff7f80 8001')
-+// MACHO_64: ('_section_data', '00017f80 01ff7f80 8001172a')
OpenPOWER on IntegriCloud