summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h3
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h11
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunction.h17
-rw-r--r--contrib/llvm/lib/CodeGen/MachineFunction.cpp5
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp41
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp11
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp14
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp11
-rw-r--r--contrib/llvm/lib/MC/MCParser/AsmParser.cpp5
-rw-r--r--contrib/llvm/lib/Target/X86/X86FrameLowering.cpp2
-rw-r--r--contrib/llvm/lib/Target/X86/X86RegisterInfo.cpp21
-rw-r--r--contrib/llvm/patches/README.TXT16
-rw-r--r--contrib/llvm/patches/patch-r208961-clang-version-include.diff39
-rw-r--r--contrib/llvm/patches/patch-r208987-format-extensions.diff214
-rw-r--r--contrib/llvm/patches/patch-r209107-clang-vendor-suffix.diff22
-rw-r--r--contrib/llvm/patches/patch-r213492-amd64-multi-os-dot.diff18
-rw-r--r--contrib/llvm/patches/patch-r221503-default-target-triple.diff26
-rw-r--r--contrib/llvm/patches/patch-r243830-arm-disable-clear-cache.diff19
-rw-r--r--contrib/llvm/patches/patch-r252503-arm-transient-stack-alignment.diff79
-rw-r--r--contrib/llvm/patches/patch-r257109-add-CC-aliases.diff25
-rw-r--r--contrib/llvm/patches/patch-r259053-gcc-installation-detector.diff63
-rw-r--r--contrib/llvm/patches/patch-r259498-add-fxsave.diff16
-rw-r--r--contrib/llvm/patches/patch-r261680-clang-r200899-fix-security-quantis.diff63
-rw-r--r--contrib/llvm/patches/patch-r261991-llvm-r195391-fix-dwarf2.diff540
-rw-r--r--contrib/llvm/patches/patch-r261991-llvm-r198385-fix-dwarf2.diff91
-rw-r--r--contrib/llvm/patches/patch-r261991-llvm-r198389-fix-dwarf2.diff105
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198028-sparc.diff258
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198029-sparc.diff210
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff678
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff166
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198149-sparc.diff54
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198157-sparc.diff368
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198280-sparc.diff55
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff99
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198286-sparc.diff231
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff213
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198484-sparc.diff844
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff516
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198565-sparc.diff76
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198567-sparc.diff21
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198580-sparc.diff460
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff762
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198592-sparc.diff33
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff359
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198681-sparc.diff298
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198738-sparc.diff734
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198739-sparc.diff19
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198740-sparc.diff115
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198893-sparc.diff236
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff229
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198910-sparc.diff463
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199014-sparc.diff133
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199024-sparc.diff69
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199028-sparc.diff147
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199031-sparc.diff42
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff944
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199061-sparc.diff126
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199186-sparc.diff28
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff81
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff200
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff142
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199786-sparc.diff55
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199940-sparc.diff21
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199974-sparc.diff54
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199975-sparc.diff344
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199977-sparc.diff377
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200103-sparc.diff49
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200104-sparc.diff18
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200112-sparc.diff169
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200130-sparc.diff45
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200131-sparc.diff117
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200141-sparc.diff67
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200282-sparc.diff183
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200368-sparc.diff88
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200373-sparc.diff296
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200376-sparc.diff76
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200509-sparc.diff73
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200617-sparc.diff97
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200960-sparc.diff512
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200961-sparc.diff443
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff378
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200963-sparc.diff131
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r200965-sparc.diff33
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r198311-sparc.diff31
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r198312-sparc.diff19
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r198911-sparc.diff46
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r198912-sparc.diff44
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r198918-sparc.diff59
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r198923-sparc.diff49
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r199012-sparc.diff41
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r199034-sparc.diff81
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff53
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r199188-sparc.diff35
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r199399-sparc.diff37
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r200452-sparc.diff20
-rw-r--r--contrib/llvm/patches/patch-r262264-llvm-r200453-sparc.diff91
-rw-r--r--contrib/llvm/patches/patch-r262265-llvm-r201718-sparc.diff40
-rw-r--r--contrib/llvm/patches/patch-r262303-enable-ppc-integrated-as.diff25
-rw-r--r--contrib/llvm/patches/patch-r262415-llvm-r201994-sparc.diff49
-rw-r--r--contrib/llvm/patches/patch-r262460-llvm-r202059-sparc.diff62
-rw-r--r--contrib/llvm/patches/patch-r262535-clang-r202177-sparc.diff84
-rw-r--r--contrib/llvm/patches/patch-r262536-clang-r202179-sparc.diff22
-rw-r--r--contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff89
-rw-r--r--contrib/llvm/patches/patch-r262611-llvm-r196874-fix-invalid-pwd-crash.diff76
-rw-r--r--contrib/llvm/patches/patch-r262809-clang-r203007-destructor-calling-conv.diff61
-rw-r--r--contrib/llvm/patches/patch-r263048-clang-r203624-fix-CC-aliases.diff24
-rw-r--r--contrib/llvm/patches/patch-r263312-llvm-r169939-inline-asm-with-realign.diff338
-rw-r--r--contrib/llvm/patches/patch-r263312-llvm-r196940-update-inline-asm-test.diff78
-rw-r--r--contrib/llvm/patches/patch-r263312-llvm-r196986-allow-realign-alloca.diff98
-rw-r--r--contrib/llvm/patches/patch-r263312-llvm-r202930-fix-alloca-esi-clobber.diff263
-rw-r--r--contrib/llvm/patches/patch-r263313-llvm-r203311-fix-sse1-oom.diff60
111 files changed, 16451 insertions, 36 deletions
diff --git a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
index 50d320f..854cac2 100644
--- a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -41,6 +41,7 @@ class MachineBasicBlock;
class MachineFunction;
class MachineModuleInfo;
class MachineRegisterInfo;
+class SelectionDAG;
class TargetLowering;
class Value;
@@ -125,7 +126,7 @@ public:
/// set - Initialize this FunctionLoweringInfo with the given Function
/// and its associated MachineFunction.
///
- void set(const Function &Fn, MachineFunction &MF);
+ void set(const Function &Fn, MachineFunction &MF, SelectionDAG *DAG);
/// clear - Clear out all the function-specific state. This returns this
/// FunctionLoweringInfo to an empty state, ready to be used for a
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index 022634d..ba536e7 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -223,6 +223,10 @@ class MachineFrameInfo {
/// Whether the "realign-stack" option is on.
bool RealignOption;
+ /// True if the function includes inline assembly that adjusts the stack
+ /// pointer.
+ bool HasInlineAsmWithSPAdjust;
+
const TargetFrameLowering *getFrameLowering() const;
public:
explicit MachineFrameInfo(const TargetMachine &TM, bool RealignOpt)
@@ -240,6 +244,7 @@ public:
LocalFrameSize = 0;
LocalFrameMaxAlign = 0;
UseLocalStackAllocationBlock = false;
+ HasInlineAsmWithSPAdjust = false;
}
/// hasStackObjects - Return true if there are any stack objects in this
@@ -451,6 +456,10 @@ public:
bool hasCalls() const { return HasCalls; }
void setHasCalls(bool V) { HasCalls = V; }
+ /// Returns true if the function contains any stack-adjusting inline assembly.
+ bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; }
+ void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; }
+
/// getMaxCallFrameSize - Return the maximum size of a call frame that must be
/// allocated for an outgoing function call. This is only available if
/// CallFrameSetup/Destroy pseudo instructions are used by the target, and
@@ -521,7 +530,7 @@ public:
/// variable sized object is created, whether or not the index returned is
/// actually used.
///
- int CreateVariableSizedObject(unsigned Alignment);
+ int CreateVariableSizedObject(unsigned Alignment, const AllocaInst *Alloca);
/// getCalleeSavedInfo - Returns a reference to call saved info vector for the
/// current function.
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
index c886e25..43b370c 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -131,8 +131,8 @@ class MachineFunction {
/// about the control flow of such functions.
bool ExposesReturnsTwice;
- /// True if the function includes MS-style inline assembly.
- bool HasMSInlineAsm;
+ /// True if the function includes any inline assembly.
+ bool HasInlineAsm;
MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
@@ -218,15 +218,14 @@ public:
ExposesReturnsTwice = B;
}
- /// Returns true if the function contains any MS-style inline assembly.
- bool hasMSInlineAsm() const {
- return HasMSInlineAsm;
+ /// Returns true if the function contains any inline assembly.
+ bool hasInlineAsm() const {
+ return HasInlineAsm;
}
- /// Set a flag that indicates that the function contains MS-style inline
- /// assembly.
- void setHasMSInlineAsm(bool B) {
- HasMSInlineAsm = B;
+ /// Set a flag that indicates that the function contains inline assembly.
+ void setHasInlineAsm(bool B) {
+ HasInlineAsm = B;
}
/// getInfo - Keep track of various per-function pieces of information for
diff --git a/contrib/llvm/lib/CodeGen/MachineFunction.cpp b/contrib/llvm/lib/CodeGen/MachineFunction.cpp
index 0703df0..f3be318 100644
--- a/contrib/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineFunction.cpp
@@ -525,13 +525,14 @@ int MachineFrameInfo::CreateSpillStackObject(uint64_t Size,
/// variable sized object is created, whether or not the index returned is
/// actually used.
///
-int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment) {
+int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment,
+ const AllocaInst *Alloca) {
HasVarSizedObjects = true;
Alignment =
clampStackAlignment(!getFrameLowering()->isStackRealignable() ||
!RealignOption,
Alignment, getFrameLowering()->getStackAlignment());
- Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0));
+ Objects.push_back(StackObject(0, Alignment, 0, false, false, true, Alloca));
ensureMaxAlignment(Alignment);
return (int)Objects.size()-NumFixedObjects-1;
}
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index 4309dc1..e9d2324 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -33,6 +33,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
@@ -55,7 +56,8 @@ static bool isUsedOutsideOfDefiningBlock(const Instruction *I) {
return false;
}
-void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) {
+void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
+ SelectionDAG *DAG) {
const TargetLowering *TLI = TM.getTargetLowering();
Fn = &fn;
@@ -100,6 +102,43 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) {
for (; BB != EB; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
+ // Look for dynamic allocas.
+ if (const AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
+ if (!AI->isStaticAlloca()) {
+ unsigned Align = std::max(
+ (unsigned)TLI->getDataLayout()->getPrefTypeAlignment(
+ AI->getAllocatedType()),
+ AI->getAlignment());
+ unsigned StackAlign = TM.getFrameLowering()->getStackAlignment();
+ if (Align <= StackAlign)
+ Align = 0;
+ // Inform the Frame Information that we have variable-sized objects.
+ MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1, AI);
+ }
+ }
+
+ // Look for inline asm that clobbers the SP register.
+ if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
+ ImmutableCallSite CS(I);
+ if (const InlineAsm *IA = dyn_cast<InlineAsm>(CS.getCalledValue())) {
+ unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
+ std::vector<TargetLowering::AsmOperandInfo> Ops =
+ TLI->ParseConstraints(CS);
+ for (size_t I = 0, E = Ops.size(); I != E; ++I) {
+ TargetLowering::AsmOperandInfo &Op = Ops[I];
+ if (Op.Type == InlineAsm::isClobber) {
+ // Clobbers don't have SDValue operands, hence SDValue().
+ TLI->ComputeConstraintToUse(Op, SDValue(), DAG);
+ std::pair<unsigned, const TargetRegisterClass*> PhysReg =
+ TLI->getRegForInlineAsmConstraint(Op.ConstraintCode,
+ Op.ConstraintVT);
+ if (PhysReg.first == SP)
+ MF->getFrameInfo()->setHasInlineAsmWithSPAdjust(true);
+ }
+ }
+ }
+ }
+
// Mark values used outside their block as exported, by allocating
// a virtual register for them.
if (isUsedOutsideOfDefiningBlock(I))
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index f7a3e3d..5f4ff75 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -2180,6 +2180,17 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) {
if (getTypeAction(CondVT) == TargetLowering::TypeWidenVector)
Cond1 = GetWidenedVector(Cond1);
+ // If we have to split the condition there is no point in widening the
+ // select. This would result in an cycle of widening the select ->
+ // widening the condition operand -> splitting the condition operand ->
+ // splitting the select -> widening the select. Instead split this select
+ // further and widen the resulting type.
+ if (getTypeAction(CondVT) == TargetLowering::TypeSplitVector) {
+ SDValue SplitSelect = SplitVecOp_VSELECT(N, 0);
+ SDValue Res = ModifyToType(SplitSelect, WidenVT);
+ return Res;
+ }
+
if (Cond1.getValueType() != CondWidenVT)
Cond1 = ModifyToType(Cond1, CondWidenVT);
}
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 2b2713d..41662a9 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -851,12 +851,20 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching,
SDValue Res = DAG.getTargetConstant(Flag, MVT::i32);
Ops.push_back(Res);
+ unsigned SP = TLI.getStackPointerRegisterToSaveRestore();
for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) {
unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), ValueVTs[Value]);
MVT RegisterVT = RegVTs[Value];
for (unsigned i = 0; i != NumRegs; ++i) {
assert(Reg < Regs.size() && "Mismatch in # registers expected");
- Ops.push_back(DAG.getRegister(Regs[Reg++], RegisterVT));
+ unsigned TheReg = Regs[Reg++];
+ Ops.push_back(DAG.getRegister(TheReg, RegisterVT));
+
+ if (TheReg == SP && Code == InlineAsm::Kind_Clobber) {
+ // If we clobbered the stack pointer, MFI should know about it.
+ assert(DAG.getMachineFunction().getFrameInfo()->
+ hasInlineAsmWithSPAdjust());
+ }
}
}
}
@@ -3370,9 +3378,7 @@ void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) {
setValue(&I, DSA);
DAG.setRoot(DSA.getValue(1));
- // Inform the Frame Information that we have just allocated a variable-sized
- // object.
- FuncInfo.MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1);
+ assert(FuncInfo.MF->getFrameInfo()->hasVarSizedObjects());
}
void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 3a0cfa1..b8b4db4 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -419,7 +419,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
SplitCriticalSideEffectEdges(const_cast<Function&>(Fn), this);
CurDAG->init(*MF, TTI, TLI);
- FuncInfo->set(Fn, *MF);
+ FuncInfo->set(Fn, *MF, CurDAG);
if (UseMBPI && OptLevel != CodeGenOpt::None)
FuncInfo->BPI = &getAnalysis<BranchProbabilityInfo>();
@@ -428,7 +428,8 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
SDB->init(GFI, *AA, LibInfo);
- MF->setHasMSInlineAsm(false);
+ MF->setHasInlineAsm(false);
+
SelectAllBasicBlocks(Fn);
// If the first basic block in the function has live ins that need to be
@@ -511,7 +512,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E;
++I) {
- if (MFI->hasCalls() && MF->hasMSInlineAsm())
+ if (MFI->hasCalls() && MF->hasInlineAsm())
break;
const MachineBasicBlock *MBB = I;
@@ -522,8 +523,8 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
II->isStackAligningInlineAsm()) {
MFI->setHasCalls(true);
}
- if (II->isMSInlineAsm()) {
- MF->setHasMSInlineAsm(true);
+ if (II->isInlineAsm()) {
+ MF->setHasInlineAsm(true);
}
}
}
diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
index a91bd93..8fe39c8 100644
--- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -4192,6 +4192,11 @@ bool AsmParser::parseMSInlineAsm(
AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size()));
}
}
+
+ // Consider implicit defs to be clobbers. Think of cpuid and push.
+ const uint16_t *ImpDefs = Desc.getImplicitDefs();
+ for (unsigned I = 0, E = Desc.getNumImplicitDefs(); I != E; ++I)
+ ClobberRegs.push_back(ImpDefs[I]);
}
// Set the number of Outputs and Inputs.
diff --git a/contrib/llvm/lib/Target/X86/X86FrameLowering.cpp b/contrib/llvm/lib/Target/X86/X86FrameLowering.cpp
index a06ba9d..0d76534 100644
--- a/contrib/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/contrib/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -50,7 +50,7 @@ bool X86FrameLowering::hasFP(const MachineFunction &MF) const {
return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
RegInfo->needsStackRealignment(MF) ||
MFI->hasVarSizedObjects() ||
- MFI->isFrameAddressTaken() || MF.hasMSInlineAsm() ||
+ MFI->isFrameAddressTaken() || MFI->hasInlineAsmWithSPAdjust() ||
MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
MMI.callsUnwindInit() || MMI.callsEHReturn());
}
diff --git a/contrib/llvm/lib/Target/X86/X86RegisterInfo.cpp b/contrib/llvm/lib/Target/X86/X86RegisterInfo.cpp
index dbda556..e6cd593 100644
--- a/contrib/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/contrib/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -403,18 +403,15 @@ bool X86RegisterInfo::hasBasePointer(const MachineFunction &MF) const {
if (!EnableBasePointer)
return false;
- // When we need stack realignment and there are dynamic allocas, we can't
- // reference off of the stack pointer, so we reserve a base pointer.
- //
- // This is also true if the function contain MS-style inline assembly. We
- // do this because if any stack changes occur in the inline assembly, e.g.,
- // "pusha", then any C local variable or C argument references in the
- // inline assembly will be wrong because the SP is not properly tracked.
- if ((needsStackRealignment(MF) && MFI->hasVarSizedObjects()) ||
- MF.hasMSInlineAsm())
- return true;
-
- return false;
+ // When we need stack realignment, we can't address the stack from the frame
+ // pointer. When we have dynamic allocas or stack-adjusting inline asm, we
+ // can't address variables from the stack pointer. MS inline asm can
+ // reference locals while also adjusting the stack pointer. When we can't
+ // use both the SP and the FP, we need a separate base pointer register.
+ bool CantUseFP = needsStackRealignment(MF);
+ bool CantUseSP =
+ MFI->hasVarSizedObjects() || MFI->hasInlineAsmWithSPAdjust();
+ return CantUseFP && CantUseSP;
}
bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
diff --git a/contrib/llvm/patches/README.TXT b/contrib/llvm/patches/README.TXT
new file mode 100644
index 0000000..b9ad69c
--- /dev/null
+++ b/contrib/llvm/patches/README.TXT
@@ -0,0 +1,16 @@
+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.4 release source tree, for example
+by doing:
+
+svn co https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_34/final llvm-3.4-final
+svn co https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_34/final llvm-3.4-final/tools/clang
+cd llvm-3.4-final
+for p in /usr/src/contrib/llvm/patches/patch-*.diff; do
+ patch -p0 -f -F0 -E -i $p -s || break
+done
+
+A number of these consist of hand-written modifications, specifically for
+FreeBSD, while most others are cherry pickings off the llvm and clang trunks.
+When a new version of llvm/clang is eventually imported, those latter ones will
+largely disappear.
diff --git a/contrib/llvm/patches/patch-r208961-clang-version-include.diff b/contrib/llvm/patches/patch-r208961-clang-version-include.diff
new file mode 100644
index 0000000..fb0ac18
--- /dev/null
+++ b/contrib/llvm/patches/patch-r208961-clang-version-include.diff
@@ -0,0 +1,39 @@
+This patch adjusts clang's default include paths to add FreeBSD-specific
+directories.
+
+Introduced here: http://svn.freebsd.org/changeset/base/208961
+
+Index: tools/clang/lib/Frontend/InitHeaderSearch.cpp
+===================================================================
+--- tools/clang/lib/Frontend/InitHeaderSearch.cpp
++++ tools/clang/lib/Frontend/InitHeaderSearch.cpp
+@@ -14,6 +14,7 @@
+ #include "clang/Frontend/Utils.h"
+ #include "clang/Basic/FileManager.h"
+ #include "clang/Basic/LangOptions.h"
++#include "clang/Basic/Version.h"
+ #include "clang/Config/config.h" // C_INCLUDE_DIRS
+ #include "clang/Lex/HeaderSearch.h"
+ #include "clang/Lex/HeaderSearchOptions.h"
+@@ -333,6 +334,9 @@ void InitHeaderSearch::AddDefaultCIncludePaths(con
+ #endif
+ }
+ break;
++ case llvm::Triple::FreeBSD:
++ AddPath("/usr/include/clang/" CLANG_VERSION_STRING, System, false);
++ break;
+
+ default:
+ break;
+@@ -423,11 +427,6 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple
+ else
+ AddPath("/usr/include/c++/4.4", CXXSystem, false);
+ break;
+- case llvm::Triple::FreeBSD:
+- // FreeBSD 8.0
+- // FreeBSD 7.3
+- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple);
+- break;
+ case llvm::Triple::OpenBSD: {
+ std::string t = triple.getTriple();
+ if (t.substr(0, 6) == "x86_64")
diff --git a/contrib/llvm/patches/patch-r208987-format-extensions.diff b/contrib/llvm/patches/patch-r208987-format-extensions.diff
new file mode 100644
index 0000000..b01553e
--- /dev/null
+++ b/contrib/llvm/patches/patch-r208987-format-extensions.diff
@@ -0,0 +1,214 @@
+This patch adds support for the FreeBSD-specific -fformat-extension option,
+which enables additional printf modifiers for the kernel.
+
+Introduced here: http://svn.freebsd.org/changeset/base/208987
+
+Index: tools/clang/lib/Frontend/CompilerInvocation.cpp
+===================================================================
+--- tools/clang/lib/Frontend/CompilerInvocation.cpp
++++ tools/clang/lib/Frontend/CompilerInvocation.cpp
+@@ -1319,6 +1319,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgLi
+ Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
+ Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
+ Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
++ Opts.FormatExtensions = Args.hasArg(OPT_fformat_extensions);
+ Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
+ Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
+ Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
+Index: tools/clang/lib/Analysis/FormatString.cpp
+===================================================================
+--- tools/clang/lib/Analysis/FormatString.cpp
++++ tools/clang/lib/Analysis/FormatString.cpp
+@@ -548,6 +548,11 @@ const char *ConversionSpecifier::toString() const
+ // Objective-C specific specifiers.
+ case ObjCObjArg: return "@";
+
++ // FreeBSD specific specifiers.
++ case FreeBSDbArg: return "b";
++ case FreeBSDDArg: return "D";
++ case FreeBSDrArg: return "r";
++
+ // GlibC specific specifiers.
+ case PrintErrno: return "m";
+ }
+@@ -626,6 +631,7 @@ bool FormatSpecifier::hasValidLengthModifier(const
+ case ConversionSpecifier::xArg:
+ case ConversionSpecifier::XArg:
+ case ConversionSpecifier::nArg:
++ case ConversionSpecifier::FreeBSDrArg:
+ return true;
+ default:
+ return false;
+@@ -654,6 +660,7 @@ bool FormatSpecifier::hasValidLengthModifier(const
+ case ConversionSpecifier::nArg:
+ case ConversionSpecifier::cArg:
+ case ConversionSpecifier::sArg:
++ case ConversionSpecifier::FreeBSDrArg:
+ case ConversionSpecifier::ScanListArg:
+ return true;
+ default:
+@@ -774,6 +781,9 @@ bool FormatSpecifier::hasStandardConversionSpecifi
+ case ConversionSpecifier::SArg:
+ return LangOpt.ObjC1 || LangOpt.ObjC2;
+ case ConversionSpecifier::InvalidSpecifier:
++ case ConversionSpecifier::FreeBSDbArg:
++ case ConversionSpecifier::FreeBSDDArg:
++ case ConversionSpecifier::FreeBSDrArg:
+ case ConversionSpecifier::PrintErrno:
+ case ConversionSpecifier::DArg:
+ case ConversionSpecifier::OArg:
+Index: tools/clang/lib/Analysis/PrintfFormatString.cpp
+===================================================================
+--- tools/clang/lib/Analysis/PrintfFormatString.cpp
++++ tools/clang/lib/Analysis/PrintfFormatString.cpp
+@@ -198,10 +198,25 @@ static PrintfSpecifierResult ParsePrintfSpecifier(
+ case '@': k = ConversionSpecifier::ObjCObjArg; break;
+ // Glibc specific.
+ case 'm': k = ConversionSpecifier::PrintErrno; break;
++ // FreeBSD format extensions
++ case 'b':
++ if (LO.FormatExtensions)
++ k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
++ break;
++ case 'r':
++ if (LO.FormatExtensions)
++ k = ConversionSpecifier::FreeBSDrArg;
++ break;
++ case 'y':
++ if (LO.FormatExtensions)
++ k = ConversionSpecifier::iArg;
++ break;
+ // Apple-specific
+ case 'D':
+ if (Target.getTriple().isOSDarwin())
+ k = ConversionSpecifier::DArg;
++ else if (LO.FormatExtensions)
++ k = ConversionSpecifier::FreeBSDDArg; // u_char * followed by char *
+ break;
+ case 'O':
+ if (Target.getTriple().isOSDarwin())
+@@ -216,6 +231,10 @@ static PrintfSpecifierResult ParsePrintfSpecifier(
+ FS.setConversionSpecifier(CS);
+ if (CS.consumesDataArgument() && !FS.usesPositionalArg())
+ FS.setArgIndex(argIndex++);
++ // FreeBSD extension
++ if (k == ConversionSpecifier::FreeBSDbArg ||
++ k == ConversionSpecifier::FreeBSDDArg)
++ argIndex++;
+
+ if (k == ConversionSpecifier::InvalidSpecifier) {
+ // Assume the conversion takes one argument.
+@@ -618,6 +637,7 @@ bool PrintfSpecifier::hasValidPlusPrefix() const {
+ case ConversionSpecifier::GArg:
+ case ConversionSpecifier::aArg:
+ case ConversionSpecifier::AArg:
++ case ConversionSpecifier::FreeBSDrArg:
+ return true;
+
+ default:
+@@ -643,6 +663,7 @@ bool PrintfSpecifier::hasValidAlternativeForm() co
+ case ConversionSpecifier::FArg:
+ case ConversionSpecifier::gArg:
+ case ConversionSpecifier::GArg:
++ case ConversionSpecifier::FreeBSDrArg:
+ return true;
+
+ default:
+Index: tools/clang/lib/Sema/SemaChecking.cpp
+===================================================================
+--- tools/clang/lib/Sema/SemaChecking.cpp
++++ tools/clang/lib/Sema/SemaChecking.cpp
+@@ -2980,6 +2980,40 @@ CheckPrintfHandler::HandlePrintfSpecifier(const an
+ CoveredArgs.set(argIndex);
+ }
+
++ // FreeBSD extensions
++ if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
++ CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
++ // claim the second argument
++ CoveredArgs.set(argIndex + 1);
++
++ // Now type check the data expression that matches the
++ // format specifier.
++ const Expr *Ex = getDataArg(argIndex);
++ const analyze_printf::ArgType &AT =
++ (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
++ ArgType(S.Context.IntTy) : ArgType::CStrTy;
++ if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType()))
++ S.Diag(getLocationOfByte(CS.getStart()),
++ diag::warn_printf_conversion_argument_type_mismatch)
++ << AT.getRepresentativeType(S.Context) << Ex->getType()
++ << getSpecifierRange(startSpecifier, specifierLen)
++ << Ex->getSourceRange();
++
++ // Now type check the data expression that matches the
++ // format specifier.
++ Ex = getDataArg(argIndex + 1);
++ const analyze_printf::ArgType &AT2 = ArgType::CStrTy;
++ if (AT2.isValid() && !AT2.matchesType(S.Context, Ex->getType()))
++ S.Diag(getLocationOfByte(CS.getStart()),
++ diag::warn_printf_conversion_argument_type_mismatch)
++ << AT2.getRepresentativeType(S.Context) << Ex->getType()
++ << getSpecifierRange(startSpecifier, specifierLen)
++ << Ex->getSourceRange();
++
++ return true;
++ }
++ // END OF FREEBSD EXTENSIONS
++
+ // Check for using an Objective-C specific conversion specifier
+ // in a non-ObjC literal.
+ if (!ObjCContext && CS.isObjCArg()) {
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -2991,6 +2991,7 @@ void Clang::ConstructJob(Compilation &C, const Job
+
+ // Forward -f (flag) options which we can pass directly.
+ Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
++ Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions);
+ Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
+ Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info);
+ Args.AddLastArg(CmdArgs, options::OPT_fno_limit_debug_info);
+Index: tools/clang/include/clang/Basic/LangOptions.def
+===================================================================
+--- tools/clang/include/clang/Basic/LangOptions.def
++++ tools/clang/include/clang/Basic/LangOptions.def
+@@ -84,6 +84,7 @@ LANGOPT(TraditionalCPP , 1, 0, "traditional CPP
+ LANGOPT(RTTI , 1, 1, "run-time type information")
+ LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout")
+ LANGOPT(Freestanding, 1, 0, "freestanding implementation")
++LANGOPT(FormatExtensions , 1, 0, "FreeBSD format extensions")
+ LANGOPT(NoBuiltin , 1, 0, "disable builtin functions")
+ LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
+
+Index: tools/clang/include/clang/Analysis/Analyses/FormatString.h
+===================================================================
+--- tools/clang/include/clang/Analysis/Analyses/FormatString.h
++++ tools/clang/include/clang/Analysis/Analyses/FormatString.h
+@@ -158,6 +158,11 @@ class ConversionSpecifier {
+ ObjCObjArg, // '@'
+ ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
+
++ // FreeBSD specific specifiers
++ FreeBSDbArg,
++ FreeBSDDArg,
++ FreeBSDrArg,
++
+ // GlibC specific specifiers.
+ PrintErrno, // 'm'
+
+Index: tools/clang/include/clang/Driver/Options.td
+===================================================================
+--- tools/clang/include/clang/Driver/Options.td
++++ tools/clang/include/clang/Driver/Options.td
+@@ -530,6 +530,8 @@ def fno_rewrite_includes : Flag<["-"], "fno-rewrit
+
+ def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Assert that the compilation takes place in a freestanding environment">;
++def fformat_extensions: Flag<["-"], "fformat-extensions">, Group<f_Group>, Flags<[CC1Option]>,
++ HelpText<"Enable FreeBSD kernel specific format string extensions">;
+ def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Allow GNU-extension keywords regardless of language standard">;
+ def fgnu89_inline : Flag<["-"], "fgnu89-inline">, Group<f_Group>, Flags<[CC1Option]>,
diff --git a/contrib/llvm/patches/patch-r209107-clang-vendor-suffix.diff b/contrib/llvm/patches/patch-r209107-clang-vendor-suffix.diff
new file mode 100644
index 0000000..d761f78
--- /dev/null
+++ b/contrib/llvm/patches/patch-r209107-clang-vendor-suffix.diff
@@ -0,0 +1,22 @@
+This patch adds a FreeBSD-specific suffix to clang's version string. This is
+usually of the form "(yyyyddmm)", representing the date when the compiler was
+last updated.
+
+Introduced here: http://svn.freebsd.org/changeset/base/209107
+
+Index: tools/clang/lib/Basic/Version.cpp
+===================================================================
+--- tools/clang/lib/Basic/Version.cpp
++++ tools/clang/lib/Basic/Version.cpp
+@@ -124,8 +124,10 @@ std::string getClangFullVersion() {
+ OS << "clang version " CLANG_VERSION_STRING " "
+ << getClangFullRepositoryVersion();
+
++#ifdef CLANG_VENDOR_SUFFIX
++ OS << CLANG_VENDOR_SUFFIX;
++#elif defined(CLANG_VENDOR)
+ // If vendor supplied, include the base LLVM version as well.
+-#ifdef CLANG_VENDOR
+ OS << " (based on LLVM " << PACKAGE_VERSION << ")";
+ #endif
+
diff --git a/contrib/llvm/patches/patch-r213492-amd64-multi-os-dot.diff b/contrib/llvm/patches/patch-r213492-amd64-multi-os-dot.diff
new file mode 100644
index 0000000..36bf317
--- /dev/null
+++ b/contrib/llvm/patches/patch-r213492-amd64-multi-os-dot.diff
@@ -0,0 +1,18 @@
+This patch makes "clang -print-multi-os-directory" print "." on amd64, which is
+required by certain ports.
+
+Introduced here: http://svn.freebsd.org/changeset/base/213492
+
+Index: tools/clang/lib/Driver/Driver.cpp
+===================================================================
+--- tools/clang/lib/Driver/Driver.cpp
++++ tools/clang/lib/Driver/Driver.cpp
+@@ -780,7 +780,7 @@ bool Driver::HandleImmediateArgs(const Compilation
+ break;
+
+ case llvm::Triple::x86_64:
+- llvm::outs() << "x86_64" << "\n";
++ llvm::outs() << "." << "\n";
+ break;
+
+ case llvm::Triple::ppc64:
diff --git a/contrib/llvm/patches/patch-r221503-default-target-triple.diff b/contrib/llvm/patches/patch-r221503-default-target-triple.diff
new file mode 100644
index 0000000..d59cce9
--- /dev/null
+++ b/contrib/llvm/patches/patch-r221503-default-target-triple.diff
@@ -0,0 +1,26 @@
+This patch ensures the target triple that is passed during the compiler build is
+respected, instead of mangling it.
+
+Introduced here: http://svn.freebsd.org/changeset/base/221503
+
+Index: lib/Support/Unix/Host.inc
+===================================================================
+--- lib/Support/Unix/Host.inc
++++ lib/Support/Unix/Host.inc
+@@ -26,6 +26,11 @@
+
+ using namespace llvm;
+
++#ifdef __FreeBSD__
++std::string sys::getDefaultTargetTriple() {
++ return LLVM_DEFAULT_TARGET_TRIPLE;
++}
++#else // __FreeBSD__
+ static std::string getOSVersion() {
+ struct utsname info;
+
+@@ -61,3 +66,4 @@ std::string sys::getDefaultTargetTriple() {
+
+ return Triple;
+ }
++#endif // __FreeBSD__
diff --git a/contrib/llvm/patches/patch-r243830-arm-disable-clear-cache.diff b/contrib/llvm/patches/patch-r243830-arm-disable-clear-cache.diff
new file mode 100644
index 0000000..b5a4342
--- /dev/null
+++ b/contrib/llvm/patches/patch-r243830-arm-disable-clear-cache.diff
@@ -0,0 +1,19 @@
+This patch ensures __clear_cache is not called on arm. In earlier versions of
+clang, this special builtin was emitted as a function call, leading to link
+errors.
+
+Introduced here: http://svn.freebsd.org/changeset/base/243830
+
+Index: lib/Support/Unix/Memory.inc
+===================================================================
+--- lib/Support/Unix/Memory.inc
++++ lib/Support/Unix/Memory.inc
+@@ -332,7 +332,7 @@ void Memory::InvalidateInstructionCache(const void
+ for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+ asm volatile("icbi 0, %0" : : "r"(Line));
+ asm volatile("isync");
+-# elif (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__)
++# elif (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__) && !defined(__FreeBSD__)
+ // FIXME: Can we safely always call this for __GNUC__ everywhere?
+ const char *Start = static_cast<const char *>(Addr);
+ const char *End = Start + Len;
diff --git a/contrib/llvm/patches/patch-r252503-arm-transient-stack-alignment.diff b/contrib/llvm/patches/patch-r252503-arm-transient-stack-alignment.diff
new file mode 100644
index 0000000..a046858
--- /dev/null
+++ b/contrib/llvm/patches/patch-r252503-arm-transient-stack-alignment.diff
@@ -0,0 +1,79 @@
+This patch applies a workaround for an ARM EABI issue, where clang would
+sometimes incorrectly align the stack in a leaf function that uses TLS.
+
+Introduced here: http://svn.freebsd.org/changeset/base/252503
+
+Index: test/CodeGen/Thumb2/large-stack.ll
+===================================================================
+--- test/CodeGen/Thumb2/large-stack.ll
++++ test/CodeGen/Thumb2/large-stack.ll
+@@ -13,7 +13,7 @@ define void @test1() {
+ define void @test2() {
+ ; DARWIN-LABEL: test2:
+ ; DARWIN: sub.w sp, sp, #4160
+-; DARWIN: sub sp, #8
++; DARWIN: sub sp, #12
+ ; LINUX-LABEL: test2:
+ ; LINUX: sub.w sp, sp, #4160
+ ; LINUX: sub sp, #8
+Index: test/CodeGen/ARM/2009-10-30.ll
+===================================================================
+--- test/CodeGen/ARM/2009-10-30.ll
++++ test/CodeGen/ARM/2009-10-30.ll
+@@ -4,9 +4,10 @@
+
+ define void @f(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, ...) {
+ entry:
+-;CHECK: sub sp, sp, #4
+-;CHECK: add r{{[0-9]+}}, sp, #8
+-;CHECK: str r{{[0-9]+}}, [sp], #4
++;CHECK: sub sp, sp, #8
++;CHECK: add r{{[0-9]+}}, sp, #12
++;CHECK: str r{{[0-9]+}}, [sp, #4]
++;CHECK: add sp, sp, #8
+ ;CHECK: bx lr
+ %ap = alloca i8*, align 4
+ %ap1 = bitcast i8** %ap to i8*
+Index: test/CodeGen/ARM/vargs_align.ll
+===================================================================
+--- test/CodeGen/ARM/vargs_align.ll
++++ test/CodeGen/ARM/vargs_align.ll
+@@ -15,8 +15,8 @@ entry:
+ return: ; preds = %entry
+ %retval2 = load i32* %retval ; <i32> [#uses=1]
+ ret i32 %retval2
+-; EABI: add sp, sp, #12
+ ; EABI: add sp, sp, #16
++; EABI: add sp, sp, #16
++; OABI: add sp, sp, #16
+ ; OABI: add sp, sp, #12
+-; OABI: add sp, sp, #12
+ }
+Index: test/CodeGen/ARM/prefetch-thumb.ll
+===================================================================
+--- test/CodeGen/ARM/prefetch-thumb.ll
++++ test/CodeGen/ARM/prefetch-thumb.ll
+@@ -10,8 +10,8 @@ entry:
+ ;ARM: pld [sp, #50]
+
+ ;THUMB2: t6:
+-;THUMB2: pld [sp]
+-;THUMB2: pld [sp, #50]
++;THUMB2: pld [sp, #4]
++;THUMB2: pld [sp, #54]
+
+ %red = alloca [100 x i8], align 1
+ %0 = getelementptr inbounds [100 x i8]* %red, i32 0, i32 0
+Index: lib/Target/ARM/ARMFrameLowering.h
+===================================================================
+--- lib/Target/ARM/ARMFrameLowering.h
++++ lib/Target/ARM/ARMFrameLowering.h
+@@ -27,7 +27,7 @@ class ARMFrameLowering : public TargetFrameLowerin
+
+ public:
+ explicit ARMFrameLowering(const ARMSubtarget &sti)
+- : TargetFrameLowering(StackGrowsDown, sti.getStackAlignment(), 0, 4),
++ : TargetFrameLowering(StackGrowsDown, sti.getStackAlignment(), 0, 8),
+ STI(sti) {
+ }
+
diff --git a/contrib/llvm/patches/patch-r257109-add-CC-aliases.diff b/contrib/llvm/patches/patch-r257109-add-CC-aliases.diff
new file mode 100644
index 0000000..686210b
--- /dev/null
+++ b/contrib/llvm/patches/patch-r257109-add-CC-aliases.diff
@@ -0,0 +1,25 @@
+This patch adds "CC" and "clang-CC" to the list of program name aliases which
+invoke the C++ compiler.
+
+Introduced here: http://svn.freebsd.org/changeset/base/257109
+
+Index: tools/clang/tools/driver/driver.cpp
+===================================================================
+--- tools/clang/tools/driver/driver.cpp
++++ tools/clang/tools/driver/driver.cpp
+@@ -215,6 +215,7 @@ static void ParseProgName(SmallVectorImpl<const ch
+ } suffixes [] = {
+ { "clang", 0 },
+ { "clang++", "--driver-mode=g++" },
++ { "clang-CC", "--driver-mode=g++" },
+ { "clang-c++", "--driver-mode=g++" },
+ { "clang-cc", 0 },
+ { "clang-cpp", "--driver-mode=cpp" },
+@@ -221,6 +222,7 @@ static void ParseProgName(SmallVectorImpl<const ch
+ { "clang-g++", "--driver-mode=g++" },
+ { "clang-gcc", 0 },
+ { "clang-cl", "--driver-mode=cl" },
++ { "CC", "--driver-mode=g++" },
+ { "cc", 0 },
+ { "cpp", "--driver-mode=cpp" },
+ { "cl" , "--driver-mode=cl" },
diff --git a/contrib/llvm/patches/patch-r259053-gcc-installation-detector.diff b/contrib/llvm/patches/patch-r259053-gcc-installation-detector.diff
new file mode 100644
index 0000000..1d04e7e
--- /dev/null
+++ b/contrib/llvm/patches/patch-r259053-gcc-installation-detector.diff
@@ -0,0 +1,63 @@
+This patch eliminates the unnecessary search for various gcc installation
+directories during each startup of clang.
+
+Introduced here: http://svn.freebsd.org/changeset/base/259053
+
+Index: tools/clang/lib/Driver/ToolChains.cpp
+===================================================================
+--- tools/clang/lib/Driver/ToolChains.cpp
++++ tools/clang/lib/Driver/ToolChains.cpp
+@@ -1014,7 +1014,7 @@ static StringRef getGCCToolchainDir(const ArgList
+ return GCC_INSTALL_PREFIX;
+ }
+
+-/// \brief Construct a GCCInstallationDetector from the driver.
++/// \brief Initialize a GCCInstallationDetector from the driver.
+ ///
+ /// This performs all of the autodetection and sets up the various paths.
+ /// Once constructed, a GCCInstallationDetector is essentially immutable.
+@@ -1023,9 +1023,9 @@ static StringRef getGCCToolchainDir(const ArgList
+ /// should instead pull the target out of the driver. This is currently
+ /// necessary because the driver doesn't store the final version of the target
+ /// triple.
+-Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
+- const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args)
+- : IsValid(false), D(D) {
++void
++Generic_GCC::GCCInstallationDetector::init(
++ const llvm::Triple &TargetTriple, const ArgList &Args) {
+ llvm::Triple BiarchVariantTriple =
+ TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
+ : TargetTriple.get32BitArchVariant();
+@@ -1565,7 +1565,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLib
+
+ Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple,
+ const ArgList &Args)
+- : ToolChain(D, Triple, Args), GCCInstallation(getDriver(), Triple, Args) {
++ : ToolChain(D, Triple, Args), GCCInstallation(getDriver()) {
+ getProgramPaths().push_back(getDriver().getInstalledDir());
+ if (getDriver().getInstalledDir() != getDriver().Dir)
+ getProgramPaths().push_back(getDriver().Dir);
+@@ -2361,6 +2361,7 @@ static StringRef getMultilibDir(const llvm::Triple
+
+ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+ : Generic_ELF(D, Triple, Args) {
++ GCCInstallation.init(Triple, Args);
+ llvm::Triple::ArchType Arch = Triple.getArch();
+ std::string SysRoot = computeSysRoot();
+
+Index: tools/clang/lib/Driver/ToolChains.h
+===================================================================
+--- tools/clang/lib/Driver/ToolChains.h
++++ tools/clang/lib/Driver/ToolChains.h
+@@ -92,8 +92,8 @@ class LLVM_LIBRARY_VISIBILITY Generic_GCC : public
+ std::set<std::string> CandidateGCCInstallPaths;
+
+ public:
+- GCCInstallationDetector(const Driver &D, const llvm::Triple &TargetTriple,
+- const llvm::opt::ArgList &Args);
++ GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
++ void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args);
+
+ /// \brief Check whether we detected a valid GCC install.
+ bool isValid() const { return IsValid; }
diff --git a/contrib/llvm/patches/patch-r259498-add-fxsave.diff b/contrib/llvm/patches/patch-r259498-add-fxsave.diff
new file mode 100644
index 0000000..311be1e
--- /dev/null
+++ b/contrib/llvm/patches/patch-r259498-add-fxsave.diff
@@ -0,0 +1,16 @@
+This patch adds the alias bit_FXSAVE for bit_FXSR to cpuid.h.
+
+Introduced here: http://svn.freebsd.org/changeset/base/259498
+
+Index: tools/clang/lib/Headers/cpuid.h
+===================================================================
+--- tools/clang/lib/Headers/cpuid.h
++++ tools/clang/lib/Headers/cpuid.h
+@@ -79,6 +79,7 @@
+ #define bit_ACPI 0x00400000
+ #define bit_MMX 0x00800000
+ #define bit_FXSR 0x01000000
++#define bit_FXSAVE bit_FXSR /* for gcc compat */
+ #define bit_SSE 0x02000000
+ #define bit_SSE2 0x04000000
+ #define bit_SS 0x08000000
diff --git a/contrib/llvm/patches/patch-r261680-clang-r200899-fix-security-quantis.diff b/contrib/llvm/patches/patch-r261680-clang-r200899-fix-security-quantis.diff
new file mode 100644
index 0000000..be81051
--- /dev/null
+++ b/contrib/llvm/patches/patch-r261680-clang-r200899-fix-security-quantis.diff
@@ -0,0 +1,63 @@
+Pull in r200899 from upstream clang trunk (by Serge Pavlov):
+
+ Allow transformation of VariableArray to ConstantArray.
+
+ In the following code:
+
+ struct A { static const int sz; };
+ template<class T> void f() { T arr[A::sz]; }
+
+ the array 'arr' is represented as a variable size array in the template.
+ If 'A::sz' gets value below in the translation unit, the array in
+ instantiation can turn into constant size array.
+
+ This change fixes PR18633.
+
+ Differential Revision: http://llvm-reviews.chandlerc.com/D2688
+
+Introduced here: http://svn.freebsd.org/changeset/base/261680
+
+Index: tools/clang/test/SemaCXX/c99-variable-length-array.cpp
+===================================================================
+--- tools/clang/test/SemaCXX/c99-variable-length-array.cpp
++++ tools/clang/test/SemaCXX/c99-variable-length-array.cpp
+@@ -140,3 +140,24 @@ namespace PR11744 {
+ }
+ int test = f<int>(0); // expected-note {{instantiation of}}
+ }
++
++namespace pr18633 {
++ struct A1 {
++ static const int sz;
++ static const int sz2;
++ };
++ const int A1::sz2 = 11;
++ template<typename T>
++ void func () {
++ int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}}
++ }
++ template<typename T>
++ void func2 () {
++ int arr[A1::sz2];
++ }
++ const int A1::sz = 12;
++ void func2() {
++ func<int>();
++ func2<int>();
++ }
++}
+Index: tools/clang/lib/Sema/TreeTransform.h
+===================================================================
+--- tools/clang/lib/Sema/TreeTransform.h
++++ tools/clang/lib/Sema/TreeTransform.h
+@@ -3966,7 +3966,9 @@ TreeTransform<Derived>::TransformVariableArrayType
+ return QualType();
+ }
+
+- VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
++ // We might have constant size array now, but fortunately it has the same
++ // location layout.
++ ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
+ NewTL.setLBracketLoc(TL.getLBracketLoc());
+ NewTL.setRBracketLoc(TL.getRBracketLoc());
+ NewTL.setSizeExpr(Size);
diff --git a/contrib/llvm/patches/patch-r261991-llvm-r195391-fix-dwarf2.diff b/contrib/llvm/patches/patch-r261991-llvm-r195391-fix-dwarf2.diff
new file mode 100644
index 0000000..0a1af3e
--- /dev/null
+++ b/contrib/llvm/patches/patch-r261991-llvm-r195391-fix-dwarf2.diff
@@ -0,0 +1,540 @@
+Pull in r195391 from upstream llvm trunk (by Eric Christopher):
+
+ In Dwarf 3 (and Dwarf 2) attributes whose value are offsets into a
+ section use the form DW_FORM_data4 whilst in Dwarf 4 and later they
+ use the form DW_FORM_sec_offset.
+
+ This patch updates the places where such attributes are generated to
+ use the appropriate form depending on the Dwarf version. The DIE entries
+ affected have the following tags:
+ DW_AT_stmt_list, DW_AT_ranges, DW_AT_location, DW_AT_GNU_pubnames,
+ DW_AT_GNU_pubtypes, DW_AT_GNU_addr_base, DW_AT_GNU_ranges_base
+
+ It also adds a hidden command line option "--dwarf-version=<uint>"
+ to llc which allows the version of Dwarf to be generated to override
+ what is specified in the metadata; this makes it possible to update
+ existing tests to check the debugging information generated for both
+ Dwarf 4 (the default) and Dwarf 3 using the same metadata.
+
+ Patch (slightly modified) by Keith Walker!
+
+Introduced here: http://svn.freebsd.org/changeset/base/261991
+
+Index: lib/CodeGen/AsmPrinter/DIE.cpp
+===================================================================
+--- lib/CodeGen/AsmPrinter/DIE.cpp
++++ lib/CodeGen/AsmPrinter/DIE.cpp
+@@ -338,6 +338,7 @@ void DIEDelta::EmitValue(AsmPrinter *AP, dwarf::Fo
+ ///
+ unsigned DIEDelta::SizeOf(AsmPrinter *AP, dwarf::Form Form) const {
+ if (Form == dwarf::DW_FORM_data4) return 4;
++ if (Form == dwarf::DW_FORM_sec_offset) return 4;
+ if (Form == dwarf::DW_FORM_strp) return 4;
+ return AP->getDataLayout().getPointerSize();
+ }
+Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+===================================================================
+--- lib/CodeGen/AsmPrinter/DwarfDebug.cpp
++++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+@@ -105,6 +105,11 @@ DwarfPubSections("generate-dwarf-pub-sections", cl
+ clEnumVal(Disable, "Disabled"), clEnumValEnd),
+ cl::init(Default));
+
++static cl::opt<unsigned>
++DwarfVersionNumber("dwarf-version", cl::Hidden,
++ cl::desc("Generate DWARF for dwarf version."),
++ cl::init(0));
++
+ static const char *const DWARFGroupName = "DWARF Emission";
+ static const char *const DbgTimerName = "DWARF Debug Writer";
+
+@@ -215,7 +220,9 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
+ else
+ HasDwarfPubSections = DwarfPubSections == Enable;
+
+- DwarfVersion = getDwarfVersionFromModule(MMI->getModule());
++ DwarfVersion = DwarfVersionNumber
++ ? DwarfVersionNumber
++ : getDwarfVersionFromModule(MMI->getModule());
+
+ {
+ NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
+@@ -470,9 +477,9 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileU
+ // .debug_range section has not been laid out yet. Emit offset in
+ // .debug_range as a uint, size 4, for now. emitDIE will handle
+ // DW_AT_ranges appropriately.
+- TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
+- DebugRangeSymbols.size()
+- * Asm->getDataLayout().getPointerSize());
++ TheCU->addSectionOffset(ScopeDIE, dwarf::DW_AT_ranges,
++ DebugRangeSymbols.size() *
++ Asm->getDataLayout().getPointerSize());
+ for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
+ RE = Ranges.end(); RI != RE; ++RI) {
+ DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
+@@ -525,9 +532,9 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileU
+ // .debug_range section has not been laid out yet. Emit offset in
+ // .debug_range as a uint, size 4, for now. emitDIE will handle
+ // DW_AT_ranges appropriately.
+- TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
+- DebugRangeSymbols.size()
+- * Asm->getDataLayout().getPointerSize());
++ TheCU->addSectionOffset(ScopeDIE, dwarf::DW_AT_ranges,
++ DebugRangeSymbols.size() *
++ Asm->getDataLayout().getPointerSize());
+ for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
+ RE = Ranges.end(); RI != RE; ++RI) {
+ DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
+@@ -758,14 +765,15 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICo
+ // The line table entries are not always emitted in assembly, so it
+ // is not okay to use line_table_start here.
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+- NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset,
+- UseTheFirstCU ? Asm->GetTempSymbol("section_line")
+- : LineTableStartSym);
++ NewCU->addSectionLabel(
++ Die, dwarf::DW_AT_stmt_list,
++ UseTheFirstCU ? Asm->GetTempSymbol("section_line")
++ : LineTableStartSym);
+ else if (UseTheFirstCU)
+- NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
++ NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0);
+ else
+- NewCU->addDelta(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4,
+- LineTableStartSym, DwarfLineSectionSym);
++ NewCU->addSectionDelta(Die, dwarf::DW_AT_stmt_list,
++ LineTableStartSym, DwarfLineSectionSym);
+
+ // If we're using split dwarf the compilation dir is going to be in the
+ // skeleton CU and so we don't need to duplicate it here.
+@@ -776,26 +784,24 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICo
+ // emit it here if we don't have a skeleton CU for split dwarf.
+ if (GenerateGnuPubSections) {
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+- NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubnames,
+- dwarf::DW_FORM_sec_offset,
+- Asm->GetTempSymbol("gnu_pubnames",
+- NewCU->getUniqueID()));
++ NewCU->addSectionLabel(
++ Die, dwarf::DW_AT_GNU_pubnames,
++ Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
+ else
+- NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4,
+- Asm->GetTempSymbol("gnu_pubnames",
+- NewCU->getUniqueID()),
+- DwarfGnuPubNamesSectionSym);
++ NewCU->addSectionDelta(
++ Die, dwarf::DW_AT_GNU_pubnames,
++ Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
++ DwarfGnuPubNamesSectionSym);
+
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+- NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubtypes,
+- dwarf::DW_FORM_sec_offset,
+- Asm->GetTempSymbol("gnu_pubtypes",
+- NewCU->getUniqueID()));
++ NewCU->addSectionLabel(
++ Die, dwarf::DW_AT_GNU_pubtypes,
++ Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
+ else
+- NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4,
+- Asm->GetTempSymbol("gnu_pubtypes",
+- NewCU->getUniqueID()),
+- DwarfGnuPubTypesSectionSym);
++ NewCU->addSectionDelta(
++ Die, dwarf::DW_AT_GNU_pubtypes,
++ Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
++ DwarfGnuPubTypesSectionSym);
+ }
+ }
+
+@@ -2956,11 +2962,10 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const
+ // Relocate to the beginning of the addr_base section, else 0 for the
+ // beginning of the one for this compile unit.
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+- NewCU->addLabel(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset,
+- DwarfAddrSectionSym);
++ NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base,
++ DwarfAddrSectionSym);
+ else
+- NewCU->addUInt(Die, dwarf::DW_AT_GNU_addr_base,
+- dwarf::DW_FORM_sec_offset, 0);
++ NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0);
+
+ // 2.17.1 requires that we use DW_AT_low_pc for a single entry point
+ // into an entity. We're using 0, or a NULL label for this.
+@@ -2970,10 +2975,10 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const
+ // compile unit in debug_line section.
+ // FIXME: Should handle multiple compile units.
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+- NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset,
+- DwarfLineSectionSym);
++ NewCU->addSectionLabel(Die, dwarf::DW_AT_stmt_list,
++ DwarfLineSectionSym);
+ else
+- NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, 0);
++ NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0);
+
+ if (!CompilationDir.empty())
+ NewCU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
+@@ -2981,27 +2986,31 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const
+ // Flags to let the linker know we have emitted new style pubnames.
+ if (GenerateGnuPubSections) {
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+- NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_sec_offset,
+- Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
++ NewCU->addSectionLabel(
++ Die, dwarf::DW_AT_GNU_pubnames,
++ Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()));
+ else
+- NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4,
+- Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
+- DwarfGnuPubNamesSectionSym);
++ NewCU->addSectionDelta(
++ Die, dwarf::DW_AT_GNU_pubnames,
++ Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()),
++ DwarfGnuPubNamesSectionSym);
+
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+- NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_sec_offset,
+- Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
++ NewCU->addSectionLabel(
++ Die, dwarf::DW_AT_GNU_pubtypes,
++ Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()));
+ else
+- NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4,
+- Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
+- DwarfGnuPubTypesSectionSym);
++ NewCU->addSectionDelta(
++ Die, dwarf::DW_AT_GNU_pubtypes,
++ Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()),
++ DwarfGnuPubTypesSectionSym);
+ }
+
+ // Flag if we've emitted any ranges and their location for the compile unit.
+ if (DebugRangeSymbols.size()) {
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+- NewCU->addLabel(Die, dwarf::DW_AT_GNU_ranges_base,
+- dwarf::DW_FORM_sec_offset, DwarfDebugRangeSectionSym);
++ NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base,
++ DwarfDebugRangeSectionSym);
+ else
+ NewCU->addUInt(Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4,
+ 0);
+Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+===================================================================
+--- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
++++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+@@ -227,6 +227,26 @@ void CompileUnit::addLabel(DIEBlock *Die, dwarf::F
+ addLabel(Die, (dwarf::Attribute)0, Form, Label);
+ }
+
++/// addSectionLabel - Add a Dwarf section label attribute data and value.
++///
++void CompileUnit::addSectionLabel(DIE *Die, dwarf::Attribute Attribute,
++ const MCSymbol *Label) {
++ if (DD->getDwarfVersion() >= 4)
++ addLabel(Die, Attribute, dwarf::DW_FORM_sec_offset, Label);
++ else
++ addLabel(Die, Attribute, dwarf::DW_FORM_data4, Label);
++}
++
++/// addSectionOffset - Add an offset into a section attribute data and value.
++///
++void CompileUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute,
++ uint64_t Integer) {
++ if (DD->getDwarfVersion() >= 4)
++ addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer);
++ else
++ addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer);
++}
++
+ /// addLabelAddress - Add a dwarf label attribute data and value using
+ /// DW_FORM_addr or DW_FORM_GNU_addr_index.
+ ///
+@@ -264,13 +284,15 @@ void CompileUnit::addOpAddress(DIEBlock *Die, cons
+ }
+ }
+
+-/// addDelta - Add a label delta attribute data and value.
++/// addSectionDelta - Add a section label delta attribute data and value.
+ ///
+-void CompileUnit::addDelta(DIE *Die, dwarf::Attribute Attribute,
+- dwarf::Form Form, const MCSymbol *Hi,
+- const MCSymbol *Lo) {
++void CompileUnit::addSectionDelta(DIE *Die, dwarf::Attribute Attribute,
++ const MCSymbol *Hi, const MCSymbol *Lo) {
+ DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
+- Die->addValue(Attribute, Form, Value);
++ if (DD->getDwarfVersion() >= 4)
++ Die->addValue(Attribute, dwarf::DW_FORM_sec_offset, Value);
++ else
++ Die->addValue(Attribute, dwarf::DW_FORM_data4, Value);
+ }
+
+ /// addDIEEntry - Add a DIE attribute data and value.
+@@ -1768,10 +1790,8 @@ DIE *CompileUnit::constructVariableDIE(DbgVariable
+
+ unsigned Offset = DV.getDotDebugLocOffset();
+ if (Offset != ~0U) {
+- addLabel(VariableDie, dwarf::DW_AT_location,
+- DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
+- : dwarf::DW_FORM_data4,
+- Asm->GetTempSymbol("debug_loc", Offset));
++ addSectionLabel(VariableDie, dwarf::DW_AT_location,
++ Asm->GetTempSymbol("debug_loc", Offset));
+ DV.setDIE(VariableDie);
+ return VariableDie;
+ }
+Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+===================================================================
+--- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
++++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+@@ -209,6 +209,14 @@ class CompileUnit {
+
+ void addLabel(DIEBlock *Die, dwarf::Form Form, const MCSymbol *Label);
+
++ /// addSectionLabel - Add a Dwarf section label attribute data and value.
++ ///
++ void addSectionLabel(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Label);
++
++ /// addSectionOffset - Add an offset into a section attribute data and value.
++ ///
++ void addSectionOffset(DIE *Die, dwarf::Attribute Attribute, uint64_t Integer);
++
+ /// addLabelAddress - Add a dwarf label attribute data and value using
+ /// either DW_FORM_addr or DW_FORM_GNU_addr_index.
+ ///
+@@ -219,10 +227,9 @@ class CompileUnit {
+ ///
+ void addOpAddress(DIEBlock *Die, const MCSymbol *Label);
+
+- /// addDelta - Add a label delta attribute data and value.
+- ///
+- void addDelta(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form, const MCSymbol *Hi,
+- const MCSymbol *Lo);
++ /// addSectionDelta - Add a label delta attribute data and value.
++ void addSectionDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
++ const MCSymbol *Lo);
+
+ /// addDIEEntry - Add a DIE attribute data and value.
+ ///
+Index: test/DebugInfo/X86/gnu-public-names.ll
+===================================================================
+--- test/DebugInfo/X86/gnu-public-names.ll
++++ test/DebugInfo/X86/gnu-public-names.ll
+@@ -1,5 +1,6 @@
+ ; RUN: llc -mtriple=x86_64-pc-linux-gnu -generate-gnu-dwarf-pub-sections < %s | FileCheck -check-prefix=ASM %s
+ ; RUN: llc -mtriple=x86_64-pc-linux-gnu -generate-gnu-dwarf-pub-sections -filetype=obj < %s | llvm-dwarfdump - | FileCheck %s
++; RUN: llc -mtriple=x86_64-pc-linux-gnu -generate-gnu-dwarf-pub-sections -filetype=obj -dwarf-version=3 < %s | llvm-dwarfdump - | FileCheck %s -check-prefix=DWARF3
+ ; ModuleID = 'dwarf-public-names.cpp'
+ ;
+ ; Generated from:
+@@ -123,6 +124,85 @@
+ ; CHECK-DAG: [[D]] EXTERNAL TYPE "ns::D"
+ ; CHECK-DAG: [[INT]] STATIC TYPE "int"
+
++; DWARF3: .debug_info contents:
++; DWARF3: DW_AT_GNU_pubnames [DW_FORM_data4] (0x00000000)
++; DWARF3: DW_AT_GNU_pubtypes [DW_FORM_data4] (0x00000000)
++
++; DWARF3: [[C:[0-9a-f]+]]: DW_TAG_structure_type
++; DWARF3-NEXT: DW_AT_name {{.*}} "C"
++
++; DWARF3: [[STATIC_MEM_DECL:[0-9a-f]+]]: DW_TAG_member
++; DWARF3-NEXT: DW_AT_name {{.*}} "static_member_variable"
++
++; DWARF3: [[MEM_FUNC_DECL:[0-9a-f]+]]: DW_TAG_subprogram
++; DWARF3-NEXT: DW_AT_MIPS_linkage_name
++; DWARF3-NEXT: DW_AT_name {{.*}} "member_function"
++
++; DWARF3: [[STATIC_MEM_FUNC_DECL:[0-9a-f]+]]: DW_TAG_subprogram
++; DWARF3-NEXT: DW_AT_MIPS_linkage_name
++; DWARF3-NEXT: DW_AT_name {{.*}} "static_member_function"
++
++; DWARF3: [[INT:[0-9a-f]+]]: DW_TAG_base_type
++; DWARF3-NEXT: DW_AT_name {{.*}} "int"
++
++; DWARF3: [[STATIC_MEM_VAR:[0-9a-f]+]]: DW_TAG_variable
++; DWARF3-NEXT: DW_AT_specification {{.*}}[[STATIC_MEM_DECL]]
++
++; DWARF3: [[GLOB_VAR:[0-9a-f]+]]: DW_TAG_variable
++; DWARF3-NEXT: DW_AT_name {{.*}} "global_variable"
++
++; DWARF3: [[NS:[0-9a-f]+]]: DW_TAG_namespace
++; DWARF3-NEXT: DW_AT_name {{.*}} "ns"
++
++; DWARF3: [[GLOB_NS_VAR_DECL:[0-9a-f]+]]: DW_TAG_variable
++; DWARF3-NEXT: DW_AT_name {{.*}} "global_namespace_variable"
++
++; DWARF3: [[D_VAR_DECL:[0-9a-f]+]]: DW_TAG_variable
++; DWARF3-NEXT: DW_AT_name {{.*}} "d"
++
++; DWARF3: [[D:[0-9a-f]+]]: DW_TAG_structure_type
++; DWARF3-NEXT: DW_AT_name {{.*}} "D"
++
++; DWARF3: [[GLOB_NS_FUNC:[0-9a-f]+]]: DW_TAG_subprogram
++; DWARF3-NEXT: DW_AT_MIPS_linkage_name
++; DWARF3-NEXT: DW_AT_name {{.*}} "global_namespace_function"
++
++; DWARF3: [[GLOB_NS_VAR:[0-9a-f]+]]: DW_TAG_variable
++; DWARF3-NEXT: DW_AT_specification {{.*}}[[GLOB_NS_VAR_DECL]]
++
++; DWARF3: [[D_VAR:[0-9a-f]+]]: DW_TAG_variable
++; DWARF3-NEXT: DW_AT_specification {{.*}}[[D_VAR_DECL]]
++
++; DWARF3: [[MEM_FUNC:[0-9a-f]+]]: DW_TAG_subprogram
++; DWARF3-NEXT: DW_AT_specification {{.*}}[[MEM_FUNC_DECL]]
++
++; DWARF3: [[STATIC_MEM_FUNC:[0-9a-f]+]]: DW_TAG_subprogram
++; DWARF3-NEXT: DW_AT_specification {{.*}}[[STATIC_MEM_FUNC_DECL]]
++
++; DWARF3: [[GLOBAL_FUNC:[0-9a-f]+]]: DW_TAG_subprogram
++; DWARF3-NEXT: DW_AT_MIPS_linkage_name
++; DWARF3-NEXT: DW_AT_name {{.*}} "global_function"
++
++; DWARF3-LABEL: .debug_gnu_pubnames contents:
++; DWARF3-NEXT: length = 0x000000e7 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x0000018b
++; DWARF3-NEXT: Offset Linkage Kind Name
++; DWARF3-DAG: [[GLOBAL_FUNC]] EXTERNAL FUNCTION "global_function"
++; DWARF3-DAG: [[NS]] EXTERNAL TYPE "ns"
++; DWARF3-DAG: [[MEM_FUNC]] EXTERNAL FUNCTION "C::member_function"
++; DWARF3-DAG: [[GLOB_VAR]] EXTERNAL VARIABLE "global_variable"
++; DWARF3-DAG: [[GLOB_NS_VAR]] EXTERNAL VARIABLE "ns::global_namespace_variable"
++; DWARF3-DAG: [[GLOB_NS_FUNC]] EXTERNAL FUNCTION "ns::global_namespace_function"
++; DWARF3-DAG: [[D_VAR]] EXTERNAL VARIABLE "ns::d"
++; DWARF3-DAG: [[STATIC_MEM_VAR]] EXTERNAL VARIABLE "C::static_member_variable"
++; DWARF3-DAG: [[STATIC_MEM_FUNC]] EXTERNAL FUNCTION "C::static_member_function"
++
++
++; DWARF3-LABEL: debug_gnu_pubtypes contents:
++; DWARF3: Offset Linkage Kind Name
++; DWARF3-DAG: [[C]] EXTERNAL TYPE "C"
++; DWARF3-DAG: [[D]] EXTERNAL TYPE "ns::D"
++; DWARF3-DAG: [[INT]] STATIC TYPE "int"
++
+ %struct.C = type { i8 }
+ %"struct.ns::D" = type { i32 }
+
+Index: test/DebugInfo/X86/stmt-list-multiple-compile-units.ll
+===================================================================
+--- test/DebugInfo/X86/stmt-list-multiple-compile-units.ll
++++ test/DebugInfo/X86/stmt-list-multiple-compile-units.ll
+@@ -1,5 +1,7 @@
+ ; RUN: llc -O0 %s -mtriple=x86_64-apple-darwin -filetype=obj -o %t
+ ; RUN: llvm-dwarfdump %t | FileCheck %s
++; RUN: llc -O0 %s -mtriple=x86_64-apple-darwin -filetype=obj -o %t -dwarf-version=3
++; RUN: llvm-dwarfdump %t | FileCheck %s -check-prefix=DWARF3
+ ; RUN: llc < %s -O0 -mtriple=x86_64-apple-macosx10.7 | FileCheck %s -check-prefix=ASM
+
+ ; rdar://13067005
+@@ -6,11 +8,11 @@
+ ; CHECK: .debug_info contents:
+ ; CHECK: DW_TAG_compile_unit
+ ; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
+-; CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x00000000)
++; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000)
+
+ ; CHECK: DW_TAG_compile_unit
+ ; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
+-; CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x0000003c)
++; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x0000003c)
+
+ ; CHECK: .debug_line contents:
+ ; CHECK-NEXT: Line table prologue:
+@@ -21,6 +23,24 @@
+ ; CHECK: file_names[ 1] 0 0x00000000 0x00000000 simple2.c
+ ; CHECK-NOT: file_names
+
++; DWARF3: .debug_info contents:
++; DWARF3: DW_TAG_compile_unit
++; DWARF3: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
++; DWARF3: DW_AT_stmt_list [DW_FORM_data4] (0x00000000)
++
++; DWARF3: DW_TAG_compile_unit
++; DWARF3: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
++; DWARF3: DW_AT_stmt_list [DW_FORM_data4] (0x0000003c)
++
++; DWARF3: .debug_line contents:
++; DWARF3-NEXT: Line table prologue:
++; DWARF3-NEXT: total_length: 0x00000038
++; DWARF3: file_names[ 1] 0 0x00000000 0x00000000 simple.c
++; DWARF3: Line table prologue:
++; DWARF3-NEXT: total_length: 0x00000039
++; DWARF3: file_names[ 1] 0 0x00000000 0x00000000 simple2.c
++; DWARF3-NOT: file_names
++
+ ; PR15408
+ ; ASM: L__DWARF__debug_info_begin0:
+ ; ASM: .long 0 ## DW_AT_stmt_list
+Index: test/DebugInfo/X86/block-capture.ll
+===================================================================
+--- test/DebugInfo/X86/block-capture.ll
++++ test/DebugInfo/X86/block-capture.ll
+@@ -1,5 +1,7 @@
+ ; RUN: llc -mtriple=x86_64-apple-darwin %s -o %t -filetype=obj
+ ; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s
++; RUN: llc -mtriple=x86_64-apple-darwin %s -o %t -filetype=obj -dwarf-version=3
++; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s -check-prefix=DWARF3
+
+ ; Checks that we emit debug info for the block variable declare.
+ ; CHECK: DW_TAG_subprogram [3]
+@@ -7,6 +9,11 @@
+ ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "block")
+ ; CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}})
+
++; DWARF3: DW_TAG_subprogram [3]
++; DWARF3: DW_TAG_variable [5]
++; DWARF3: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "block")
++; DWARF3: DW_AT_location [DW_FORM_data4] ({{.*}})
++
+ %struct.__block_descriptor = type { i64, i64 }
+ %struct.__block_literal_generic = type { i8*, i32, i32, i8*, %struct.__block_descriptor* }
+
+Index: test/DebugInfo/X86/op_deref.ll
+===================================================================
+--- test/DebugInfo/X86/op_deref.ll
++++ test/DebugInfo/X86/op_deref.ll
+@@ -1,5 +1,7 @@
+ ; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o %t -filetype=obj
+ ; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s -check-prefix=DW-CHECK
++; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o %t -filetype=obj -dwarf-version=3
++; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s -check-prefix=DWARF3
+
+ ; DW-CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000067] = "vla")
+ ; FIXME: The location here needs to be fixed, but llvm-dwarfdump doesn't handle
+@@ -6,6 +8,11 @@
+ ; DW_AT_location lists yet.
+ ; DW-CHECK: DW_AT_location [DW_FORM_sec_offset] (0x00000000)
+
++; DWARF3: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000067] = "vla")
++; FIXME: The location here needs to be fixed, but llvm-dwarfdump doesn't handle
++; DW_AT_location lists yet.
++; DWARF3: DW_AT_location [DW_FORM_data4] (0x00000000)
++
+ ; Unfortunately llvm-dwarfdump can't unparse a list of DW_AT_locations
+ ; right now, so we check the asm output:
+ ; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - -filetype=asm | FileCheck %s -check-prefix=ASM-CHECK
+Index: test/DebugInfo/X86/DW_AT_stmt_list_sec_offset.ll
+===================================================================
+--- test/DebugInfo/X86/DW_AT_stmt_list_sec_offset.ll
++++ test/DebugInfo/X86/DW_AT_stmt_list_sec_offset.ll
+@@ -1,7 +1,10 @@
+ ; RUN: llc -mtriple=i686-w64-mingw32 -o %t -filetype=obj %s
+ ; RUN: llvm-dwarfdump -debug-dump=all %t | FileCheck %s
++; RUN: llc -mtriple=i686-w64-mingw32 -o %t -filetype=obj -dwarf-version=3 %s
++; RUN: llvm-dwarfdump -debug-dump=all %t | FileCheck %s -check-prefix=DWARF3
+
+ ; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset]
++; DWARF3: DW_AT_stmt_list [DW_FORM_data4]
+ ;
+ ; generated from:
+ ; clang -g -S -emit-llvm test.c -o test.ll
+@@ -36,6 +39,6 @@ attributes #0 = { nounwind "less-precise-fpmad"="f
+ !6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+ !7 = metadata !{metadata !8}
+ !8 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+-!9 = metadata !{i32 2, metadata !"Dwarf Version", i32 3}
++!9 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+ !10 = metadata !{i32 3, i32 0, metadata !4, null}
+ !11 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
diff --git a/contrib/llvm/patches/patch-r261991-llvm-r198385-fix-dwarf2.diff b/contrib/llvm/patches/patch-r261991-llvm-r198385-fix-dwarf2.diff
new file mode 100644
index 0000000..375f662
--- /dev/null
+++ b/contrib/llvm/patches/patch-r261991-llvm-r198385-fix-dwarf2.diff
@@ -0,0 +1,91 @@
+Pull in r198385 from upstream llvm trunk (by David Blaikie):
+
+ Reverting r193835 due to weirdness with Go...
+
+ Apologies for the noise - we're seeing some Go failures with cgo
+ interacting with Clang's debug info due to this change.
+
+Introduced here: http://svn.freebsd.org/changeset/base/261991
+
+Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+===================================================================
+--- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
++++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+@@ -1845,9 +1845,6 @@ void CompileUnit::constructMemberDIE(DIE &Buffer,
+
+ addSourceLine(MemberDie, DT);
+
+- DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
+- addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
+-
+ if (DT.getTag() == dwarf::DW_TAG_inheritance && DT.isVirtual()) {
+
+ // For C++, virtual base classes are not at fixed offset. Use following
+@@ -1892,7 +1889,11 @@ void CompileUnit::constructMemberDIE(DIE &Buffer,
+ } else
+ // This is not a bitfield.
+ OffsetInBytes = DT.getOffsetInBits() >> 3;
+- addUInt(MemberDie, dwarf::DW_AT_data_member_location, None, OffsetInBytes);
++
++ DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
++ addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
++ addUInt(MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
++ addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
+ }
+
+ if (DT.isProtected())
+Index: test/DebugInfo/X86/data_member_location.ll
+===================================================================
+--- test/DebugInfo/X86/data_member_location.ll
++++ test/DebugInfo/X86/data_member_location.ll
+@@ -11,11 +11,11 @@
+
+ ; CHECK: DW_AT_name {{.*}} "c"
+ ; CHECK-NOT: DW_TAG
+-; CHECK: DW_AT_data_member_location {{.*}} (0x00)
++; CHECK: DW_AT_data_member_location {{.*}} (<0x02> 23 00 )
+
+ ; CHECK: DW_AT_name {{.*}} "i"
+ ; CHECK-NOT: DW_TAG
+-; CHECK: DW_AT_data_member_location {{.*}} (0x04)
++; CHECK: DW_AT_data_member_location {{.*}} (<0x02> 23 04 )
+
+ %struct.foo = type { i8, i32 }
+
+Index: test/DebugInfo/X86/concrete_out_of_line.ll
+===================================================================
+--- test/DebugInfo/X86/concrete_out_of_line.ll
++++ test/DebugInfo/X86/concrete_out_of_line.ll
+@@ -7,7 +7,7 @@
+ ; first check that we have a TAG_subprogram at a given offset and it has
+ ; AT_inline.
+
+-; CHECK: 0x0000011c: DW_TAG_subprogram [17]
++; CHECK: 0x0000011e: DW_TAG_subprogram [17]
+ ; CHECK-NEXT: DW_AT_specification
+ ; CHECK-NEXT: DW_AT_inline
+
+@@ -14,8 +14,8 @@
+
+ ; and then that a TAG_subprogram refers to it with AT_abstract_origin.
+
+-; CHECK: 0x0000015d: DW_TAG_subprogram [19]
+-; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x011c => {0x0000011c})
++; CHECK: 0x0000015f: DW_TAG_subprogram [19]
++; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x011e => {0x0000011e})
+
+ define i32 @_ZN17nsAutoRefCnt7ReleaseEv() {
+ entry:
+Index: test/DebugInfo/X86/generate-odr-hash.ll
+===================================================================
+--- test/DebugInfo/X86/generate-odr-hash.ll
++++ test/DebugInfo/X86/generate-odr-hash.ll
+@@ -1,5 +1,8 @@
+ ; REQUIRES: object-emission
+
++; Fail while investigating problem with non-block representations of member offsets.
++; XFAIL: *
++
+ ; RUN: llc %s -o %t -filetype=obj -O0 -generate-odr-hash -mtriple=x86_64-unknown-linux-gnu
+ ; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s
+ ;
diff --git a/contrib/llvm/patches/patch-r261991-llvm-r198389-fix-dwarf2.diff b/contrib/llvm/patches/patch-r261991-llvm-r198389-fix-dwarf2.diff
new file mode 100644
index 0000000..a4a00a9
--- /dev/null
+++ b/contrib/llvm/patches/patch-r261991-llvm-r198389-fix-dwarf2.diff
@@ -0,0 +1,105 @@
+Pull in r198389 from upstream llvm trunk (by David Blaikie):
+
+ Revert "Reverting r193835 due to weirdness with Go..."
+
+ The cgo problem was that it wants dwarf2 which doesn't support direct
+ constant encoding of the location. So let's add support for dwarf2
+ encoding (using a location expression) of data member locations.
+
+ This reverts commit r198385.
+
+Introduced here: http://svn.freebsd.org/changeset/base/261991
+
+Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+===================================================================
+--- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
++++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+@@ -1890,10 +1890,14 @@ void CompileUnit::constructMemberDIE(DIE &Buffer,
+ // This is not a bitfield.
+ OffsetInBytes = DT.getOffsetInBits() >> 3;
+
+- DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
+- addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
+- addUInt(MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
+- addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
++ if (DD->getDwarfVersion() <= 2) {
++ DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
++ addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
++ addUInt(MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
++ addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
++ } else
++ addUInt(MemberDie, dwarf::DW_AT_data_member_location, None,
++ OffsetInBytes);
+ }
+
+ if (DT.isProtected())
+Index: test/DebugInfo/X86/data_member_location.ll
+===================================================================
+--- test/DebugInfo/X86/data_member_location.ll
++++ test/DebugInfo/X86/data_member_location.ll
+@@ -1,4 +1,5 @@
+ ; RUN: llc -mtriple=x86_64-linux -O0 -o - -filetype=obj < %s | llvm-dwarfdump -debug-dump=info -| FileCheck %s
++; RUN: llc -mtriple=x86_64-linux -dwarf-version=2 -O0 -o - -filetype=obj < %s | llvm-dwarfdump -debug-dump=info -| FileCheck -check-prefix=DWARF2 %s
+
+ ; Generated from Clang with the following source:
+ ;
+@@ -11,12 +12,20 @@
+
+ ; CHECK: DW_AT_name {{.*}} "c"
+ ; CHECK-NOT: DW_TAG
+-; CHECK: DW_AT_data_member_location {{.*}} (<0x02> 23 00 )
++; CHECK: DW_AT_data_member_location {{.*}} (0x00)
+
+ ; CHECK: DW_AT_name {{.*}} "i"
+ ; CHECK-NOT: DW_TAG
+-; CHECK: DW_AT_data_member_location {{.*}} (<0x02> 23 04 )
++; CHECK: DW_AT_data_member_location {{.*}} (0x04)
+
++; DWARF2: DW_AT_name {{.*}} "c"
++; DWARF2-NOT: DW_TAG
++; DWARF2: DW_AT_data_member_location {{.*}} (<0x02> 23 00 )
++
++; DWARF2: DW_AT_name {{.*}} "i"
++; DWARF2-NOT: DW_TAG
++; DWARF2: DW_AT_data_member_location {{.*}} (<0x02> 23 04 )
++
+ %struct.foo = type { i8, i32 }
+
+ @f = global %struct.foo zeroinitializer, align 4
+Index: test/DebugInfo/X86/concrete_out_of_line.ll
+===================================================================
+--- test/DebugInfo/X86/concrete_out_of_line.ll
++++ test/DebugInfo/X86/concrete_out_of_line.ll
+@@ -7,7 +7,7 @@
+ ; first check that we have a TAG_subprogram at a given offset and it has
+ ; AT_inline.
+
+-; CHECK: 0x0000011e: DW_TAG_subprogram [17]
++; CHECK: 0x0000011c: DW_TAG_subprogram [17]
+ ; CHECK-NEXT: DW_AT_specification
+ ; CHECK-NEXT: DW_AT_inline
+
+@@ -14,8 +14,8 @@
+
+ ; and then that a TAG_subprogram refers to it with AT_abstract_origin.
+
+-; CHECK: 0x0000015f: DW_TAG_subprogram [19]
+-; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x011e => {0x0000011e})
++; CHECK: 0x0000015d: DW_TAG_subprogram [19]
++; CHECK-NEXT: DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x011c => {0x0000011c})
+
+ define i32 @_ZN17nsAutoRefCnt7ReleaseEv() {
+ entry:
+Index: test/DebugInfo/X86/generate-odr-hash.ll
+===================================================================
+--- test/DebugInfo/X86/generate-odr-hash.ll
++++ test/DebugInfo/X86/generate-odr-hash.ll
+@@ -1,8 +1,5 @@
+ ; REQUIRES: object-emission
+
+-; Fail while investigating problem with non-block representations of member offsets.
+-; XFAIL: *
+-
+ ; RUN: llc %s -o %t -filetype=obj -O0 -generate-odr-hash -mtriple=x86_64-unknown-linux-gnu
+ ; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s
+ ;
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198028-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198028-sparc.diff
new file mode 100644
index 0000000..b4fb929
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198028-sparc.diff
@@ -0,0 +1,258 @@
+Pull in r198028 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add MCInstPrinter implementation for SPARC.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/InstPrinter/LLVMBuild.txt
+===================================================================
+--- lib/Target/Sparc/InstPrinter/LLVMBuild.txt
++++ lib/Target/Sparc/InstPrinter/LLVMBuild.txt
+@@ -0,0 +1,23 @@
++;===- ./lib/Target/Sparc/InstPrinter/LLVMBuild.txt -------------*- Conf -*--===;
++;
++; The LLVM Compiler Infrastructure
++;
++; This file is distributed under the University of Illinois Open Source
++; License. See LICENSE.TXT for details.
++;
++;===------------------------------------------------------------------------===;
++;
++; This is an LLVMBuild description file for the components in this subdirectory.
++;
++; For more information on the LLVMBuild system, please see:
++;
++; http://llvm.org/docs/LLVMBuild.html
++;
++;===------------------------------------------------------------------------===;
++
++[component_0]
++type = Library
++name = SparcAsmPrinter
++parent = Sparc
++required_libraries = MC Support
++add_to_library_groups = Sparc
+Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+@@ -0,0 +1,95 @@
++//===-- SparcInstPrinter.cpp - Convert Sparc MCInst to assembly syntax -----==//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This class prints an Sparc MCInst to a .s file.
++//
++//===----------------------------------------------------------------------===//
++
++#define DEBUG_TYPE "asm-printer"
++#include "SparcInstPrinter.h"
++
++#include "Sparc.h"
++#include "MCTargetDesc/SparcBaseInfo.h"
++#include "llvm/MC/MCExpr.h"
++#include "llvm/MC/MCInst.h"
++#include "llvm/MC/MCSymbol.h"
++#include "llvm/Support/raw_ostream.h"
++using namespace llvm;
++
++#define GET_INSTRUCTION_NAME
++// Uncomment the following line once we are ready to use MCAsmWriter.
++//#include "SparcGenAsmWriter.inc"
++
++void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
++{
++ OS << '%' << StringRef(getRegisterName(RegNo)).lower();
++}
++
++void SparcInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
++ StringRef Annot)
++{
++ printInstruction(MI, O);
++ printAnnotation(O, Annot);
++}
++
++void SparcInstPrinter::printOperand(const MCInst *MI, int opNum,
++ raw_ostream &O)
++{
++ const MCOperand &MO = MI->getOperand (opNum);
++
++ if (MO.isReg()) {
++ printRegName(O, MO.getReg());
++ return ;
++ }
++
++ if (MO.isImm()) {
++ O << (int)MO.getImm();
++ return;
++ }
++
++ assert(MO.isExpr() && "Unknown operand kind in printOperand");
++ MO.getExpr()->print(O);
++}
++
++void SparcInstPrinter::printMemOperand(const MCInst *MI, int opNum,
++ raw_ostream &O, const char *Modifier)
++{
++ printOperand(MI, opNum, O);
++
++ // If this is an ADD operand, emit it like normal operands.
++ if (Modifier && !strcmp(Modifier, "arith")) {
++ O << ", ";
++ printOperand(MI, opNum+1, O);
++ return;
++ }
++ const MCOperand &MO = MI->getOperand(opNum+1);
++
++ if (MO.isReg() && MO.getReg() == SP::G0)
++ return; // don't print "+%g0"
++ if (MO.isImm() && MO.getImm() == 0)
++ return; // don't print "+0"
++
++ O << "+";
++
++ printOperand(MI, opNum+1, O);
++}
++
++void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum,
++ raw_ostream &O)
++{
++ int CC = (int)MI->getOperand(opNum).getImm();
++ O << SPARCCondCodeToString((SPCC::CondCodes)CC);
++}
++
++bool SparcInstPrinter::printGetPCX(const MCInst *MI, unsigned opNum,
++ raw_ostream &O)
++{
++ assert(0 && "FIXME: Implement SparcInstPrinter::printGetPCX.");
++ return true;
++}
+Index: lib/Target/Sparc/InstPrinter/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/InstPrinter/CMakeLists.txt
++++ lib/Target/Sparc/InstPrinter/CMakeLists.txt
+@@ -0,0 +1,3 @@
++add_llvm_library(LLVMSparcAsmPrinter
++ SparcInstPrinter.cpp
++ )
+Index: lib/Target/Sparc/InstPrinter/Makefile
+===================================================================
+--- lib/Target/Sparc/InstPrinter/Makefile
++++ lib/Target/Sparc/InstPrinter/Makefile
+@@ -0,0 +1,16 @@
++##===- lib/Target/Sparc/InstPrinter/Makefile ---------------*- Makefile -*-===##
++#
++# The LLVM Compiler Infrastructure
++#
++# This file is distributed under the University of Illinois Open Source
++# License. See LICENSE.TXT for details.
++#
++##===----------------------------------------------------------------------===##
++
++LEVEL = ../../../..
++LIBRARYNAME = LLVMSparcAsmPrinter
++
++# Hack: we need to include 'main' target directory to grab private headers
++CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
++
++include $(LEVEL)/Makefile.common
+Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
+===================================================================
+--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
+@@ -0,0 +1,46 @@
++//===-- SparcInstPrinter.h - Convert Sparc MCInst to assembly syntax ------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This class prints an Sparc MCInst to a .s file.
++//
++//===----------------------------------------------------------------------===//
++
++#ifndef SparcINSTPRINTER_H
++#define SparcINSTPRINTER_H
++
++#include "llvm/MC/MCInstPrinter.h"
++
++namespace llvm {
++
++class MCOperand;
++
++class SparcInstPrinter : public MCInstPrinter {
++public:
++ SparcInstPrinter(const MCAsmInfo &MAI,
++ const MCInstrInfo &MII,
++ const MCRegisterInfo &MRI)
++ : MCInstPrinter(MAI, MII, MRI) {}
++
++ virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
++ virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
++
++ // Autogenerated by tblgen.
++ void printInstruction(const MCInst *MI, raw_ostream &O);
++ static const char *getRegisterName(unsigned RegNo);
++
++ void printOperand(const MCInst *MI, int opNum, raw_ostream &OS);
++ void printMemOperand(const MCInst *MI, int opNum, raw_ostream &OS,
++ const char *Modifier = 0);
++ void printCCOperand(const MCInst *MI, int opNum, raw_ostream &OS);
++ bool printGetPCX(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
++
++};
++} // end namespace llvm
++
++#endif
+Index: lib/Target/Sparc/LLVMBuild.txt
+===================================================================
+--- lib/Target/Sparc/LLVMBuild.txt
++++ lib/Target/Sparc/LLVMBuild.txt
+@@ -16,7 +16,7 @@
+ ;===------------------------------------------------------------------------===;
+
+ [common]
+-subdirectories = MCTargetDesc TargetInfo
++subdirectories = InstPrinter MCTargetDesc TargetInfo
+
+ [component_0]
+ type = TargetGroup
+@@ -29,6 +29,6 @@ has_jit = 1
+ type = Library
+ name = SparcCodeGen
+ parent = Sparc
+-required_libraries = AsmPrinter CodeGen Core MC SelectionDAG SparcDesc
+- SparcInfo Support Target
++required_libraries = AsmPrinter CodeGen Core MC SelectionDAG SparcAsmPrinter
++ SparcDesc SparcInfo Support Target
+ add_to_library_groups = Sparc
+Index: lib/Target/Sparc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/CMakeLists.txt
++++ lib/Target/Sparc/CMakeLists.txt
+@@ -29,3 +29,4 @@ add_dependencies(LLVMSparcCodeGen SparcCommonTable
+
+ add_subdirectory(TargetInfo)
+ add_subdirectory(MCTargetDesc)
++add_subdirectory(InstPrinter)
+Index: lib/Target/Sparc/Makefile
+===================================================================
+--- lib/Target/Sparc/Makefile
++++ lib/Target/Sparc/Makefile
+@@ -17,7 +17,7 @@ BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenI
+ SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
+ SparcGenCodeEmitter.inc
+
+-DIRS = TargetInfo MCTargetDesc
++DIRS = InstPrinter TargetInfo MCTargetDesc
+
+ include $(LEVEL)/Makefile.common
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198029-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198029-sparc.diff
new file mode 100644
index 0000000..6656bce
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198029-sparc.diff
@@ -0,0 +1,210 @@
+Pull in r198029 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add target specific MCExpr class to handle sparc specific modifiers like %hi, %lo, etc.,
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+@@ -0,0 +1,84 @@
++//===-- SparcMCExpr.cpp - Sparc specific MC expression classes --------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This file contains the implementation of the assembly expression modifiers
++// accepted by the Sparc architecture (e.g. "%hi", "%lo", ...).
++//
++//===----------------------------------------------------------------------===//
++
++#define DEBUG_TYPE "sparcmcexpr"
++#include "SparcMCExpr.h"
++#include "llvm/MC/MCContext.h"
++#include "llvm/MC/MCAssembler.h"
++#include "llvm/MC/MCELF.h"
++#include "llvm/Object/ELF.h"
++
++
++using namespace llvm;
++
++const SparcMCExpr*
++SparcMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
++ MCContext &Ctx) {
++ return new (Ctx) SparcMCExpr(Kind, Expr);
++}
++
++
++void SparcMCExpr::PrintImpl(raw_ostream &OS) const
++{
++ bool closeParen = true;
++ switch (Kind) {
++ case VK_Sparc_None: closeParen = false; break;
++ case VK_Sparc_LO: OS << "%lo("; break;
++ case VK_Sparc_HI: OS << "%hi("; break;
++ case VK_Sparc_H44: OS << "%h44("; break;
++ case VK_Sparc_M44: OS << "%m44("; break;
++ case VK_Sparc_L44: OS << "%l44("; break;
++ case VK_Sparc_HH: OS << "%hh("; break;
++ case VK_Sparc_HM: OS << "%hm("; break;
++ case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break;
++ case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break;
++ case VK_Sparc_TLS_GD_ADD: OS << "%tgd_add("; break;
++ case VK_Sparc_TLS_GD_CALL: OS << "%tgd_call("; break;
++ case VK_Sparc_TLS_LDM_HI22: OS << "%tldm_hi22("; break;
++ case VK_Sparc_TLS_LDM_LO10: OS << "%tldm_lo10("; break;
++ case VK_Sparc_TLS_LDM_ADD: OS << "%tldm_add("; break;
++ case VK_Sparc_TLS_LDM_CALL: OS << "%tldm_call("; break;
++ case VK_Sparc_TLS_LDO_HIX22: OS << "%tldo_hix22("; break;
++ case VK_Sparc_TLS_LDO_LOX10: OS << "%tldo_lox10("; break;
++ case VK_Sparc_TLS_LDO_ADD: OS << "%tldo_add("; break;
++ case VK_Sparc_TLS_IE_HI22: OS << "%tie_hi22("; break;
++ case VK_Sparc_TLS_IE_LO10: OS << "%tie_lo10("; break;
++ case VK_Sparc_TLS_IE_LD: OS << "%tie_ld("; break;
++ case VK_Sparc_TLS_IE_LDX: OS << "%tie_ldx("; break;
++ case VK_Sparc_TLS_IE_ADD: OS << "%tie_add("; break;
++ case VK_Sparc_TLS_LE_HIX22: OS << "%tle_hix22("; break;
++ case VK_Sparc_TLS_LE_LOX10: OS << "%tle_lox10("; break;
++ }
++
++ const MCExpr *Expr = getSubExpr();
++ Expr->print(OS);
++ if (closeParen)
++ OS << ')';
++}
++
++bool
++SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
++ const MCAsmLayout *Layout) const {
++ assert(0 && "FIXME: Implement SparcMCExpr::EvaluateAsRelocatableImpl");
++ return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
++}
++
++
++void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
++ assert(0 && "FIXME: Implement SparcMCExpr::fixELFSymbolsInTLSFixups");
++}
++
++void SparcMCExpr::AddValueSymbols(MCAssembler *Asm) const {
++ assert(0 && "FIXME: Implement SparcMCExpr::AddValueSymbols");
++}
+Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
++++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
+@@ -1,6 +1,7 @@
+ add_llvm_library(LLVMSparcDesc
+ SparcMCTargetDesc.cpp
+ SparcMCAsmInfo.cpp
++ SparcMCExpr.cpp
+ )
+
+ add_dependencies(LLVMSparcDesc SparcCommonTableGen)
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+@@ -0,0 +1,98 @@
++//====- SparcMCExpr.h - Sparc specific MC expression classes --*- C++ -*-=====//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This file describes Sparc-specific MCExprs, used for modifiers like
++// "%hi" or "%lo" etc.,
++//
++//===----------------------------------------------------------------------===//
++
++#ifndef LLVM_SPARCMCEXPR_H
++#define LLVM_SPARCMCEXPR_H
++
++#include "llvm/MC/MCExpr.h"
++
++namespace llvm {
++
++class SparcMCExpr : public MCTargetExpr {
++public:
++ enum VariantKind {
++ VK_Sparc_None,
++ VK_Sparc_LO,
++ VK_Sparc_HI,
++ VK_Sparc_H44,
++ VK_Sparc_M44,
++ VK_Sparc_L44,
++ VK_Sparc_HH,
++ VK_Sparc_HM,
++ VK_Sparc_TLS_GD_HI22,
++ VK_Sparc_TLS_GD_LO10,
++ VK_Sparc_TLS_GD_ADD,
++ VK_Sparc_TLS_GD_CALL,
++ VK_Sparc_TLS_LDM_HI22,
++ VK_Sparc_TLS_LDM_LO10,
++ VK_Sparc_TLS_LDM_ADD,
++ VK_Sparc_TLS_LDM_CALL,
++ VK_Sparc_TLS_LDO_HIX22,
++ VK_Sparc_TLS_LDO_LOX10,
++ VK_Sparc_TLS_LDO_ADD,
++ VK_Sparc_TLS_IE_HI22,
++ VK_Sparc_TLS_IE_LO10,
++ VK_Sparc_TLS_IE_LD,
++ VK_Sparc_TLS_IE_LDX,
++ VK_Sparc_TLS_IE_ADD,
++ VK_Sparc_TLS_LE_HIX22,
++ VK_Sparc_TLS_LE_LOX10
++ };
++
++private:
++ const VariantKind Kind;
++ const MCExpr *Expr;
++
++ explicit SparcMCExpr(VariantKind _Kind, const MCExpr *_Expr)
++ : Kind(_Kind), Expr(_Expr) {}
++
++public:
++ /// @name Construction
++ /// @{
++
++ static const SparcMCExpr *Create(VariantKind Kind, const MCExpr *Expr,
++ MCContext &Ctx);
++ /// @}
++ /// @name Accessors
++ /// @{
++
++ /// getOpcode - Get the kind of this expression.
++ VariantKind getKind() const { return Kind; }
++
++ /// getSubExpr - Get the child of this expression.
++ const MCExpr *getSubExpr() const { return Expr; }
++
++ /// @}
++ void PrintImpl(raw_ostream &OS) const;
++ bool EvaluateAsRelocatableImpl(MCValue &Res,
++ const MCAsmLayout *Layout) const;
++ void AddValueSymbols(MCAssembler *) const;
++ const MCSection *FindAssociatedSection() const {
++ return getSubExpr()->FindAssociatedSection();
++ }
++
++ void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const;
++
++ static bool classof(const MCExpr *E) {
++ return E->getKind() == MCExpr::Target;
++ }
++
++ static bool classof(const SparcMCExpr *) { return true; }
++
++
++};
++
++} // end namespace llvm.
++
++#endif
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff
new file mode 100644
index 0000000..7ab4291
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff
@@ -0,0 +1,678 @@
+Pull in r198030 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
+@@ -0,0 +1,40 @@
++//===-- SparcTargetStreamer.cpp - Sparc Target Streamer Methods -----------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This file provides Sparc specific target streamer methods.
++//
++//===----------------------------------------------------------------------===//
++
++#include "SparcTargetStreamer.h"
++#include "InstPrinter/SparcInstPrinter.h"
++#include "llvm/Support/FormattedStream.h"
++
++using namespace llvm;
++
++// pin vtable to this file
++void SparcTargetStreamer::anchor() {}
++
++SparcTargetAsmStreamer::SparcTargetAsmStreamer(formatted_raw_ostream &OS)
++ : OS(OS) {}
++
++void SparcTargetAsmStreamer::emitSparcRegisterIgnore(unsigned reg) {
++ OS << "\t.register "
++ << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
++ << ", #ignore\n";
++}
++
++void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) {
++ OS << "\t.register "
++ << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
++ << ", #scratch\n";
++}
++
++MCELFStreamer &SparcTargetELFStreamer::getStreamer() {
++ return static_cast<MCELFStreamer &>(*Streamer);
++}
+Index: lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
++++ lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
+@@ -19,5 +19,5 @@
+ type = Library
+ name = SparcDesc
+ parent = Sparc
+-required_libraries = MC SparcInfo Support
++required_libraries = MC SparcAsmPrinter SparcInfo Support
+ add_to_library_groups = Sparc
+Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
++++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
+@@ -2,6 +2,7 @@ add_llvm_library(LLVMSparcDesc
+ SparcMCTargetDesc.cpp
+ SparcMCAsmInfo.cpp
+ SparcMCExpr.cpp
++ SparcTargetStreamer.cpp
+ )
+
+ add_dependencies(LLVMSparcDesc SparcCommonTableGen)
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+@@ -13,6 +13,8 @@
+
+ #include "SparcMCTargetDesc.h"
+ #include "SparcMCAsmInfo.h"
++#include "SparcTargetStreamer.h"
++#include "InstPrinter/SparcInstPrinter.h"
+ #include "llvm/MC/MCCodeGenInfo.h"
+ #include "llvm/MC/MCInstrInfo.h"
+ #include "llvm/MC/MCRegisterInfo.h"
+@@ -86,6 +88,28 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(S
+ X->InitMCCodeGenInfo(RM, CM, OL);
+ return X;
+ }
++
++static MCStreamer *
++createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
++ bool isVerboseAsm, bool useLoc, bool useCFI,
++ bool useDwarfDirectory, MCInstPrinter *InstPrint,
++ MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) {
++ SparcTargetAsmStreamer *S = new SparcTargetAsmStreamer(OS);
++
++ return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
++ useDwarfDirectory, InstPrint, CE, TAB,
++ ShowInst);
++}
++
++static MCInstPrinter *createSparcMCInstPrinter(const Target &T,
++ unsigned SyntaxVariant,
++ const MCAsmInfo &MAI,
++ const MCInstrInfo &MII,
++ const MCRegisterInfo &MRI,
++ const MCSubtargetInfo &STI) {
++ return new SparcInstPrinter(MAI, MII, MRI);
++}
++
+ extern "C" void LLVMInitializeSparcTargetMC() {
+ // Register the MC asm info.
+ RegisterMCAsmInfo<SparcELFMCAsmInfo> X(TheSparcTarget);
+@@ -106,4 +130,15 @@ extern "C" void LLVMInitializeSparcTargetMC() {
+ // Register the MC subtarget info.
+ TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget,
+ createSparcMCSubtargetInfo);
++
++ TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
++ createMCAsmStreamer);
++ TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
++ createMCAsmStreamer);
++
++ // Register the MCInstPrinter
++ TargetRegistry::RegisterMCInstPrinter(TheSparcTarget,
++ createSparcMCInstPrinter);
++ TargetRegistry::RegisterMCInstPrinter(TheSparcV9Target,
++ createSparcMCInstPrinter);
+ }
+Index: lib/Target/Sparc/SparcTargetStreamer.h
+===================================================================
+--- lib/Target/Sparc/SparcTargetStreamer.h
++++ lib/Target/Sparc/SparcTargetStreamer.h
+@@ -0,0 +1,47 @@
++//===-- SparcTargetStreamer.h - Sparc Target Streamer ----------*- C++ -*--===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++
++#ifndef SPARCTARGETSTREAMER_H
++#define SPARCTARGETSTREAMER_H
++
++#include "llvm/MC/MCELFStreamer.h"
++#include "llvm/MC/MCStreamer.h"
++
++namespace llvm {
++class SparcTargetStreamer : public MCTargetStreamer {
++ virtual void anchor();
++
++public:
++ /// Emit ".register <reg>, #ignore".
++ virtual void emitSparcRegisterIgnore(unsigned reg) = 0;
++ /// Emit ".register <reg>, #scratch".
++ virtual void emitSparcRegisterScratch(unsigned reg) = 0;
++};
++
++// This part is for ascii assembly output
++class SparcTargetAsmStreamer : public SparcTargetStreamer {
++ formatted_raw_ostream &OS;
++
++public:
++ SparcTargetAsmStreamer(formatted_raw_ostream &OS);
++ virtual void emitSparcRegisterIgnore(unsigned reg);
++ virtual void emitSparcRegisterScratch(unsigned reg);
++
++};
++
++// This part is for ELF object output
++class SparcTargetELFStreamer : public SparcTargetStreamer {
++public:
++ MCELFStreamer &getStreamer();
++ virtual void emitSparcRegisterIgnore(unsigned reg) {}
++ virtual void emitSparcRegisterScratch(unsigned reg) {}
++};
++} // end namespace llvm
++
++#endif
+Index: lib/Target/Sparc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/CMakeLists.txt
++++ lib/Target/Sparc/CMakeLists.txt
+@@ -23,6 +23,7 @@ add_llvm_target(SparcCodeGen
+ SparcSelectionDAGInfo.cpp
+ SparcJITInfo.cpp
+ SparcCodeEmitter.cpp
++ SparcMCInstLower.cpp
+ )
+
+ add_dependencies(LLVMSparcCodeGen SparcCommonTableGen intrinsics_gen)
+Index: lib/Target/Sparc/Sparc.td
+===================================================================
+--- lib/Target/Sparc/Sparc.td
++++ lib/Target/Sparc/Sparc.td
+@@ -65,6 +65,10 @@ def : Proc<"ultrasparc", [FeatureV9, FeatureV
+ def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>;
+ def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>;
+
++def SparcAsmWriter : AsmWriter {
++ string AsmWriterClassName = "InstPrinter";
++ bit isMCAsmWriter = 1;
++}
+
+ //===----------------------------------------------------------------------===//
+ // Declare the target which we are implementing
+@@ -73,4 +77,6 @@ def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV
+ def Sparc : Target {
+ // Pull in Instruction Info:
+ let InstructionSet = SparcInstrInfo;
++
++ let AssemblyWriters = [SparcAsmWriter];
+ }
+Index: lib/Target/Sparc/SparcMCInstLower.cpp
+===================================================================
+--- lib/Target/Sparc/SparcMCInstLower.cpp
++++ lib/Target/Sparc/SparcMCInstLower.cpp
+@@ -0,0 +1,141 @@
++//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This file contains code to lower Sparc MachineInstrs to their corresponding
++// MCInst records.
++//
++//===----------------------------------------------------------------------===//
++
++#include "Sparc.h"
++#include "MCTargetDesc/SparcBaseInfo.h"
++#include "MCTargetDesc/SparcMCExpr.h"
++#include "llvm/CodeGen/AsmPrinter.h"
++#include "llvm/CodeGen/MachineFunction.h"
++#include "llvm/CodeGen/MachineInstr.h"
++#include "llvm/CodeGen/MachineOperand.h"
++#include "llvm/MC/MCContext.h"
++#include "llvm/MC/MCAsmInfo.h"
++#include "llvm/MC/MCExpr.h"
++#include "llvm/MC/MCInst.h"
++#include "llvm/Target/Mangler.h"
++#include "llvm/ADT/SmallString.h"
++
++using namespace llvm;
++
++
++static MCOperand LowerSymbolOperand(const MachineInstr *MI,
++ const MachineOperand &MO,
++ AsmPrinter &AP) {
++
++ SparcMCExpr::VariantKind Kind;
++ const MCSymbol *Symbol = 0;
++
++ unsigned TF = MO.getTargetFlags();
++
++ switch(TF) {
++ default: llvm_unreachable("Unknown target flags on operand");
++ case SPII::MO_NO_FLAG: Kind = SparcMCExpr::VK_Sparc_None; break;
++ case SPII::MO_LO: Kind = SparcMCExpr::VK_Sparc_LO; break;
++ case SPII::MO_HI: Kind = SparcMCExpr::VK_Sparc_HI; break;
++ case SPII::MO_H44: Kind = SparcMCExpr::VK_Sparc_H44; break;
++ case SPII::MO_M44: Kind = SparcMCExpr::VK_Sparc_M44; break;
++ case SPII::MO_L44: Kind = SparcMCExpr::VK_Sparc_L44; break;
++ case SPII::MO_HH: Kind = SparcMCExpr::VK_Sparc_HH; break;
++ case SPII::MO_HM: Kind = SparcMCExpr::VK_Sparc_HM; break;
++ case SPII::MO_TLS_GD_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_GD_HI22; break;
++ case SPII::MO_TLS_GD_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_GD_LO10; break;
++ case SPII::MO_TLS_GD_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_GD_ADD; break;
++ case SPII::MO_TLS_GD_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_GD_CALL; break;
++ case SPII::MO_TLS_LDM_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_HI22; break;
++ case SPII::MO_TLS_LDM_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_LO10; break;
++ case SPII::MO_TLS_LDM_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_ADD; break;
++ case SPII::MO_TLS_LDM_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_CALL; break;
++ case SPII::MO_TLS_LDO_HIX22:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_HIX22; break;
++ case SPII::MO_TLS_LDO_LOX10:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_LOX10; break;
++ case SPII::MO_TLS_LDO_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDO_ADD; break;
++ case SPII::MO_TLS_IE_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_IE_HI22; break;
++ case SPII::MO_TLS_IE_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LO10; break;
++ case SPII::MO_TLS_IE_LD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LD; break;
++ case SPII::MO_TLS_IE_LDX: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LDX; break;
++ case SPII::MO_TLS_IE_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_ADD; break;
++ case SPII::MO_TLS_LE_HIX22: Kind = SparcMCExpr::VK_Sparc_TLS_LE_HIX22; break;
++ case SPII::MO_TLS_LE_LOX10: Kind = SparcMCExpr::VK_Sparc_TLS_LE_LOX10; break;
++ }
++
++ switch(MO.getType()) {
++ default: llvm_unreachable("Unknown type in LowerSymbolOperand");
++ case MachineOperand::MO_MachineBasicBlock:
++ Symbol = MO.getMBB()->getSymbol();
++ break;
++
++ case MachineOperand::MO_GlobalAddress:
++ Symbol = AP.getSymbol(MO.getGlobal());
++ break;
++
++ case MachineOperand::MO_BlockAddress:
++ Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
++ break;
++
++ case MachineOperand::MO_ExternalSymbol:
++ Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
++ break;
++
++ case MachineOperand::MO_ConstantPoolIndex:
++ Symbol = AP.GetCPISymbol(MO.getIndex());
++ break;
++ }
++
++ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol,
++ AP.OutContext);
++ const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym,
++ AP.OutContext);
++ return MCOperand::CreateExpr(expr);
++}
++
++static MCOperand LowerOperand(const MachineInstr *MI,
++ const MachineOperand &MO,
++ AsmPrinter &AP) {
++ switch(MO.getType()) {
++ default: llvm_unreachable("unknown operand type"); break;
++ case MachineOperand::MO_Register:
++ if (MO.isImplicit())
++ break;
++ return MCOperand::CreateReg(MO.getReg());
++
++ case MachineOperand::MO_Immediate:
++ return MCOperand::CreateImm(MO.getImm());
++
++ case MachineOperand::MO_MachineBasicBlock:
++ case MachineOperand::MO_GlobalAddress:
++ case MachineOperand::MO_BlockAddress:
++ case MachineOperand::MO_ExternalSymbol:
++ case MachineOperand::MO_ConstantPoolIndex:
++ return LowerSymbolOperand(MI, MO, AP);
++
++ case MachineOperand::MO_RegisterMask: break;
++
++ }
++ return MCOperand();
++}
++
++void llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
++ MCInst &OutMI,
++ AsmPrinter &AP)
++{
++
++ OutMI.setOpcode(MI->getOpcode());
++
++ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
++ const MachineOperand &MO = MI->getOperand(i);
++ MCOperand MCOp = LowerOperand(MI, MO, AP);
++
++ if (MCOp.isValid())
++ OutMI.addOperand(MCOp);
++ }
++}
+Index: lib/Target/Sparc/Sparc.h
+===================================================================
+--- lib/Target/Sparc/Sparc.h
++++ lib/Target/Sparc/Sparc.h
+@@ -23,6 +23,9 @@ namespace llvm {
+ class FunctionPass;
+ class SparcTargetMachine;
+ class formatted_raw_ostream;
++ class AsmPrinter;
++ class MCInst;
++ class MachineInstr;
+
+ FunctionPass *createSparcISelDag(SparcTargetMachine &TM);
+ FunctionPass *createSparcDelaySlotFillerPass(TargetMachine &TM);
+@@ -29,6 +32,9 @@ namespace llvm {
+ FunctionPass *createSparcJITCodeEmitterPass(SparcTargetMachine &TM,
+ JITCodeEmitter &JCE);
+
++ void LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
++ MCInst &OutMI,
++ AsmPrinter &AP);
+ } // end namespace llvm;
+
+ namespace llvm {
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -16,12 +16,17 @@
+ #include "Sparc.h"
+ #include "SparcInstrInfo.h"
+ #include "SparcTargetMachine.h"
++#include "SparcTargetStreamer.h"
++#include "InstPrinter/SparcInstPrinter.h"
+ #include "MCTargetDesc/SparcBaseInfo.h"
++#include "MCTargetDesc/SparcMCExpr.h"
+ #include "llvm/ADT/SmallString.h"
+ #include "llvm/CodeGen/AsmPrinter.h"
+ #include "llvm/CodeGen/MachineInstr.h"
+ #include "llvm/CodeGen/MachineRegisterInfo.h"
+ #include "llvm/MC/MCAsmInfo.h"
++#include "llvm/MC/MCContext.h"
++#include "llvm/MC/MCInst.h"
+ #include "llvm/MC/MCStreamer.h"
+ #include "llvm/MC/MCSymbol.h"
+ #include "llvm/Support/TargetRegistry.h"
+@@ -31,6 +36,9 @@ using namespace llvm;
+
+ namespace {
+ class SparcAsmPrinter : public AsmPrinter {
++ SparcTargetStreamer &getTargetStreamer() {
++ return static_cast<SparcTargetStreamer&>(OutStreamer.getTargetStreamer());
++ }
+ public:
+ explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {}
+@@ -45,14 +53,11 @@ namespace {
+ void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
+
+ virtual void EmitFunctionBodyStart();
+- virtual void EmitInstruction(const MachineInstr *MI) {
+- SmallString<128> Str;
+- raw_svector_ostream OS(Str);
+- printInstruction(MI, OS);
+- OutStreamer.EmitRawText(OS.str());
++ virtual void EmitInstruction(const MachineInstr *MI);
++
++ static const char *getRegisterName(unsigned RegNo) {
++ return SparcInstPrinter::getRegisterName(RegNo);
+ }
+- void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd.
+- static const char *getRegisterName(unsigned RegNo);
+
+ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+@@ -61,25 +66,139 @@ namespace {
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
+
+- bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS);
+-
+ virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
+ const;
+- void EmitGlobalRegisterDecl(unsigned reg) {
+- SmallString<128> Str;
+- raw_svector_ostream OS(Str);
+- OS << "\t.register "
+- << "%" << StringRef(getRegisterName(reg)).lower()
+- << ", "
+- << ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch");
+- OutStreamer.EmitRawText(OS.str());
+- }
+
+ };
+ } // end of anonymous namespace
+
+-#include "SparcGenAsmWriter.inc"
++static MCOperand createPCXCallOP(MCSymbol *Label,
++ MCContext &OutContext)
++{
++ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
++ OutContext);
++ const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
++ MCSym, OutContext);
++ return MCOperand::CreateExpr(expr);
++}
+
++static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
++ MCSymbol *GOTLabel, MCSymbol *StartLabel,
++ MCSymbol *CurLabel,
++ MCContext &OutContext)
++{
++ const MCSymbolRefExpr *GOT = MCSymbolRefExpr::Create(GOTLabel, OutContext);
++ const MCSymbolRefExpr *Start = MCSymbolRefExpr::Create(StartLabel,
++ OutContext);
++ const MCSymbolRefExpr *Cur = MCSymbolRefExpr::Create(CurLabel,
++ OutContext);
++
++ const MCBinaryExpr *Sub = MCBinaryExpr::CreateSub(Cur, Start, OutContext);
++ const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(GOT, Sub, OutContext);
++ const SparcMCExpr *expr = SparcMCExpr::Create(Kind,
++ Add, OutContext);
++ return MCOperand::CreateExpr(expr);
++}
++
++static void EmitCall(MCStreamer &OutStreamer,
++ MCOperand &Callee)
++{
++ MCInst CallInst;
++ CallInst.setOpcode(SP::CALL);
++ CallInst.addOperand(Callee);
++ OutStreamer.EmitInstruction(CallInst);
++}
++
++static void EmitSETHI(MCStreamer &OutStreamer,
++ MCOperand &Imm, MCOperand &RD)
++{
++ MCInst SETHIInst;
++ SETHIInst.setOpcode(SP::SETHIi);
++ SETHIInst.addOperand(RD);
++ SETHIInst.addOperand(Imm);
++ OutStreamer.EmitInstruction(SETHIInst);
++}
++
++static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
++ MCOperand &Imm, MCOperand &RD)
++{
++ MCInst ORInst;
++ ORInst.setOpcode(SP::ORri);
++ ORInst.addOperand(RD);
++ ORInst.addOperand(RS1);
++ ORInst.addOperand(Imm);
++ OutStreamer.EmitInstruction(ORInst);
++}
++
++void EmitADD(MCStreamer &OutStreamer,
++ MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
++{
++ MCInst ADDInst;
++ ADDInst.setOpcode(SP::ADDrr);
++ ADDInst.addOperand(RD);
++ ADDInst.addOperand(RS1);
++ ADDInst.addOperand(RS2);
++ OutStreamer.EmitInstruction(ADDInst);
++}
++
++static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
++ MCStreamer &OutStreamer,
++ MCContext &OutContext)
++{
++ const MachineOperand &MO = MI->getOperand(0);
++ MCSymbol *StartLabel = OutContext.CreateTempSymbol();
++ MCSymbol *EndLabel = OutContext.CreateTempSymbol();
++ MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
++ MCSymbol *GOTLabel =
++ OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
++
++ assert(MO.getReg() != SP::O7 &&
++ "%o7 is assigned as destination for getpcx!");
++
++ MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
++ MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
++
++ // <StartLabel>:
++ // call <EndLabel>
++ // <SethiLabel>:
++ // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO>
++ // <EndLabel>:
++ // or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO>
++ // add <MO>, %o7, <MO>
++
++ OutStreamer.EmitLabel(StartLabel);
++ MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
++ EmitCall(OutStreamer, Callee);
++ OutStreamer.EmitLabel(SethiLabel);
++ MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI,
++ GOTLabel, StartLabel, SethiLabel,
++ OutContext);
++ EmitSETHI(OutStreamer, hiImm, MCRegOP);
++ OutStreamer.EmitLabel(EndLabel);
++ MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO,
++ GOTLabel, StartLabel, EndLabel,
++ OutContext);
++ EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP);
++ EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
++}
++
++void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
++{
++ MCInst TmpInst;
++
++ switch (MI->getOpcode()) {
++ default: break;
++ case TargetOpcode::DBG_VALUE:
++ // FIXME: Debug Value.
++ return;
++ case SP::GETPCX:
++ LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
++ return;
++ }
++ LowerSparcMachineInstrToMCInst(MI, TmpInst, *this);
++ OutStreamer.EmitInstruction(TmpInst);
++}
++
+ void SparcAsmPrinter::EmitFunctionBodyStart() {
+ if (!TM.getSubtarget<SparcSubtarget>().is64Bit())
+ return;
+@@ -90,7 +209,11 @@ void SparcAsmPrinter::EmitFunctionBodyStart() {
+ unsigned reg = globalRegs[i];
+ if (MRI.use_empty(reg))
+ continue;
+- EmitGlobalRegisterDecl(reg);
++
++ if (reg == SP::G6 || reg == SP::G7)
++ getTargetStreamer().emitSparcRegisterIgnore(reg);
++ else
++ getTargetStreamer().emitSparcRegisterScratch(reg);
+ }
+ }
+
+@@ -226,46 +349,6 @@ void SparcAsmPrinter::printMemOperand(const Machin
+ printOperand(MI, opNum+1, O);
+ }
+
+-bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum,
+- raw_ostream &O) {
+- std::string operand = "";
+- const MachineOperand &MO = MI->getOperand(opNum);
+- switch (MO.getType()) {
+- default: llvm_unreachable("Operand is not a register");
+- case MachineOperand::MO_Register:
+- assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
+- "Operand is not a physical register ");
+- assert(MO.getReg() != SP::O7 &&
+- "%o7 is assigned as destination for getpcx!");
+- operand = "%" + StringRef(getRegisterName(MO.getReg())).lower();
+- break;
+- }
+-
+- unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber();
+- unsigned bbNum = MI->getParent()->getNumber();
+-
+- O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n";
+- O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ;
+-
+- O << "\t sethi\t"
+- << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
+- << ")), " << operand << '\n' ;
+-
+- O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ;
+- O << "\tor\t" << operand
+- << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
+- << ")), " << operand << '\n';
+- O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
+-
+- return true;
+-}
+-
+-void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum,
+- raw_ostream &O) {
+- int CC = (int)MI->getOperand(opNum).getImm();
+- O << SPARCCondCodeToString((SPCC::CondCodes)CC);
+-}
+-
+ /// PrintAsmOperand - Print out an operand for an inline asm expression.
+ ///
+ bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+@@ -23,8 +23,7 @@
+ using namespace llvm;
+
+ #define GET_INSTRUCTION_NAME
+-// Uncomment the following line once we are ready to use MCAsmWriter.
+-//#include "SparcGenAsmWriter.inc"
++#include "SparcGenAsmWriter.inc"
+
+ void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
+ {
+Index: test/CodeGen/SPARC/exception.ll
+===================================================================
+--- test/CodeGen/SPARC/exception.ll
++++ test/CodeGen/SPARC/exception.ll
+@@ -11,7 +11,7 @@
+
+ ; CHECK-LABEL: main:
+ ; CHECK: .cfi_startproc
+-; CHECK: .cfi_def_cfa_register 30
++; CHECK: .cfi_def_cfa_register {{30|%fp}}
+ ; CHECK: .cfi_window_save
+ ; CHECK: .cfi_register 15, 31
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff
new file mode 100644
index 0000000..2429e52
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198145-sparc.diff
@@ -0,0 +1,166 @@
+Pull in r198145 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9]: Implement lowering of long double (fp128) arguments in Sparc64 ABI.
+ Also, pass fp128 arguments to varargs through integer registers if necessary.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/CodeGen/SPARC/64abi.ll
+===================================================================
+--- test/CodeGen/SPARC/64abi.ll
++++ test/CodeGen/SPARC/64abi.ll
+@@ -411,3 +411,33 @@ entry:
+ }
+
+ declare i32 @use_buf(i32, i8*)
++
++; CHECK-LABEL: test_fp128_args
++; CHECK-DAG: std %f0, [%fp+{{.+}}]
++; CHECK-DAG: std %f2, [%fp+{{.+}}]
++; CHECK-DAG: std %f6, [%fp+{{.+}}]
++; CHECK-DAG: std %f4, [%fp+{{.+}}]
++; CHECK: add %fp, [[Offset:[0-9]+]], %o0
++; CHECK: call _Qp_add
++; CHECK: ldd [%fp+[[Offset]]], %f0
++define fp128 @test_fp128_args(fp128 %a, fp128 %b) {
++entry:
++ %0 = fadd fp128 %a, %b
++ ret fp128 %0
++}
++
++declare i64 @receive_fp128(i64 %a, ...)
++
++; CHECK-LABEL: test_fp128_variable_args
++; CHECK-DAG: std %f4, [%sp+[[Offset0:[0-9]+]]]
++; CHECK-DAG: std %f6, [%sp+[[Offset1:[0-9]+]]]
++; CHECK-DAG: ldx [%sp+[[Offset0]]], %o2
++; CHECK-DAG: ldx [%sp+[[Offset1]]], %o3
++; CHECK: call receive_fp128
++define i64 @test_fp128_variable_args(i64 %a, fp128 %b) {
++entry:
++ %0 = call i64 (i64, ...)* @receive_fp128(i64 %a, fp128 %b)
++ ret i64 %0
++}
++
++
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -80,11 +80,14 @@ static bool CC_Sparc_Assign_f64(unsigned &ValNo, M
+ static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT,
+ MVT &LocVT, CCValAssign::LocInfo &LocInfo,
+ ISD::ArgFlagsTy &ArgFlags, CCState &State) {
+- assert((LocVT == MVT::f32 || LocVT.getSizeInBits() == 64) &&
++ assert((LocVT == MVT::f32 || LocVT == MVT::f128
++ || LocVT.getSizeInBits() == 64) &&
+ "Can't handle non-64 bits locations");
+
+ // Stack space is allocated for all arguments starting from [%fp+BIAS+128].
+- unsigned Offset = State.AllocateStack(8, 8);
++ unsigned size = (LocVT == MVT::f128) ? 16 : 8;
++ unsigned alignment = (LocVT == MVT::f128) ? 16 : 8;
++ unsigned Offset = State.AllocateStack(size, alignment);
+ unsigned Reg = 0;
+
+ if (LocVT == MVT::i64 && Offset < 6*8)
+@@ -96,6 +99,9 @@ static bool CC_Sparc64_Full(unsigned &ValNo, MVT &
+ else if (LocVT == MVT::f32 && Offset < 16*8)
+ // Promote floats to %f1, %f3, ...
+ Reg = SP::F1 + Offset/4;
++ else if (LocVT == MVT::f128 && Offset < 16*8)
++ // Promote long doubles to %q0-%q28. (Which LLVM calls Q0-Q7).
++ Reg = SP::Q0 + Offset/16;
+
+ // Promote to register when possible, otherwise use the stack slot.
+ if (Reg) {
+@@ -998,9 +1004,10 @@ static void fixupVariableFloatArgs(SmallVectorImpl
+ ArrayRef<ISD::OutputArg> Outs) {
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ const CCValAssign &VA = ArgLocs[i];
++ MVT ValTy = VA.getLocVT();
+ // FIXME: What about f32 arguments? C promotes them to f64 when calling
+ // varargs functions.
+- if (!VA.isRegLoc() || VA.getLocVT() != MVT::f64)
++ if (!VA.isRegLoc() || (ValTy != MVT::f64 && ValTy != MVT::f128))
+ continue;
+ // The fixed arguments to a varargs function still go in FP registers.
+ if (Outs[VA.getValNo()].IsFixed)
+@@ -1010,15 +1017,25 @@ static void fixupVariableFloatArgs(SmallVectorImpl
+ CCValAssign NewVA;
+
+ // Determine the offset into the argument array.
+- unsigned Offset = 8 * (VA.getLocReg() - SP::D0);
++ unsigned firstReg = (ValTy == MVT::f64) ? SP::D0 : SP::Q0;
++ unsigned argSize = (ValTy == MVT::f64) ? 8 : 16;
++ unsigned Offset = argSize * (VA.getLocReg() - firstReg);
+ assert(Offset < 16*8 && "Offset out of range, bad register enum?");
+
+ if (Offset < 6*8) {
+ // This argument should go in %i0-%i5.
+ unsigned IReg = SP::I0 + Offset/8;
+- // Full register, just bitconvert into i64.
+- NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
+- IReg, MVT::i64, CCValAssign::BCvt);
++ if (ValTy == MVT::f64)
++ // Full register, just bitconvert into i64.
++ NewVA = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
++ IReg, MVT::i64, CCValAssign::BCvt);
++ else {
++ assert(ValTy == MVT::f128 && "Unexpected type!");
++ // Full register, just bitconvert into i128 -- We will lower this into
++ // two i64s in LowerCall_64.
++ NewVA = CCValAssign::getCustomReg(VA.getValNo(), VA.getValVT(),
++ IReg, MVT::i128, CCValAssign::BCvt);
++ }
+ } else {
+ // This needs to go to memory, we're out of integer registers.
+ NewVA = CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
+@@ -1094,11 +1111,46 @@ SparcTargetLowering::LowerCall_64(TargetLowering::
+ Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
+ break;
+ case CCValAssign::BCvt:
+- Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
++ // fixupVariableFloatArgs() may create bitcasts from f128 to i128. But
++ // SPARC does not support i128 natively. Lower it into two i64, see below.
++ if (!VA.needsCustom() || VA.getValVT() != MVT::f128
++ || VA.getLocVT() != MVT::i128)
++ Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg);
+ break;
+ }
+
+ if (VA.isRegLoc()) {
++ if (VA.needsCustom() && VA.getValVT() == MVT::f128
++ && VA.getLocVT() == MVT::i128) {
++ // Store and reload into the interger register reg and reg+1.
++ unsigned Offset = 8 * (VA.getLocReg() - SP::I0);
++ unsigned StackOffset = Offset + Subtarget->getStackPointerBias() + 128;
++ SDValue StackPtr = DAG.getRegister(SP::O6, getPointerTy());
++ SDValue HiPtrOff = DAG.getIntPtrConstant(StackOffset);
++ HiPtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr,
++ HiPtrOff);
++ SDValue LoPtrOff = DAG.getIntPtrConstant(StackOffset + 8);
++ LoPtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr,
++ LoPtrOff);
++
++ // Store to %sp+BIAS+128+Offset
++ SDValue Store = DAG.getStore(Chain, DL, Arg, HiPtrOff,
++ MachinePointerInfo(),
++ false, false, 0);
++ // Load into Reg and Reg+1
++ SDValue Hi64 = DAG.getLoad(MVT::i64, DL, Store, HiPtrOff,
++ MachinePointerInfo(),
++ false, false, false, 0);
++ SDValue Lo64 = DAG.getLoad(MVT::i64, DL, Store, LoPtrOff,
++ MachinePointerInfo(),
++ false, false, false, 0);
++ RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()),
++ Hi64));
++ RegsToPass.push_back(std::make_pair(toCallerWindow(VA.getLocReg()+1),
++ Lo64));
++ continue;
++ }
++
+ // The custom bit on an i32 return value indicates that it should be
+ // passed in the high bits of the register.
+ if (VA.getValVT() == MVT::i32 && VA.needsCustom()) {
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198149-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198149-sparc.diff
new file mode 100644
index 0000000..912daf3
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198149-sparc.diff
@@ -0,0 +1,54 @@
+Pull in r198149 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9] For codegen generated library calls that return float, set inreg flag manually in LowerCall().
+ This makes the sparc backend to generate Sparc64 ABI compliant code.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1252,6 +1252,12 @@ SparcTargetLowering::LowerCall_64(TargetLowering::
+ SmallVector<CCValAssign, 16> RVLocs;
+ CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(),
+ DAG.getTarget(), RVLocs, *DAG.getContext());
++
++ // Set inreg flag manually for codegen generated library calls that
++ // return float.
++ if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && CLI.CS == 0)
++ CLI.Ins[0].Flags.setInReg();
++
+ RVInfo.AnalyzeCallResult(CLI.Ins, CC_Sparc64);
+
+ // Copy all of the result registers out of their specified physreg.
+Index: test/CodeGen/SPARC/64abi.ll
+===================================================================
+--- test/CodeGen/SPARC/64abi.ll
++++ test/CodeGen/SPARC/64abi.ll
+@@ -440,4 +440,25 @@ entry:
+ ret i64 %0
+ }
+
++; CHECK-LABEL: test_call_libfunc
++; CHECK: st %f1, [%fp+[[Offset0:[0-9]+]]]
++; CHECK: fmovs %f3, %f1
++; CHECK: call cosf
++; CHECK: st %f0, [%fp+[[Offset1:[0-9]+]]]
++; CHECK: ld [%fp+[[Offset0]]], %f1
++; CHECK: call sinf
++; CHECK: ld [%fp+[[Offset1]]], %f1
++; CHECK: fmuls %f1, %f0, %f0
+
++define inreg float @test_call_libfunc(float %arg0, float %arg1) {
++entry:
++ %0 = tail call inreg float @cosf(float %arg1)
++ %1 = tail call inreg float @sinf(float %arg0)
++ %2 = fmul float %0, %1
++ ret float %2
++}
++
++declare inreg float @cosf(float %arg) readnone nounwind
++declare inreg float @sinf(float %arg) readnone nounwind
++
++
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198157-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198157-sparc.diff
new file mode 100644
index 0000000..42ef3db
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198157-sparc.diff
@@ -0,0 +1,368 @@
+Pull in r198157 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9] Use separate instruction patterns for 64 bit arithmetic instructions instead of reusing 32 bit instruction patterns.
+ This is done to avoid spilling the result of the 64-bit instructions to a 4-byte slot.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -227,7 +227,7 @@ void SparcAsmPrinter::printOperand(const MachineIn
+ if (MI->getOpcode() == SP::CALL)
+ assert(TF == SPII::MO_NO_FLAG &&
+ "Cannot handle target flags on call address");
+- else if (MI->getOpcode() == SP::SETHIi)
++ else if (MI->getOpcode() == SP::SETHIi || MI->getOpcode() == SP::SETHIXi)
+ assert((TF == SPII::MO_HI || TF == SPII::MO_H44 || TF == SPII::MO_HH
+ || TF == SPII::MO_TLS_GD_HI22
+ || TF == SPII::MO_TLS_LDM_HI22
+@@ -250,7 +250,7 @@ void SparcAsmPrinter::printOperand(const MachineIn
+ else if (MI->getOpcode() == SP::TLS_LDXrr)
+ assert(TF == SPII::MO_TLS_IE_LDX &&
+ "Cannot handle target flags on ldx for TLS");
+- else if (MI->getOpcode() == SP::XORri)
++ else if (MI->getOpcode() == SP::XORri || MI->getOpcode() == SP::XORXri)
+ assert((TF == SPII::MO_TLS_LDO_LOX10 || TF == SPII::MO_TLS_LE_LOX10) &&
+ "Cannot handle target flags on xor for TLS");
+ else
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -141,32 +141,36 @@ def : Pat<(i64 imm:$val),
+ let Predicates = [Is64Bit] in {
+
+ // Register-register instructions.
++defm ANDX : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>;
++defm ORX : F3_12<"or", 0b000010, or, I64Regs, i64, i64imm>;
++defm XORX : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>;
+
+-def : Pat<(and i64:$a, i64:$b), (ANDrr $a, $b)>;
+-def : Pat<(or i64:$a, i64:$b), (ORrr $a, $b)>;
+-def : Pat<(xor i64:$a, i64:$b), (XORrr $a, $b)>;
++def ANDXNrr : F3_1<2, 0b000101,
++ (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c),
++ "andn $b, $c, $dst",
++ [(set i64:$dst, (and i64:$b, (not i64:$c)))]>;
++def ORXNrr : F3_1<2, 0b000110,
++ (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c),
++ "orn $b, $c, $dst",
++ [(set i64:$dst, (or i64:$b, (not i64:$c)))]>;
++def XNORXrr : F3_1<2, 0b000111,
++ (outs I64Regs:$dst), (ins I64Regs:$b, I64Regs:$c),
++ "xnor $b, $c, $dst",
++ [(set i64:$dst, (not (xor i64:$b, i64:$c)))]>;
+
+-def : Pat<(and i64:$a, (not i64:$b)), (ANDNrr $a, $b)>;
+-def : Pat<(or i64:$a, (not i64:$b)), (ORNrr $a, $b)>;
+-def : Pat<(xor i64:$a, (not i64:$b)), (XNORrr $a, $b)>;
++defm ADDX : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>;
++defm SUBX : F3_12<"sub", 0b000100, sub, I64Regs, i64, i64imm>;
+
+-def : Pat<(add i64:$a, i64:$b), (ADDrr $a, $b)>;
+-def : Pat<(sub i64:$a, i64:$b), (SUBrr $a, $b)>;
+-
+ def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>;
+
+-def : Pat<(tlsadd i64:$a, i64:$b, tglobaltlsaddr:$sym),
+- (TLS_ADDrr $a, $b, $sym)>;
++def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd),
++ (ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym),
++ "add $rs1, $rs2, $rd, $sym",
++ [(set i64:$rd,
++ (tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>;
+
+ // Register-immediate instructions.
+
+-def : Pat<(and i64:$a, (i64 simm13:$b)), (ANDri $a, (as_i32imm $b))>;
+-def : Pat<(or i64:$a, (i64 simm13:$b)), (ORri $a, (as_i32imm $b))>;
+-def : Pat<(xor i64:$a, (i64 simm13:$b)), (XORri $a, (as_i32imm $b))>;
+-
+-def : Pat<(add i64:$a, (i64 simm13:$b)), (ADDri $a, (as_i32imm $b))>;
+-def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>;
+-
+ def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>;
+
+ def : Pat<(ctpop i64:$src), (POPCrr $src)>;
+@@ -402,3 +406,38 @@ def : Pat<(SPselectfcc (i64 simm11:$t), i64:$f, im
+ (MOVFCCri (as_i32imm $t), $f, imm:$cond)>;
+
+ } // Predicates = [Is64Bit]
++
++
++// 64 bit SETHI
++let Predicates = [Is64Bit] in {
++def SETHIXi : F2_1<0b100,
++ (outs IntRegs:$rd), (ins i64imm:$imm22),
++ "sethi $imm22, $rd",
++ [(set i64:$rd, SETHIimm:$imm22)]>;
++}
++// Global addresses, constant pool entries
++let Predicates = [Is64Bit] in {
++
++def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
++def : Pat<(SPlo tglobaladdr:$in), (ORXri (i64 G0), tglobaladdr:$in)>;
++def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>;
++def : Pat<(SPlo tconstpool:$in), (ORXri (i64 G0), tconstpool:$in)>;
++
++// GlobalTLS addresses
++def : Pat<(SPhi tglobaltlsaddr:$in), (SETHIi tglobaltlsaddr:$in)>;
++def : Pat<(SPlo tglobaltlsaddr:$in), (ORXri (i64 G0), tglobaltlsaddr:$in)>;
++def : Pat<(add (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)),
++ (ADDXri (SETHIXi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>;
++def : Pat<(xor (SPhi tglobaltlsaddr:$in1), (SPlo tglobaltlsaddr:$in2)),
++ (XORXri (SETHIXi tglobaltlsaddr:$in1), (tglobaltlsaddr:$in2))>;
++
++// Blockaddress
++def : Pat<(SPhi tblockaddress:$in), (SETHIi tblockaddress:$in)>;
++def : Pat<(SPlo tblockaddress:$in), (ORXri (i64 G0), tblockaddress:$in)>;
++
++// Add reg, lo. This is used when taking the addr of a global/constpool entry.
++def : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (ADDXri $r, tglobaladdr:$in)>;
++def : Pat<(add iPTR:$r, (SPlo tconstpool:$in)), (ADDXri $r, tconstpool:$in)>;
++def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)),
++ (ADDXri $r, tblockaddress:$in)>;
++}
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -210,15 +210,16 @@ def FCC_O : FCC_VAL<29>; // Ordered
+ //===----------------------------------------------------------------------===//
+
+ /// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot.
+-multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode> {
++multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode,
++ RegisterClass RC, ValueType Ty, Operand immOp> {
+ def rr : F3_1<2, Op3Val,
+- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
++ (outs RC:$dst), (ins RC:$b, RC:$c),
+ !strconcat(OpcStr, " $b, $c, $dst"),
+- [(set i32:$dst, (OpNode i32:$b, i32:$c))]>;
++ [(set Ty:$dst, (OpNode Ty:$b, Ty:$c))]>;
+ def ri : F3_2<2, Op3Val,
+- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
++ (outs RC:$dst), (ins RC:$b, immOp:$c),
+ !strconcat(OpcStr, " $b, $c, $dst"),
+- [(set i32:$dst, (OpNode i32:$b, (i32 simm13:$c)))]>;
++ [(set Ty:$dst, (OpNode Ty:$b, (Ty simm13:$c)))]>;
+ }
+
+ /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no
+@@ -464,7 +465,7 @@ let rd = 0, imm22 = 0 in
+ def NOP : F2_1<0b100, (outs), (ins), "nop", []>;
+
+ // Section B.11 - Logical Instructions, p. 106
+-defm AND : F3_12<"and", 0b000001, and>;
++defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>;
+
+ def ANDNrr : F3_1<2, 0b000101,
+ (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
+@@ -474,7 +475,7 @@ def ANDNri : F3_2<2, 0b000101,
+ (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
+ "andn $b, $c, $dst", []>;
+
+-defm OR : F3_12<"or", 0b000010, or>;
++defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>;
+
+ def ORNrr : F3_1<2, 0b000110,
+ (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
+@@ -483,7 +484,7 @@ def ORNrr : F3_1<2, 0b000110,
+ def ORNri : F3_2<2, 0b000110,
+ (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
+ "orn $b, $c, $dst", []>;
+-defm XOR : F3_12<"xor", 0b000011, xor>;
++defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>;
+
+ def XNORrr : F3_1<2, 0b000111,
+ (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
+@@ -494,12 +495,12 @@ def XNORri : F3_2<2, 0b000111,
+ "xnor $b, $c, $dst", []>;
+
+ // Section B.12 - Shift Instructions, p. 107
+-defm SLL : F3_12<"sll", 0b100101, shl>;
+-defm SRL : F3_12<"srl", 0b100110, srl>;
+-defm SRA : F3_12<"sra", 0b100111, sra>;
++defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>;
++defm SRL : F3_12<"srl", 0b100110, srl, IntRegs, i32, i32imm>;
++defm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i32, i32imm>;
+
+ // Section B.13 - Add Instructions, p. 108
+-defm ADD : F3_12<"add", 0b000000, add>;
++defm ADD : F3_12<"add", 0b000000, add, IntRegs, i32, i32imm>;
+
+ // "LEA" forms of add (patterns to make tblgen happy)
+ let Predicates = [Is32Bit] in
+@@ -509,18 +510,18 @@ let Predicates = [Is32Bit] in
+ [(set iPTR:$dst, ADDRri:$addr)]>;
+
+ let Defs = [ICC] in
+- defm ADDCC : F3_12<"addcc", 0b010000, addc>;
++ defm ADDCC : F3_12<"addcc", 0b010000, addc, IntRegs, i32, i32imm>;
+
+ let Uses = [ICC], Defs = [ICC] in
+- defm ADDX : F3_12<"addxcc", 0b011000, adde>;
++ defm ADDE : F3_12<"addxcc", 0b011000, adde, IntRegs, i32, i32imm>;
+
+ // Section B.15 - Subtract Instructions, p. 110
+-defm SUB : F3_12 <"sub" , 0b000100, sub>;
++defm SUB : F3_12 <"sub" , 0b000100, sub, IntRegs, i32, i32imm>;
+ let Uses = [ICC], Defs = [ICC] in
+- defm SUBX : F3_12 <"subxcc" , 0b011100, sube>;
++ defm SUBE : F3_12 <"subxcc" , 0b011100, sube, IntRegs, i32, i32imm>;
+
+ let Defs = [ICC] in
+- defm SUBCC : F3_12 <"subcc", 0b010100, subc>;
++ defm SUBCC : F3_12 <"subcc", 0b010100, subc, IntRegs, i32, i32imm>;
+
+ let Defs = [ICC], rd = 0 in {
+ def CMPrr : F3_1<2, 0b010100,
+@@ -542,7 +543,7 @@ let Uses = [ICC], Defs = [ICC] in
+ // Section B.18 - Multiply Instructions, p. 113
+ let Defs = [Y] in {
+ defm UMUL : F3_12np<"umul", 0b001010>;
+- defm SMUL : F3_12 <"smul", 0b001011, mul>;
++ defm SMUL : F3_12 <"smul", 0b001011, mul, IntRegs, i32, i32imm>;
+ }
+
+ // Section B.19 - Divide Instructions, p. 115
+@@ -987,6 +988,8 @@ def : Pat<(i32 imm:$val),
+
+
+ // Global addresses, constant pool entries
++let Predicates = [Is32Bit] in {
++
+ def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
+ def : Pat<(SPlo tglobaladdr:$in), (ORri (i32 G0), tglobaladdr:$in)>;
+ def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>;
+@@ -1009,6 +1012,7 @@ def : Pat<(add iPTR:$r, (SPlo tglobaladdr:$in)), (
+ def : Pat<(add iPTR:$r, (SPlo tconstpool:$in)), (ADDri $r, tconstpool:$in)>;
+ def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)),
+ (ADDri $r, tblockaddress:$in)>;
++}
+
+ // Calls:
+ def : Pat<(call tglobaladdr:$dst),
+Index: test/CodeGen/SPARC/64spill.ll
+===================================================================
+--- test/CodeGen/SPARC/64spill.ll
++++ test/CodeGen/SPARC/64spill.ll
+@@ -0,0 +1,116 @@
++; RUN: llc < %s -march=sparcv9 | FileCheck %s
++
++target datalayout = "E-i64:64-n32:64-S128"
++target triple = "sparc64-sun-sparc"
++
++; CHECK-LABEL: test_and_spill
++; CHECK: and %i0, %i1, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_and_spill(i64 %a, i64 %b) {
++entry:
++ %r0 = and i64 %a, %b
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++; CHECK-LABEL: test_or_spill
++; CHECK: or %i0, %i1, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_or_spill(i64 %a, i64 %b) {
++entry:
++ %r0 = or i64 %a, %b
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++; CHECK-LABEL: test_xor_spill
++; CHECK: xor %i0, %i1, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_xor_spill(i64 %a, i64 %b) {
++entry:
++ %r0 = xor i64 %a, %b
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++
++; CHECK-LABEL: test_add_spill
++; CHECK: add %i0, %i1, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_add_spill(i64 %a, i64 %b) {
++entry:
++ %r0 = add i64 %a, %b
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++; CHECK-LABEL: test_sub_spill
++; CHECK: sub %i0, %i1, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_sub_spill(i64 %a, i64 %b) {
++entry:
++ %r0 = sub i64 %a, %b
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++; CHECK-LABEL: test_andi_spill
++; CHECK: and %i0, 1729, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_andi_spill(i64 %a) {
++entry:
++ %r0 = and i64 %a, 1729
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++; CHECK-LABEL: test_ori_spill
++; CHECK: or %i0, 1729, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_ori_spill(i64 %a) {
++entry:
++ %r0 = or i64 %a, 1729
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++; CHECK-LABEL: test_xori_spill
++; CHECK: xor %i0, 1729, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_xori_spill(i64 %a) {
++entry:
++ %r0 = xor i64 %a, 1729
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++; CHECK-LABEL: test_addi_spill
++; CHECK: add %i0, 1729, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_addi_spill(i64 %a) {
++entry:
++ %r0 = add i64 %a, 1729
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
++; CHECK-LABEL: test_subi_spill
++; CHECK: add %i0, -1729, [[R:%[gilo][0-7]]]
++; CHECK: stx [[R]], [%fp+{{.+}}]
++; CHECK: ldx [%fp+{{.+}}, %i0
++define i64 @test_subi_spill(i64 %a) {
++entry:
++ %r0 = sub i64 %a, 1729
++ %0 = tail call i64 asm sideeffect "#$0 $1", "=r,r,~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6}"(i64 %r0)
++ ret i64 %r0
++}
++
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198280-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198280-sparc.diff
new file mode 100644
index 0000000..f75d9fc
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198280-sparc.diff
@@ -0,0 +1,55 @@
+Pull in r198280 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9]: Use SRL instead of SLL to clear top 32-bits in ctpop:i32. SLL does not clear top 32 bit, only SRL does.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -967,13 +967,13 @@ let Predicates = [HasV9] in {
+ }
+
+ // POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear
+-// the top 32-bits before using it. To do this clearing, we use a SLLri X,0.
++// the top 32-bits before using it. To do this clearing, we use a SRLri X,0.
+ let rs1 = 0 in
+ def POPCrr : F3_1<2, 0b101110,
+ (outs IntRegs:$dst), (ins IntRegs:$src),
+ "popc $src, $dst", []>, Requires<[HasV9]>;
+ def : Pat<(ctpop i32:$src),
+- (POPCrr (SLLri $src, 0))>;
++ (POPCrr (SRLri $src, 0))>;
+
+ //===----------------------------------------------------------------------===//
+ // Non-Instruction Patterns
+Index: test/CodeGen/SPARC/ctpop.ll
+===================================================================
+--- test/CodeGen/SPARC/ctpop.ll
++++ test/CodeGen/SPARC/ctpop.ll
+@@ -1,8 +1,22 @@
+-; RUN: llc < %s -march=sparc -mattr=-v9 | not grep popc
+-; RUN: llc < %s -march=sparc -mattr=+v9 | grep popc
++; RUN: llc < %s -march=sparc -mattr=-v9 | FileCheck %s -check-prefix=V8
++; RUN: llc < %s -march=sparc -mattr=+v9 | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparcv9 | FileCheck %s -check-prefix=SPARC64
+
+ declare i32 @llvm.ctpop.i32(i32)
+
++; V8-LABEL: test
++; V8-NOT : popc
++
++; V9-LABEL: test
++; V9: srl %o0, 0, %o0
++; V9-NEXT: jmp %o7+8
++; V9-NEXT: popc %o0, %o0
++
++; SPARC64-LABEL: test
++; SPARC64: srl %o0, 0, %o0
++; SPARC64: jmp %o7+8
++; SPARC64: popc %o0, %o0
++
+ define i32 @test(i32 %X) {
+ %Y = call i32 @llvm.ctpop.i32( i32 %X ) ; <i32> [#uses=1]
+ ret i32 %Y
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff
new file mode 100644
index 0000000..0af21f4
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff
@@ -0,0 +1,99 @@
+Pull in r198281 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9]: Custom lower UMULO/SMULO so that the arguments are send to __multi3() in correct order.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1525,6 +1525,9 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
+ setOperationAction(ISD::MULHU, MVT::i64, Expand);
+ setOperationAction(ISD::MULHS, MVT::i64, Expand);
++
++ setOperationAction(ISD::UMULO, MVT::i64, Custom);
++ setOperationAction(ISD::SMULO, MVT::i64, Custom);
+ }
+
+ // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
+@@ -2673,6 +2676,53 @@ static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op
+ return DAG.getMergeValues(Ops, 2, dl);
+ }
+
++// Custom lower UMULO/SMULO for SPARC. This code is similar to ExpandNode()
++// in LegalizeDAG.cpp except the order of arguments to the library function.
++static SDValue LowerUMULO_SMULO(SDValue Op, SelectionDAG &DAG,
++ const SparcTargetLowering &TLI)
++{
++ unsigned opcode = Op.getOpcode();
++ assert((opcode == ISD::UMULO || opcode == ISD::SMULO) && "Invalid Opcode.");
++
++ bool isSigned = (opcode == ISD::SMULO);
++ EVT VT = MVT::i64;
++ EVT WideVT = MVT::i128;
++ SDLoc dl(Op);
++ SDValue LHS = Op.getOperand(0);
++
++ if (LHS.getValueType() != VT)
++ return Op;
++
++ SDValue ShiftAmt = DAG.getConstant(63, VT);
++
++ SDValue RHS = Op.getOperand(1);
++ SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, LHS, ShiftAmt);
++ SDValue HiRHS = DAG.getNode(ISD::SRA, dl, MVT::i64, RHS, ShiftAmt);
++ SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
++
++ SDValue MulResult = TLI.makeLibCall(DAG,
++ RTLIB::MUL_I128, WideVT,
++ Args, 4, isSigned, dl).first;
++ SDValue BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT,
++ MulResult, DAG.getIntPtrConstant(0));
++ SDValue TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT,
++ MulResult, DAG.getIntPtrConstant(1));
++ if (isSigned) {
++ SDValue Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, ShiftAmt);
++ TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, Tmp1, ISD::SETNE);
++ } else {
++ TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, DAG.getConstant(0, VT),
++ ISD::SETNE);
++ }
++ // MulResult is a node with an illegal type. Because such things are not
++ // generally permitted during this phase of legalization, delete the
++ // node. The above EXTRACT_ELEMENT nodes should have been folded.
++ DAG.DeleteNode(MulResult.getNode());
++
++ SDValue Ops[2] = { BottomHalf, TopHalf } ;
++ return DAG.getMergeValues(Ops, 2, dl);
++}
++
+ SDValue SparcTargetLowering::
+ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
+
+@@ -2726,6 +2776,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
+ case ISD::ADDE:
+ case ISD::SUBC:
+ case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
++ case ISD::UMULO:
++ case ISD::SMULO: return LowerUMULO_SMULO(Op, DAG, *this);
+ }
+ }
+
+Index: test/CodeGen/SPARC/64cond.ll
+===================================================================
+--- test/CodeGen/SPARC/64cond.ll
++++ test/CodeGen/SPARC/64cond.ll
+@@ -111,6 +111,11 @@ entry:
+ }
+
+ ; CHECK-LABEL: setcc_resultty
++; CHECK-DAG: srax %i0, 63, %o0
++; CHECK-DAG: or %g0, %i0, %o1
++; CHECK-DAG: or %g0, 0, %o2
++; CHECK-DAG: or %g0, 32, %o3
++; CHECK-DAG: call __multi3
+ ; CHECK: cmp
+ ; CHECK: movne %xcc, 1, [[R:%[gilo][0-7]]]
+ ; CHECK: or [[R]], %i1, %i0
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198286-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198286-sparc.diff
new file mode 100644
index 0000000..041e263
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198286-sparc.diff
@@ -0,0 +1,231 @@
+Pull in r198286 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Handle atomic loads/stores in sparc backend.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -975,6 +975,33 @@ let rs1 = 0 in
+ def : Pat<(ctpop i32:$src),
+ (POPCrr (SRLri $src, 0))>;
+
++// Atomic swap.
++let hasSideEffects =1, rd = 0, rs1 = 0b01111, rs2 = 0 in
++ def STBAR : F3_1<2, 0b101000, (outs), (ins), "stbar", []>;
++
++let Predicates = [HasV9], hasSideEffects = 1, rd = 0, rs1 = 0b01111 in
++ def MEMBARi : F3_2<2, 0b101000, (outs), (ins i32imm:$simm13),
++ "membar $simm13", []>;
++
++let Constraints = "$val = $rd" in {
++ def SWAPrr : F3_1<3, 0b001111,
++ (outs IntRegs:$rd), (ins IntRegs:$val, MEMrr:$addr),
++ "swap [$addr], $rd",
++ [(set i32:$rd, (atomic_swap_32 ADDRrr:$addr, i32:$val))]>;
++ def SWAPri : F3_2<3, 0b001111,
++ (outs IntRegs:$rd), (ins IntRegs:$val, MEMri:$addr),
++ "swap [$addr], $rd",
++ [(set i32:$rd, (atomic_swap_32 ADDRri:$addr, i32:$val))]>;
++}
++
++let Predicates = [HasV9], Constraints = "$swap = $rd" in
++ def CASrr: F3_1<3, 0b111100,
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
++ IntRegs:$swap),
++ "cas [$rs1], $rs2, $rd",
++ [(set i32:$rd,
++ (atomic_cmp_swap iPTR:$rs1, i32:$rs2, i32:$swap))]>;
++
+ //===----------------------------------------------------------------------===//
+ // Non-Instruction Patterns
+ //===----------------------------------------------------------------------===//
+@@ -1036,4 +1063,17 @@ def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri
+ def : Pat<(store (i32 0), ADDRrr:$dst), (STrr ADDRrr:$dst, (i32 G0))>;
+ def : Pat<(store (i32 0), ADDRri:$dst), (STri ADDRri:$dst, (i32 G0))>;
+
++// store bar for all atomic_fence in V8.
++let Predicates = [HasNoV9] in
++ def : Pat<(atomic_fence imm, imm), (STBAR)>;
++
++// atomic_load_32 addr -> load addr
++def : Pat<(i32 (atomic_load ADDRrr:$src)), (LDrr ADDRrr:$src)>;
++def : Pat<(i32 (atomic_load ADDRri:$src)), (LDri ADDRri:$src)>;
++
++// atomic_store_32 val, addr -> store val, addr
++def : Pat<(atomic_store ADDRrr:$dst, i32:$val), (STrr ADDRrr:$dst, $val)>;
++def : Pat<(atomic_store ADDRri:$dst, i32:$val), (STri ADDRri:$dst, $val)>;
++
++
+ include "SparcInstr64Bit.td"
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1472,10 +1472,30 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
+ }
+
+- // FIXME: There are instructions available for ATOMIC_FENCE
+- // on SparcV8 and later.
+- setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
++ // ATOMICs.
++ // FIXME: We insert fences for each atomics and generate sub-optimal code
++ // for PSO/TSO. Also, implement other atomicrmw operations.
+
++ setInsertFencesForAtomic(true);
++
++ setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Legal);
++ setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32,
++ (Subtarget->isV9() ? Legal: Expand));
++
++
++ setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Legal);
++
++ // Custom Lower Atomic LOAD/STORE
++ setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Custom);
++ setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Custom);
++
++ if (Subtarget->is64Bit()) {
++ setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, Legal);
++ setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Expand);
++ setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Custom);
++ setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Custom);
++ }
++
+ if (!Subtarget->isV9()) {
+ // SparcV8 does not have FNEGD and FABSD.
+ setOperationAction(ISD::FNEG, MVT::f64, Custom);
+@@ -2723,6 +2743,16 @@ static SDValue LowerUMULO_SMULO(SDValue Op, Select
+ return DAG.getMergeValues(Ops, 2, dl);
+ }
+
++static SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) {
++ // Monotonic load/stores are legal.
++ if (cast<AtomicSDNode>(Op)->getOrdering() <= Monotonic)
++ return Op;
++
++ // Otherwise, expand with a fence.
++ return SDValue();
++}
++
++
+ SDValue SparcTargetLowering::
+ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
+
+@@ -2778,6 +2808,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
+ case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
+ case ISD::UMULO:
+ case ISD::SMULO: return LowerUMULO_SMULO(Op, DAG, *this);
++ case ISD::ATOMIC_LOAD:
++ case ISD::ATOMIC_STORE: return LowerATOMIC_LOAD_STORE(Op, DAG);
+ }
+ }
+
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -415,6 +415,32 @@ def SETHIXi : F2_1<0b100,
+ "sethi $imm22, $rd",
+ [(set i64:$rd, SETHIimm:$imm22)]>;
+ }
++
++// ATOMICS.
++let Predicates = [Is64Bit], Constraints = "$swap = $rd" in {
++ def CASXrr: F3_1<3, 0b111110,
++ (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
++ I64Regs:$swap),
++ "casx [$rs1], $rs2, $rd",
++ [(set i64:$rd,
++ (atomic_cmp_swap i64:$rs1, i64:$rs2, i64:$swap))]>;
++
++} // Predicates = [Is64Bit], Constraints = ...
++
++let Predicates = [Is64Bit] in {
++
++def : Pat<(atomic_fence imm, imm), (MEMBARi 0xf)>;
++
++// atomic_load_64 addr -> load addr
++def : Pat<(i64 (atomic_load ADDRrr:$src)), (LDXrr ADDRrr:$src)>;
++def : Pat<(i64 (atomic_load ADDRri:$src)), (LDXri ADDRri:$src)>;
++
++// atomic_store_64 val, addr -> store val, addr
++def : Pat<(atomic_store ADDRrr:$dst, i64:$val), (STXrr ADDRrr:$dst, $val)>;
++def : Pat<(atomic_store ADDRri:$dst, i64:$val), (STXri ADDRri:$dst, $val)>;
++
++} // Predicates = [Is64Bit]
++
+ // Global addresses, constant pool entries
+ let Predicates = [Is64Bit] in {
+
+Index: test/CodeGen/SPARC/atomics.ll
+===================================================================
+--- test/CodeGen/SPARC/atomics.ll
++++ test/CodeGen/SPARC/atomics.ll
+@@ -0,0 +1,63 @@
++; RUN: llc < %s -march=sparcv9 | FileCheck %s
++
++; CHECK-LABEL: test_atomic_i32
++; CHECK: ld [%o0]
++; CHECK: membar
++; CHECK: ld [%o1]
++; CHECK: membar
++; CHECK: membar
++; CHECK: st {{.+}}, [%o2]
++define i32 @test_atomic_i32(i32* %ptr1, i32* %ptr2, i32* %ptr3) {
++entry:
++ %0 = load atomic i32* %ptr1 acquire, align 8
++ %1 = load atomic i32* %ptr2 acquire, align 8
++ %2 = add i32 %0, %1
++ store atomic i32 %2, i32* %ptr3 release, align 8
++ ret i32 %2
++}
++
++; CHECK-LABEL: test_atomic_i64
++; CHECK: ldx [%o0]
++; CHECK: membar
++; CHECK: ldx [%o1]
++; CHECK: membar
++; CHECK: membar
++; CHECK: stx {{.+}}, [%o2]
++define i64 @test_atomic_i64(i64* %ptr1, i64* %ptr2, i64* %ptr3) {
++entry:
++ %0 = load atomic i64* %ptr1 acquire, align 8
++ %1 = load atomic i64* %ptr2 acquire, align 8
++ %2 = add i64 %0, %1
++ store atomic i64 %2, i64* %ptr3 release, align 8
++ ret i64 %2
++}
++
++; CHECK-LABEL: test_cmpxchg_i32
++; CHECK: or %g0, 123, [[R:%[gilo][0-7]]]
++; CHECK: cas [%o1], %o0, [[R]]
++
++define i32 @test_cmpxchg_i32(i32 %a, i32* %ptr) {
++entry:
++ %b = cmpxchg i32* %ptr, i32 %a, i32 123 monotonic
++ ret i32 %b
++}
++
++; CHECK-LABEL: test_cmpxchg_i64
++; CHECK: or %g0, 123, [[R:%[gilo][0-7]]]
++; CHECK: casx [%o1], %o0, [[R]]
++
++define i64 @test_cmpxchg_i64(i64 %a, i64* %ptr) {
++entry:
++ %b = cmpxchg i64* %ptr, i64 %a, i64 123 monotonic
++ ret i64 %b
++}
++
++; CHECK-LABEL: test_swap_i32
++; CHECK: or %g0, 42, [[R:%[gilo][0-7]]]
++; CHECK: swap [%o1], [[R]]
++
++define i32 @test_swap_i32(i32 %a, i32* %ptr) {
++entry:
++ %b = atomicrmw xchg i32* %ptr, i32 42 monotonic
++ ret i32 %b
++}
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff
new file mode 100644
index 0000000..b3e1362
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff
@@ -0,0 +1,213 @@
+Pull in r198480 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -2415,7 +2415,8 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG
+ return Chain;
+ }
+
+-static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
++static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG,
++ const SparcSubtarget *Subtarget) {
+ MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+ MFI->setFrameAddressIsTaken(true);
+
+@@ -2422,32 +2423,49 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG
+ EVT VT = Op.getValueType();
+ SDLoc dl(Op);
+ unsigned FrameReg = SP::I6;
++ unsigned stackBias = Subtarget->getStackPointerBias();
+
+- uint64_t depth = Op.getConstantOperandVal(0);
++ SDValue FrameAddr;
+
+- SDValue FrameAddr;
+- if (depth == 0)
++ if (depth == 0) {
+ FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
+- else {
+- // flush first to make sure the windowed registers' values are in stack
+- SDValue Chain = getFLUSHW(Op, DAG);
+- FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
++ if (Subtarget->is64Bit())
++ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
++ DAG.getIntPtrConstant(stackBias));
++ return FrameAddr;
++ }
+
+- for (uint64_t i = 0; i != depth; ++i) {
+- SDValue Ptr = DAG.getNode(ISD::ADD,
+- dl, MVT::i32,
+- FrameAddr, DAG.getIntPtrConstant(56));
+- FrameAddr = DAG.getLoad(MVT::i32, dl,
+- Chain,
+- Ptr,
+- MachinePointerInfo(), false, false, false, 0);
+- }
++ // flush first to make sure the windowed registers' values are in stack
++ SDValue Chain = getFLUSHW(Op, DAG);
++ FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
++
++ unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56;
++
++ while (depth--) {
++ SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
++ DAG.getIntPtrConstant(Offset));
++ FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo(),
++ false, false, false, 0);
+ }
++ if (Subtarget->is64Bit())
++ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
++ DAG.getIntPtrConstant(stackBias));
+ return FrameAddr;
+ }
+
++
++static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG,
++ const SparcSubtarget *Subtarget) {
++
++ uint64_t depth = Op.getConstantOperandVal(0);
++
++ return getFRAMEADDR(depth, Op, DAG, Subtarget);
++
++}
++
+ static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG,
+- const SparcTargetLowering &TLI) {
++ const SparcTargetLowering &TLI,
++ const SparcSubtarget *Subtarget) {
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ MFI->setReturnAddressIsTaken(true);
+@@ -2461,25 +2479,20 @@ static SDValue LowerRETURNADDR(SDValue Op, Selecti
+ unsigned RetReg = MF.addLiveIn(SP::I7,
+ TLI.getRegClassFor(TLI.getPointerTy()));
+ RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
+- } else {
+- // Need frame address to find return address of the caller.
+- MFI->setFrameAddressIsTaken(true);
++ return RetAddr;
++ }
+
+- // flush first to make sure the windowed registers' values are in stack
+- SDValue Chain = getFLUSHW(Op, DAG);
+- RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT);
++ // Need frame address to find return address of the caller.
++ SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget);
+
+- for (uint64_t i = 0; i != depth; ++i) {
+- SDValue Ptr = DAG.getNode(ISD::ADD,
+- dl, MVT::i32,
+- RetAddr,
+- DAG.getIntPtrConstant((i == depth-1)?60:56));
+- RetAddr = DAG.getLoad(MVT::i32, dl,
+- Chain,
+- Ptr,
+- MachinePointerInfo(), false, false, false, 0);
+- }
+- }
++ unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60;
++ SDValue Ptr = DAG.getNode(ISD::ADD,
++ dl, VT,
++ FrameAddr,
++ DAG.getIntPtrConstant(Offset));
++ RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr,
++ MachinePointerInfo(), false, false, false, 0);
++
+ return RetAddr;
+ }
+
+@@ -2763,8 +2776,10 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
+ switch (Op.getOpcode()) {
+ default: llvm_unreachable("Should not custom lower this!");
+
+- case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this);
+- case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
++ case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this,
++ Subtarget);
++ case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG,
++ Subtarget);
+ case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
+ case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
+ case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
+Index: test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
+===================================================================
+--- test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
++++ test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
+@@ -2,6 +2,7 @@
+ ;RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9
+ ;RUN: llc -march=sparc -regalloc=basic < %s | FileCheck %s -check-prefix=V8
+ ;RUN: llc -march=sparc -regalloc=basic -mattr=v9 < %s | FileCheck %s -check-prefix=V9
++;RUN: llc -march=sparcv9 < %s | FileCheck %s -check-prefix=SPARC64
+
+
+ define i8* @frameaddr() nounwind readnone {
+@@ -15,6 +16,13 @@ entry:
+ ;V9: save %sp, -96, %sp
+ ;V9: jmp %i7+8
+ ;V9: restore %g0, %fp, %o0
++
++;SPARC64-LABEL: frameaddr
++;SPARC64: save %sp, -128, %sp
++;SPARC64: add %fp, 2047, %i0
++;SPARC64: jmp %i7+8
++;SPARC64: restore %g0, %g0, %g0
++
+ %0 = tail call i8* @llvm.frameaddress(i32 0)
+ ret i8* %0
+ }
+@@ -32,6 +40,14 @@ entry:
+ ;V9: ld [%fp+56], {{.+}}
+ ;V9: ld [{{.+}}+56], {{.+}}
+ ;V9: ld [{{.+}}+56], {{.+}}
++
++;SPARC64-LABEL: frameaddr2
++;SPARC64: flushw
++;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]]
++;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]]
++;SPARC64: ldx [%[[R1]]+2159], %[[R2:[goli][0-7]]]
++;SPARC64: add %[[R2]], 2047, {{.+}}
++
+ %0 = tail call i8* @llvm.frameaddress(i32 3)
+ ret i8* %0
+ }
+@@ -48,6 +64,9 @@ entry:
+ ;V9-LABEL: retaddr:
+ ;V9: or %g0, %o7, {{.+}}
+
++;SPARC64-LABEL: retaddr
++;SPARC64: or %g0, %o7, {{.+}}
++
+ %0 = tail call i8* @llvm.returnaddress(i32 0)
+ ret i8* %0
+ }
+@@ -66,18 +85,12 @@ entry:
+ ;V9: ld [{{.+}}+56], {{.+}}
+ ;V9: ld [{{.+}}+60], {{.+}}
+
+-;V8LEAF-LABEL: retaddr2:
+-;V8LEAF: ta 3
+-;V8LEAF: ld [%fp+56], %[[R:[goli][0-7]]]
+-;V8LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]]
+-;V8LEAF: ld [%[[R1]]+60], {{.+}}
++;SPARC64-LABEL: retaddr2
++;SPARC64: flushw
++;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]]
++;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]]
++;SPARC64: ldx [%[[R1]]+2167], {{.+}}
+
+-;V9LEAF-LABEL: retaddr2:
+-;V9LEAF: flushw
+-;V9LEAF: ld [%fp+56], %[[R:[goli][0-7]]]
+-;V9LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]]
+-;V9LEAF: ld [%[[R1]]+60], {{.+}}
+-
+ %0 = tail call i8* @llvm.returnaddress(i32 3)
+ ret i8* %0
+ }
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198484-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198484-sparc.diff
new file mode 100644
index 0000000..3bfb7d5
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198484-sparc.diff
@@ -0,0 +1,844 @@
+Pull in r198484 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add the initial implementation of an asm parser for sparc/sparcv9.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+@@ -123,13 +123,18 @@ extern "C" void LLVMInitializeSparcTargetMC() {
+
+ // Register the MC instruction info.
+ TargetRegistry::RegisterMCInstrInfo(TheSparcTarget, createSparcMCInstrInfo);
++ TargetRegistry::RegisterMCInstrInfo(TheSparcV9Target, createSparcMCInstrInfo);
+
+ // Register the MC register info.
+ TargetRegistry::RegisterMCRegInfo(TheSparcTarget, createSparcMCRegisterInfo);
++ TargetRegistry::RegisterMCRegInfo(TheSparcV9Target,
++ createSparcMCRegisterInfo);
+
+ // Register the MC subtarget info.
+ TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget,
+ createSparcMCSubtargetInfo);
++ TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target,
++ createSparcMCSubtargetInfo);
+
+ TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
+ createMCAsmStreamer);
+Index: lib/Target/Sparc/LLVMBuild.txt
+===================================================================
+--- lib/Target/Sparc/LLVMBuild.txt
++++ lib/Target/Sparc/LLVMBuild.txt
+@@ -16,7 +16,7 @@
+ ;===------------------------------------------------------------------------===;
+
+ [common]
+-subdirectories = InstPrinter MCTargetDesc TargetInfo
++subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
+
+ [component_0]
+ type = TargetGroup
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -76,13 +76,25 @@ def ADDRrr : ComplexPattern<iPTR, 2, "SelectADDRrr
+ def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri", [frameindex], []>;
+
+ // Address operands
++def SparcMEMrrAsmOperand : AsmOperandClass {
++ let Name = "MEMrr";
++ let ParserMethod = "parseMEMrrOperand";
++}
++
++def SparcMEMriAsmOperand : AsmOperandClass {
++ let Name = "MEMri";
++ let ParserMethod = "parseMEMriOperand";
++}
++
+ def MEMrr : Operand<iPTR> {
+ let PrintMethod = "printMemOperand";
+ let MIOperandInfo = (ops ptr_rc, ptr_rc);
++ let ParserMatchClass = SparcMEMrrAsmOperand;
+ }
+ def MEMri : Operand<iPTR> {
+ let PrintMethod = "printMemOperand";
+ let MIOperandInfo = (ops ptr_rc, i32imm);
++ let ParserMatchClass = SparcMEMriAsmOperand;
+ }
+
+ def TLSSym : Operand<iPTR>;
+@@ -239,7 +251,10 @@ multiclass F3_12np<string OpcStr, bits<6> Op3Val>
+
+ // Pseudo instructions.
+ class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
+- : InstSP<outs, ins, asmstr, pattern>;
++ : InstSP<outs, ins, asmstr, pattern> {
++ let isCodeGenOnly = 1;
++ let isPseudo = 1;
++}
+
+ // GETPCX for PIC
+ let Defs = [O7] in {
+@@ -503,7 +518,7 @@ defm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i3
+ defm ADD : F3_12<"add", 0b000000, add, IntRegs, i32, i32imm>;
+
+ // "LEA" forms of add (patterns to make tblgen happy)
+-let Predicates = [Is32Bit] in
++let Predicates = [Is32Bit], isCodeGenOnly = 1 in
+ def LEA_ADDri : F3_2<2, 0b000000,
+ (outs IntRegs:$dst), (ins MEMri:$addr),
+ "add ${addr:arith}, $dst",
+Index: lib/Target/Sparc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/CMakeLists.txt
++++ lib/Target/Sparc/CMakeLists.txt
+@@ -4,6 +4,7 @@ tablegen(LLVM SparcGenRegisterInfo.inc -gen-regist
+ tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
+ tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
+ tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
++tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
+ tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel)
+ tablegen(LLVM SparcGenSubtargetInfo.inc -gen-subtarget)
+ tablegen(LLVM SparcGenCallingConv.inc -gen-callingconv)
+@@ -31,3 +32,4 @@ add_dependencies(LLVMSparcCodeGen SparcCommonTable
+ add_subdirectory(TargetInfo)
+ add_subdirectory(MCTargetDesc)
+ add_subdirectory(InstPrinter)
++add_subdirectory(AsmParser)
+Index: lib/Target/Sparc/Makefile
+===================================================================
+--- lib/Target/Sparc/Makefile
++++ lib/Target/Sparc/Makefile
+@@ -13,11 +13,12 @@ TARGET = Sparc
+
+ # Make sure that tblgen is run, first thing.
+ BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
+- SparcGenAsmWriter.inc SparcGenDAGISel.inc \
++ SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
++ SparcGenDAGISel.inc \
+ SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
+ SparcGenCodeEmitter.inc
+
+-DIRS = InstPrinter TargetInfo MCTargetDesc
++DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
+
+ include $(LEVEL)/Makefile.common
+
+Index: lib/Target/Sparc/Sparc.td
+===================================================================
+--- lib/Target/Sparc/Sparc.td
++++ lib/Target/Sparc/Sparc.td
+@@ -44,6 +44,10 @@ include "SparcInstrInfo.td"
+
+ def SparcInstrInfo : InstrInfo;
+
++def SparcAsmParser : AsmParser {
++ bit ShouldEmitMatchRegisterName = 0;
++}
++
+ //===----------------------------------------------------------------------===//
+ // SPARC processors supported.
+ //===----------------------------------------------------------------------===//
+@@ -77,6 +81,7 @@ def SparcAsmWriter : AsmWriter {
+ def Sparc : Target {
+ // Pull in Instruction Info:
+ let InstructionSet = SparcInstrInfo;
++ let AssemblyParsers = [SparcAsmParser];
+
+ let AssemblyWriters = [SparcAsmWriter];
+ }
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -0,0 +1,614 @@
++//===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++
++#include "MCTargetDesc/SparcMCTargetDesc.h"
++#include "llvm/ADT/STLExtras.h"
++#include "llvm/MC/MCContext.h"
++#include "llvm/MC/MCInst.h"
++#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
++#include "llvm/MC/MCStreamer.h"
++#include "llvm/MC/MCSubtargetInfo.h"
++#include "llvm/MC/MCTargetAsmParser.h"
++#include "llvm/Support/TargetRegistry.h"
++
++using namespace llvm;
++
++// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
++// namespace. But SPARC backend uses "SP" as its namespace.
++namespace llvm {
++ namespace Sparc {
++ using namespace SP;
++ }
++}
++
++namespace {
++class SparcAsmParser : public MCTargetAsmParser {
++
++ MCSubtargetInfo &STI;
++ MCAsmParser &Parser;
++
++ /// @name Auto-generated Match Functions
++ /// {
++
++#define GET_ASSEMBLER_HEADER
++#include "SparcGenAsmMatcher.inc"
++
++ /// }
++
++ // public interface of the MCTargetAsmParser.
++ bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
++ SmallVectorImpl<MCParsedAsmOperand*> &Operands,
++ MCStreamer &Out, unsigned &ErrorInfo,
++ bool MatchingInlineAsm);
++ bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
++ bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
++ SMLoc NameLoc,
++ SmallVectorImpl<MCParsedAsmOperand*> &Operands);
++ bool ParseDirective(AsmToken DirectiveID);
++
++
++ // Custom parse functions for Sparc specific operands.
++ OperandMatchResultTy
++ parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
++ OperandMatchResultTy
++ parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
++
++ OperandMatchResultTy
++ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
++ int ImmOffsetOrReg);
++
++ OperandMatchResultTy
++ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
++ StringRef Name);
++
++ // returns true if Tok is matched to a register and returns register in RegNo.
++ bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
++ bool isQFP);
++
++public:
++ SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
++ const MCInstrInfo &MII)
++ : MCTargetAsmParser(), STI(sti), Parser(parser) {
++ // Initialize the set of available features.
++ setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
++ }
++
++};
++
++ static unsigned IntRegs[32] = {
++ Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
++ Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
++ Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
++ Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
++ Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
++ Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
++ Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
++ Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
++
++ static unsigned FloatRegs[32] = {
++ Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
++ Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
++ Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
++ Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
++ Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
++ Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
++ Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
++ Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
++
++ static unsigned DoubleRegs[32] = {
++ Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
++ Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
++ Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
++ Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
++ Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
++ Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
++ Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
++ Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
++
++ static unsigned QuadFPRegs[32] = {
++ Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
++ Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
++ Sparc::Q8, Sparc::Q7, Sparc::Q8, Sparc::Q9,
++ Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
++
++
++/// SparcOperand - Instances of this class represent a parsed Sparc machine
++/// instruction.
++class SparcOperand : public MCParsedAsmOperand {
++public:
++ enum RegisterKind {
++ rk_None,
++ rk_IntReg,
++ rk_FloatReg,
++ rk_DoubleReg,
++ rk_QuadReg,
++ rk_CCReg,
++ rk_Y
++ };
++private:
++ enum KindTy {
++ k_Token,
++ k_Register,
++ k_Immediate,
++ k_MemoryReg,
++ k_MemoryImm
++ } Kind;
++
++ SMLoc StartLoc, EndLoc;
++
++ SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
++
++ struct Token {
++ const char *Data;
++ unsigned Length;
++ };
++
++ struct RegOp {
++ unsigned RegNum;
++ RegisterKind Kind;
++ };
++
++ struct ImmOp {
++ const MCExpr *Val;
++ };
++
++ struct MemOp {
++ unsigned Base;
++ unsigned OffsetReg;
++ const MCExpr *Off;
++ };
++
++ union {
++ struct Token Tok;
++ struct RegOp Reg;
++ struct ImmOp Imm;
++ struct MemOp Mem;
++ };
++public:
++ bool isToken() const { return Kind == k_Token; }
++ bool isReg() const { return Kind == k_Register; }
++ bool isImm() const { return Kind == k_Immediate; }
++ bool isMem() const { return isMEMrr() || isMEMri(); }
++ bool isMEMrr() const { return Kind == k_MemoryReg; }
++ bool isMEMri() const { return Kind == k_MemoryImm; }
++
++ StringRef getToken() const {
++ assert(Kind == k_Token && "Invalid access!");
++ return StringRef(Tok.Data, Tok.Length);
++ }
++
++ unsigned getReg() const {
++ assert((Kind == k_Register) && "Invalid access!");
++ return Reg.RegNum;
++ }
++
++ const MCExpr *getImm() const {
++ assert((Kind == k_Immediate) && "Invalid access!");
++ return Imm.Val;
++ }
++
++ unsigned getMemBase() const {
++ assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
++ return Mem.Base;
++ }
++
++ unsigned getMemOffsetReg() const {
++ assert((Kind == k_MemoryReg) && "Invalid access!");
++ return Mem.OffsetReg;
++ }
++
++ const MCExpr *getMemOff() const {
++ assert((Kind == k_MemoryImm) && "Invalid access!");
++ return Mem.Off;
++ }
++
++ /// getStartLoc - Get the location of the first token of this operand.
++ SMLoc getStartLoc() const {
++ return StartLoc;
++ }
++ /// getEndLoc - Get the location of the last token of this operand.
++ SMLoc getEndLoc() const {
++ return EndLoc;
++ }
++
++ virtual void print(raw_ostream &OS) const {
++ switch (Kind) {
++ case k_Token: OS << "Token: " << getToken() << "\n"; break;
++ case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
++ case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
++ case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
++ << getMemOffsetReg() << "\n"; break;
++ case k_MemoryImm: assert(getMemOff() != 0);
++ OS << "Mem: " << getMemBase()
++ << "+" << *getMemOff()
++ << "\n"; break;
++ }
++ }
++
++ void addRegOperands(MCInst &Inst, unsigned N) const {
++ assert(N == 1 && "Invalid number of operands!");
++ Inst.addOperand(MCOperand::CreateReg(getReg()));
++ }
++
++ void addImmOperands(MCInst &Inst, unsigned N) const {
++ assert(N == 1 && "Invalid number of operands!");
++ const MCExpr *Expr = getImm();
++ addExpr(Inst, Expr);
++ }
++
++ void addExpr(MCInst &Inst, const MCExpr *Expr) const{
++ // Add as immediate when possible. Null MCExpr = 0.
++ if (Expr == 0)
++ Inst.addOperand(MCOperand::CreateImm(0));
++ else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
++ Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
++ else
++ Inst.addOperand(MCOperand::CreateExpr(Expr));
++ }
++
++ void addMEMrrOperands(MCInst &Inst, unsigned N) const {
++ assert(N == 2 && "Invalid number of operands!");
++
++ Inst.addOperand(MCOperand::CreateReg(getMemBase()));
++
++ assert(getMemOffsetReg() != 0 && "Invalid offset");
++ Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
++ }
++
++ void addMEMriOperands(MCInst &Inst, unsigned N) const {
++ assert(N == 2 && "Invalid number of operands!");
++
++ Inst.addOperand(MCOperand::CreateReg(getMemBase()));
++
++ const MCExpr *Expr = getMemOff();
++ addExpr(Inst, Expr);
++ }
++
++ static SparcOperand *CreateToken(StringRef Str, SMLoc S) {
++ SparcOperand *Op = new SparcOperand(k_Token);
++ Op->Tok.Data = Str.data();
++ Op->Tok.Length = Str.size();
++ Op->StartLoc = S;
++ Op->EndLoc = S;
++ return Op;
++ }
++
++ static SparcOperand *CreateReg(unsigned RegNum,
++ SparcOperand::RegisterKind Kind,
++ SMLoc S, SMLoc E) {
++ SparcOperand *Op = new SparcOperand(k_Register);
++ Op->Reg.RegNum = RegNum;
++ Op->Reg.Kind = Kind;
++ Op->StartLoc = S;
++ Op->EndLoc = E;
++ return Op;
++ }
++
++ static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
++ SparcOperand *Op = new SparcOperand(k_Immediate);
++ Op->Imm.Val = Val;
++ Op->StartLoc = S;
++ Op->EndLoc = E;
++ return Op;
++ }
++
++
++};
++
++} // end namespace
++
++bool SparcAsmParser::
++MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
++ SmallVectorImpl<MCParsedAsmOperand*> &Operands,
++ MCStreamer &Out, unsigned &ErrorInfo,
++ bool MatchingInlineAsm) {
++ MCInst Inst;
++ SmallVector<MCInst, 8> Instructions;
++ unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
++ MatchingInlineAsm);
++ switch (MatchResult) {
++ default:
++ break;
++
++ case Match_Success: {
++ Inst.setLoc(IDLoc);
++ Out.EmitInstruction(Inst);
++ return false;
++ }
++
++ case Match_MissingFeature:
++ return Error(IDLoc,
++ "instruction requires a CPU feature not currently enabled");
++
++ case Match_InvalidOperand: {
++ SMLoc ErrorLoc = IDLoc;
++ if (ErrorInfo != ~0U) {
++ if (ErrorInfo >= Operands.size())
++ return Error(IDLoc, "too few operands for instruction");
++
++ ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
++ if (ErrorLoc == SMLoc())
++ ErrorLoc = IDLoc;
++ }
++
++ return Error(ErrorLoc, "invalid operand for instruction");
++ }
++ case Match_MnemonicFail:
++ return Error(IDLoc, "invalid instruction");
++ }
++ return true;
++}
++
++bool SparcAsmParser::
++ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
++{
++ const AsmToken &Tok = Parser.getTok();
++ StartLoc = Tok.getLoc();
++ EndLoc = Tok.getEndLoc();
++ RegNo = 0;
++ if (getLexer().getKind() != AsmToken::Percent)
++ return false;
++ Parser.Lex();
++ if (matchRegisterName(Tok, RegNo, false, false)) {
++ Parser.Lex();
++ return false;
++ }
++
++ return Error(StartLoc, "invalid register name");
++}
++
++bool SparcAsmParser::
++ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
++ SMLoc NameLoc,
++ SmallVectorImpl<MCParsedAsmOperand*> &Operands)
++{
++ // Check if we have valid mnemonic.
++ if (!mnemonicIsValid(Name, 0)) {
++ Parser.eatToEndOfStatement();
++ return Error(NameLoc, "Unknown instruction");
++ }
++ // First operand in MCInst is instruction mnemonic.
++ Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
++
++ if (getLexer().isNot(AsmToken::EndOfStatement)) {
++ // Read the first operand.
++ if (parseOperand(Operands, Name) != MatchOperand_Success) {
++ SMLoc Loc = getLexer().getLoc();
++ Parser.eatToEndOfStatement();
++ return Error(Loc, "unexpected token");
++ }
++
++ while (getLexer().is(AsmToken::Comma)) {
++ Parser.Lex(); // Eat the comma.
++ // Parse and remember the operand.
++ if (parseOperand(Operands, Name) != MatchOperand_Success) {
++ SMLoc Loc = getLexer().getLoc();
++ Parser.eatToEndOfStatement();
++ return Error(Loc, "unexpected token");
++ }
++ }
++ }
++ if (getLexer().isNot(AsmToken::EndOfStatement)) {
++ SMLoc Loc = getLexer().getLoc();
++ Parser.eatToEndOfStatement();
++ return Error(Loc, "unexpected token");
++ }
++ Parser.Lex(); // Consume the EndOfStatement.
++ return false;
++}
++
++bool SparcAsmParser::
++ParseDirective(AsmToken DirectiveID)
++{
++ // Ignore all directives for now.
++ Parser.eatToEndOfStatement();
++ return false;
++}
++
++SparcAsmParser::OperandMatchResultTy SparcAsmParser::
++parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
++ int ImmOffsetOrReg)
++{
++ // FIXME: Implement memory operand parsing here.
++ return MatchOperand_NoMatch;
++}
++
++SparcAsmParser::OperandMatchResultTy SparcAsmParser::
++parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
++{
++ return parseMEMOperand(Operands, 2);
++}
++
++SparcAsmParser::OperandMatchResultTy SparcAsmParser::
++parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
++{
++ return parseMEMOperand(Operands, 1);
++}
++
++SparcAsmParser::OperandMatchResultTy SparcAsmParser::
++parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
++ StringRef Mnemonic)
++{
++ OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
++ if (ResTy == MatchOperand_Success)
++ return ResTy;
++ // If there wasn't a custom match, try the generic matcher below. Otherwise,
++ // there was a match, but an error occurred, in which case, just return that
++ // the operand parsing failed.
++ if (ResTy == MatchOperand_ParseFail)
++ return ResTy;
++
++ SMLoc S = Parser.getTok().getLoc();
++ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
++ const MCExpr *EVal;
++ SparcOperand *Op;
++ switch (getLexer().getKind()) {
++ case AsmToken::Percent:
++ Parser.Lex(); // Eat the '%'.
++ unsigned RegNo;
++ if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
++ Parser.Lex(); // Eat the identifier token.
++ Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
++ break;
++ }
++ // FIXME: Handle modifiers like %hi, %lo etc.,
++ return MatchOperand_ParseFail;
++
++ case AsmToken::Minus:
++ case AsmToken::Integer:
++ if (getParser().parseExpression(EVal))
++ return MatchOperand_ParseFail;
++
++ Op = SparcOperand::CreateImm(EVal, S, E);
++ break;
++
++ case AsmToken::Identifier: {
++ StringRef Identifier;
++ if (getParser().parseIdentifier(Identifier))
++ return MatchOperand_ParseFail;
++ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
++ MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
++
++ // Otherwise create a symbol reference.
++ const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
++ getContext());
++
++ Op = SparcOperand::CreateImm(Res, S, E);
++ break;
++ }
++
++ case AsmToken::LBrac: // handle [
++ return parseMEMOperand(Operands, 0);
++
++ default:
++ return MatchOperand_ParseFail;
++ }
++ // Push the parsed operand into the list of operands
++ Operands.push_back(Op);
++ return MatchOperand_Success;
++}
++
++bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
++ unsigned &RegNo,
++ bool isDFP,
++ bool isQFP)
++{
++ int64_t intVal = 0;
++ RegNo = 0;
++ if (Tok.is(AsmToken::Identifier)) {
++ StringRef name = Tok.getString();
++
++ // %fp
++ if (name.equals("fp")) {
++ RegNo = Sparc::I6;
++ return true;
++ }
++ // %sp
++ if (name.equals("sp")) {
++ RegNo = Sparc::O6;
++ return true;
++ }
++
++ if (name.equals("y")) {
++ RegNo = Sparc::Y;
++ return true;
++ }
++
++ if (name.equals("icc")) {
++ RegNo = Sparc::ICC;
++ return true;
++ }
++
++ if (name.equals("xcc")) {
++ // FIXME:: check 64bit.
++ RegNo = Sparc::ICC;
++ return true;
++ }
++
++ // %fcc0 - %fcc3
++ if (name.substr(0, 3).equals_lower("fcc")
++ && !name.substr(3).getAsInteger(10, intVal)
++ && intVal < 4) {
++ // FIXME: check 64bit and handle %fcc1 - %fcc3
++ RegNo = Sparc::FCC;
++ return true;
++ }
++
++ // %g0 - %g7
++ if (name.substr(0, 1).equals_lower("g")
++ && !name.substr(1).getAsInteger(10, intVal)
++ && intVal < 8) {
++ RegNo = IntRegs[intVal];
++ return true;
++ }
++ // %o0 - %o7
++ if (name.substr(0, 1).equals_lower("o")
++ && !name.substr(1).getAsInteger(10, intVal)
++ && intVal < 8) {
++ RegNo = IntRegs[8 + intVal];
++ return true;
++ }
++ if (name.substr(0, 1).equals_lower("l")
++ && !name.substr(1).getAsInteger(10, intVal)
++ && intVal < 8) {
++ RegNo = IntRegs[16 + intVal];
++ return true;
++ }
++ if (name.substr(0, 1).equals_lower("i")
++ && !name.substr(1).getAsInteger(10, intVal)
++ && intVal < 8) {
++ RegNo = IntRegs[24 + intVal];
++ return true;
++ }
++ // %f0 - %f31
++ if (name.substr(0, 1).equals_lower("f")
++ && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
++ if (isDFP && (intVal%2 == 0)) {
++ RegNo = DoubleRegs[intVal/2];
++ } else if (isQFP && (intVal%4 == 0)) {
++ RegNo = QuadFPRegs[intVal/4];
++ } else {
++ RegNo = FloatRegs[intVal];
++ }
++ return true;
++ }
++ // %f32 - %f62
++ if (name.substr(0, 1).equals_lower("f")
++ && !name.substr(1, 2).getAsInteger(10, intVal)
++ && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
++ if (isDFP) {
++ RegNo = DoubleRegs[16 + intVal/2];
++ } else if (isQFP && (intVal % 4 == 0)) {
++ RegNo = QuadFPRegs[8 + intVal/4];
++ } else {
++ return false;
++ }
++ return true;
++ }
++
++ // %r0 - %r31
++ if (name.substr(0, 1).equals_lower("r")
++ && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
++ RegNo = IntRegs[intVal];
++ return true;
++ }
++ }
++ return false;
++}
++
++
++
++extern "C" void LLVMInitializeSparcAsmParser() {
++ RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
++ RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
++}
++
++#define GET_REGISTER_MATCHER
++#define GET_MATCHER_IMPLEMENTATION
++#include "SparcGenAsmMatcher.inc"
+Index: lib/Target/Sparc/AsmParser/LLVMBuild.txt
+===================================================================
+--- lib/Target/Sparc/AsmParser/LLVMBuild.txt
++++ lib/Target/Sparc/AsmParser/LLVMBuild.txt
+@@ -0,0 +1,23 @@
++;===- ./lib/Target/Sparc/AsmParser/LLVMBuild.txt ---------------*- Conf -*--===;
++;
++; The LLVM Compiler Infrastructure
++;
++; This file is distributed under the University of Illinois Open Source
++; License. See LICENSE.TXT for details.
++;
++;===------------------------------------------------------------------------===;
++;
++; This is an LLVMBuild description file for the components in this subdirectory.
++;
++; For more information on the LLVMBuild system, please see:
++;
++; http://llvm.org/docs/LLVMBuild.html
++;
++;===------------------------------------------------------------------------===;
++
++[component_0]
++type = Library
++name = SparcAsmParser
++parent = Sparc
++required_libraries = MC MCParser Support SparcDesc SparcInfo
++add_to_library_groups = Sparc
+Index: lib/Target/Sparc/AsmParser/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/AsmParser/CMakeLists.txt
++++ lib/Target/Sparc/AsmParser/CMakeLists.txt
+@@ -0,0 +1,3 @@
++add_llvm_library(LLVMSparcAsmParser
++ SparcAsmParser.cpp
++ )
+Index: lib/Target/Sparc/AsmParser/Makefile
+===================================================================
+--- lib/Target/Sparc/AsmParser/Makefile
++++ lib/Target/Sparc/AsmParser/Makefile
+@@ -0,0 +1,15 @@
++##===- lib/Target/Sparc/AsmParser/Makefile ------------------*- Makefile-*-===##
++#
++# The LLVM Compiler Infrastructure
++#
++# This file is distributed under the University of Illinois Open Source
++# License. See LICENSE.TXT for details.
++#
++##===----------------------------------------------------------------------===##
++LEVEL = ../../../..
++LIBRARYNAME = LLVMSparcAsmParser
++
++# Hack: we need to include 'main' Sparc target directory to grab private headers
++CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
++
++include $(LEVEL)/Makefile.common
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -176,11 +176,11 @@ def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMP
+ def : Pat<(ctpop i64:$src), (POPCrr $src)>;
+
+ // "LEA" form of add
++let isCodeGenOnly = 1 in
+ def LEAX_ADDri : F3_2<2, 0b000000,
+ (outs I64Regs:$dst), (ins MEMri:$addr),
+ "add ${addr:arith}, $dst",
+ [(set iPTR:$dst, ADDRri:$addr)]>;
+-
+ } // Predicates = [Is64Bit]
+
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff
new file mode 100644
index 0000000..d6e65da
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff
@@ -0,0 +1,516 @@
+Pull in r198533 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add initial implementation of MC Code emitter for sparc.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -100,9 +100,14 @@ def MEMri : Operand<iPTR> {
+ def TLSSym : Operand<iPTR>;
+
+ // Branch targets have OtherVT type.
+-def brtarget : Operand<OtherVT>;
+-def calltarget : Operand<i32>;
++def brtarget : Operand<OtherVT> {
++ let EncoderMethod = "getBranchTargetOpValue";
++}
+
++def calltarget : Operand<i32> {
++ let EncoderMethod = "getCallTargetOpValue";
++}
++
+ // Operand for printing out a condition code.
+ let PrintMethod = "printCCOperand" in
+ def CCOp : Operand<i32>;
+Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
++++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
+@@ -1,6 +1,8 @@
+ add_llvm_library(LLVMSparcDesc
++ SparcAsmBackend.cpp
++ SparcMCAsmInfo.cpp
++ SparcMCCodeEmitter.cpp
+ SparcMCTargetDesc.cpp
+- SparcMCAsmInfo.cpp
+ SparcMCExpr.cpp
+ SparcTargetStreamer.cpp
+ )
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+@@ -0,0 +1,131 @@
++//===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This file implements the SparcMCCodeEmitter class.
++//
++//===----------------------------------------------------------------------===//
++
++#define DEBUG_TYPE "mccodeemitter"
++#include "SparcMCTargetDesc.h"
++#include "MCTargetDesc/SparcFixupKinds.h"
++#include "llvm/MC/MCCodeEmitter.h"
++#include "llvm/MC/MCContext.h"
++#include "llvm/MC/MCExpr.h"
++#include "llvm/MC/MCInst.h"
++#include "llvm/MC/MCRegisterInfo.h"
++#include "llvm/ADT/Statistic.h"
++#include "llvm/Support/raw_ostream.h"
++
++using namespace llvm;
++
++STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
++
++namespace {
++class SparcMCCodeEmitter : public MCCodeEmitter {
++ SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
++ void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
++ MCContext &Ctx;
++
++public:
++ SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {}
++
++ ~SparcMCCodeEmitter() {}
++
++ void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
++ SmallVectorImpl<MCFixup> &Fixups) const;
++
++ // getBinaryCodeForInstr - TableGen'erated function for getting the
++ // binary encoding for an instruction.
++ uint64_t getBinaryCodeForInstr(const MCInst &MI,
++ SmallVectorImpl<MCFixup> &Fixups) const;
++
++ /// getMachineOpValue - Return binary encoding of operand. If the machine
++ /// operand requires relocation, record the relocation and return zero.
++ unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
++ SmallVectorImpl<MCFixup> &Fixups) const;
++
++ unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
++ SmallVectorImpl<MCFixup> &Fixups) const;
++ unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
++ SmallVectorImpl<MCFixup> &Fixups) const;
++
++};
++} // end anonymous namespace
++
++MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
++ const MCRegisterInfo &MRI,
++ const MCSubtargetInfo &STI,
++ MCContext &Ctx) {
++ return new SparcMCCodeEmitter(Ctx);
++}
++
++void SparcMCCodeEmitter::
++EncodeInstruction(const MCInst &MI, raw_ostream &OS,
++ SmallVectorImpl<MCFixup> &Fixups) const {
++ unsigned Bits = getBinaryCodeForInstr(MI, Fixups);
++
++ // Output the constant in big endian byte order.
++ for (unsigned i = 0; i != 4; ++i) {
++ OS << (char)(Bits >> 24);
++ Bits <<= 8;
++ }
++
++ ++MCNumEmitted; // Keep track of the # of mi's emitted.
++}
++
++
++unsigned SparcMCCodeEmitter::
++getMachineOpValue(const MCInst &MI, const MCOperand &MO,
++ SmallVectorImpl<MCFixup> &Fixups) const {
++
++ if (MO.isReg())
++ return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
++
++ if (MO.isImm())
++ return MO.getImm();
++
++ assert(MO.isExpr());
++ const MCExpr *Expr = MO.getExpr();
++ int64_t Res;
++ if (Expr->EvaluateAsAbsolute(Res))
++ return Res;
++
++ assert(0 && "Unhandled expression!");
++ return 0;
++}
++
++unsigned SparcMCCodeEmitter::
++getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
++ SmallVectorImpl<MCFixup> &Fixups) const {
++ const MCOperand &MO = MI.getOperand(OpNo);
++ if (MO.isReg() || MO.isImm())
++ return getMachineOpValue(MI, MO, Fixups);
++
++ Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
++ (MCFixupKind)Sparc::fixup_sparc_call30));
++ return 0;
++}
++
++unsigned SparcMCCodeEmitter::
++getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
++ SmallVectorImpl<MCFixup> &Fixups) const {
++ const MCOperand &MO = MI.getOperand(OpNo);
++ if (MO.isReg() || MO.isImm())
++ return getMachineOpValue(MI, MO, Fixups);
++
++ Sparc::Fixups fixup = Sparc::fixup_sparc_br22;
++ if (MI.getOpcode() == SP::BPXCC)
++ fixup = Sparc::fixup_sparc_br19;
++
++ Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
++ (MCFixupKind)fixup));
++ return 0;
++}
++
++#include "SparcGenMCCodeEmitter.inc"
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+@@ -136,6 +136,18 @@ extern "C" void LLVMInitializeSparcTargetMC() {
+ TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target,
+ createSparcMCSubtargetInfo);
+
++ // Register the MC Code Emitter.
++ TargetRegistry::RegisterMCCodeEmitter(TheSparcTarget,
++ createSparcMCCodeEmitter);
++ TargetRegistry::RegisterMCCodeEmitter(TheSparcV9Target,
++ createSparcMCCodeEmitter);
++
++ //Register the asm backend.
++ TargetRegistry::RegisterMCAsmBackend(TheSparcTarget,
++ createSparcAsmBackend);
++ TargetRegistry::RegisterMCAsmBackend(TheSparcV9Target,
++ createSparcAsmBackend);
++
+ TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
+ createMCAsmStreamer);
+ TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
+Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+@@ -0,0 +1,101 @@
++//===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++
++#include "llvm/MC/MCAsmBackend.h"
++#include "MCTargetDesc/SparcMCTargetDesc.h"
++#include "MCTargetDesc/SparcFixupKinds.h"
++#include "llvm/MC/MCFixupKindInfo.h"
++#include "llvm/MC/MCObjectWriter.h"
++#include "llvm/Support/TargetRegistry.h"
++
++using namespace llvm;
++
++namespace {
++ class SparcAsmBackend : public MCAsmBackend {
++
++ public:
++ SparcAsmBackend(const Target &T) : MCAsmBackend() {}
++
++ unsigned getNumFixupKinds() const {
++ return Sparc::NumTargetFixupKinds;
++ }
++
++ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
++ const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = {
++ // name offset bits flags
++ { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel }
++ };
++
++ if (Kind < FirstTargetFixupKind)
++ return MCAsmBackend::getFixupKindInfo(Kind);
++
++ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
++ "Invalid kind!");
++ return Infos[Kind - FirstTargetFixupKind];
++ }
++
++ bool mayNeedRelaxation(const MCInst &Inst) const {
++ // FIXME.
++ return false;
++ }
++
++ /// fixupNeedsRelaxation - Target specific predicate for whether a given
++ /// fixup requires the associated instruction to be relaxed.
++ bool fixupNeedsRelaxation(const MCFixup &Fixup,
++ uint64_t Value,
++ const MCRelaxableFragment *DF,
++ const MCAsmLayout &Layout) const {
++ // FIXME.
++ assert(0 && "fixupNeedsRelaxation() unimplemented");
++ return false;
++ }
++ void relaxInstruction(const MCInst &Inst, MCInst &Res) const {
++ // FIXME.
++ assert(0 && "relaxInstruction() unimplemented");
++ }
++
++ bool writeNopData(uint64_t Count, MCObjectWriter *OW) const {
++ // FIXME: Zero fill for now.
++ for (uint64_t i = 0; i != Count; ++i)
++ OW->Write8(0);
++ return true;
++ }
++ };
++
++ class ELFSparcAsmBackend : public SparcAsmBackend {
++ public:
++ ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
++ SparcAsmBackend(T) { }
++
++ void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
++ uint64_t Value) const {
++ assert(0 && "applyFixup not implemented yet");
++ }
++
++ MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
++ assert(0 && "Object Writer not implemented yet");
++ return 0;
++ }
++
++ virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
++ return false;
++ }
++ };
++
++} // end anonymous namespace
++
++
++MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
++ const MCRegisterInfo &MRI,
++ StringRef TT,
++ StringRef CPU) {
++ return new ELFSparcAsmBackend(T, Triple(TT).getOS());
++}
+Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
++++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+@@ -0,0 +1,36 @@
++//===-- SparcFixupKinds.h - Sparc Specific Fixup Entries --------*- C++ -*-===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++
++#ifndef LLVM_SPARC_FIXUPKINDS_H
++#define LLVM_SPARC_FIXUPKINDS_H
++
++#include "llvm/MC/MCFixup.h"
++
++namespace llvm {
++ namespace Sparc {
++ enum Fixups {
++ // fixup_sparc_call30 - 30-bit PC relative relocation for call
++ fixup_sparc_call30 = FirstTargetFixupKind,
++
++ /// fixup_sparc_br22 - 22-bit PC relative relocation for
++ /// branches
++ fixup_sparc_br22,
++
++ /// fixup_sparc_br22 - 22-bit PC relative relocation for
++ /// branches on icc/xcc
++ fixup_sparc_br19,
++
++ // Marker
++ LastTargetFixupKind,
++ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
++ };
++ }
++}
++
++#endif
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
+@@ -15,11 +15,27 @@
+ #define SPARCMCTARGETDESC_H
+
+ namespace llvm {
++class MCAsmBackend;
++class MCCodeEmitter;
++class MCContext;
++class MCInstrInfo;
++class MCRegisterInfo;
++class MCSubtargetInfo;
+ class Target;
++class StringRef;
+
+ extern Target TheSparcTarget;
+ extern Target TheSparcV9Target;
+
++MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII,
++ const MCRegisterInfo &MRI,
++ const MCSubtargetInfo &STI,
++ MCContext &Ctx);
++MCAsmBackend *createSparcAsmBackend(const Target &T,
++ const MCRegisterInfo &MRI,
++ StringRef TT,
++ StringRef CPU);
++
+ } // End llvm namespace
+
+ // Defines symbolic names for Sparc registers. This defines a mapping from
+Index: lib/Target/Sparc/Makefile
+===================================================================
+--- lib/Target/Sparc/Makefile
++++ lib/Target/Sparc/Makefile
+@@ -16,7 +16,7 @@ BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenI
+ SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
+ SparcGenDAGISel.inc \
+ SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
+- SparcGenCodeEmitter.inc
++ SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc
+
+ DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
+
+Index: lib/Target/Sparc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/CMakeLists.txt
++++ lib/Target/Sparc/CMakeLists.txt
+@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td)
+ tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
+ tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
+ tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
++tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter)
+ tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
+ tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
+ tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel)
+Index: lib/Target/Sparc/SparcCodeEmitter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcCodeEmitter.cpp
++++ lib/Target/Sparc/SparcCodeEmitter.cpp
+@@ -72,6 +72,11 @@ class SparcCodeEmitter : public MachineFunctionPas
+ unsigned getMachineOpValue(const MachineInstr &MI,
+ const MachineOperand &MO) const;
+
++ unsigned getCallTargetOpValue(const MachineInstr &MI,
++ unsigned) const;
++ unsigned getBranchTargetOpValue(const MachineInstr &MI,
++ unsigned) const;
++
+ void emitWord(unsigned Word);
+
+ unsigned getRelocation(const MachineInstr &MI,
+@@ -181,6 +186,18 @@ unsigned SparcCodeEmitter::getMachineOpValue(const
+ llvm_unreachable("Unable to encode MachineOperand!");
+ return 0;
+ }
++unsigned SparcCodeEmitter::getCallTargetOpValue(const MachineInstr &MI,
++ unsigned opIdx) const {
++ const MachineOperand MO = MI.getOperand(opIdx);
++ return getMachineOpValue(MI, MO);
++}
++
++unsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
++ unsigned opIdx) const {
++ const MachineOperand MO = MI.getOperand(opIdx);
++ return getMachineOpValue(MI, MO);
++}
++
+ unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI,
+ const MachineOperand &MO) const {
+
+Index: test/MC/Sparc/sparc-alu-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-alu-instructions.s
++++ test/MC/Sparc/sparc-alu-instructions.s
+@@ -0,0 +1,72 @@
++! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
++
++ ! CHECK: add %g0, %g0, %g0 ! encoding: [0x80,0x00,0x00,0x00]
++ add %g0, %g0, %g0
++ ! CHECK: add %g1, %g2, %g3 ! encoding: [0x86,0x00,0x40,0x02]
++ add %g1, %g2, %g3
++ ! CHECK: add %o0, %o1, %l0 ! encoding: [0xa0,0x02,0x00,0x09]
++ add %r8, %r9, %l0
++ ! CHECK: add %o0, 10, %l0 ! encoding: [0xa0,0x02,0x20,0x0a]
++ add %o0, 10, %l0
++
++ ! CHECK: addcc %g1, %g2, %g3 ! encoding: [0x86,0x80,0x40,0x02]
++ addcc %g1, %g2, %g3
++
++ ! CHECK: addxcc %g1, %g2, %g3 ! encoding: [0x86,0xc0,0x40,0x02]
++ addxcc %g1, %g2, %g3
++
++ ! CHECK: udiv %g1, %g2, %g3 ! encoding: [0x86,0x70,0x40,0x02]
++ udiv %g1, %g2, %g3
++
++ ! CHECK: sdiv %g1, %g2, %g3 ! encoding: [0x86,0x78,0x40,0x02]
++ sdiv %g1, %g2, %g3
++
++ ! CHECK: and %g1, %g2, %g3 ! encoding: [0x86,0x08,0x40,0x02]
++ and %g1, %g2, %g3
++ ! CHECK: andn %g1, %g2, %g3 ! encoding: [0x86,0x28,0x40,0x02]
++ andn %g1, %g2, %g3
++ ! CHECK: or %g1, %g2, %g3 ! encoding: [0x86,0x10,0x40,0x02]
++ or %g1, %g2, %g3
++ ! CHECK: orn %g1, %g2, %g3 ! encoding: [0x86,0x30,0x40,0x02]
++ orn %g1, %g2, %g3
++ ! CHECK: xor %g1, %g2, %g3 ! encoding: [0x86,0x18,0x40,0x02]
++ xor %g1, %g2, %g3
++ ! CHECK: xnor %g1, %g2, %g3 ! encoding: [0x86,0x38,0x40,0x02]
++ xnor %g1, %g2, %g3
++
++ ! CHECK: umul %g1, %g2, %g3 ! encoding: [0x86,0x50,0x40,0x02]
++ umul %g1, %g2, %g3
++
++ ! CHECK: smul %g1, %g2, %g3 ! encoding: [0x86,0x58,0x40,0x02]
++ smul %g1, %g2, %g3
++
++ ! CHECK: nop ! encoding: [0x01,0x00,0x00,0x00]
++ nop
++
++ ! CHECK: sethi 10, %l0 ! encoding: [0x21,0x00,0x00,0x0a]
++ sethi 10, %l0
++
++ ! CHECK: sll %g1, %g2, %g3 ! encoding: [0x87,0x28,0x40,0x02]
++ sll %g1, %g2, %g3
++ ! CHECK: sll %g1, 31, %g3 ! encoding: [0x87,0x28,0x60,0x1f]
++ sll %g1, 31, %g3
++
++ ! CHECK: srl %g1, %g2, %g3 ! encoding: [0x87,0x30,0x40,0x02]
++ srl %g1, %g2, %g3
++ ! CHECK: srl %g1, 31, %g3 ! encoding: [0x87,0x30,0x60,0x1f]
++ srl %g1, 31, %g3
++
++ ! CHECK: sra %g1, %g2, %g3 ! encoding: [0x87,0x38,0x40,0x02]
++ sra %g1, %g2, %g3
++ ! CHECK: sra %g1, 31, %g3 ! encoding: [0x87,0x38,0x60,0x1f]
++ sra %g1, 31, %g3
++
++ ! CHECK: sub %g1, %g2, %g3 ! encoding: [0x86,0x20,0x40,0x02]
++ sub %g1, %g2, %g3
++ ! CHECK: subcc %g1, %g2, %g3 ! encoding: [0x86,0xa0,0x40,0x02]
++ subcc %g1, %g2, %g3
++
++ ! CHECK: subxcc %g1, %g2, %g3 ! encoding: [0x86,0xe0,0x40,0x02]
++ subxcc %g1, %g2, %g3
++
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198565-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198565-sparc.diff
new file mode 100644
index 0000000..cf32440
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198565-sparc.diff
@@ -0,0 +1,76 @@
+Pull in r198565 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ ELF relocation types for sparc.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: include/llvm/Support/ELF.h
+===================================================================
+--- include/llvm/Support/ELF.h
++++ include/llvm/Support/ELF.h
+@@ -1087,6 +1087,65 @@ enum {
+ R_390_IRELATIVE = 61
+ };
+
++// ELF Relocation type for Sparc.
++enum {
++ R_SPARC_NONE = 0,
++ R_SPARC_8 = 1,
++ R_SPARC_16 = 2,
++ R_SPARC_32 = 3,
++ R_SPARC_DISP8 = 4,
++ R_SPARC_DISP16 = 5,
++ R_SPARC_DISP32 = 6,
++ R_SPARC_WDISP30 = 7,
++ R_SPARC_WDISP22 = 8,
++ R_SPARC_HI22 = 9,
++ R_SPARC_22 = 10,
++ R_SPARC_13 = 11,
++ R_SPARC_LO10 = 12,
++ R_SPARC_GOT10 = 13,
++ R_SPARC_GOT13 = 14,
++ R_SPARC_GOT22 = 15,
++ R_SPARC_PC10 = 16,
++ R_SPARC_PC22 = 17,
++ R_SPARC_WPLT30 = 18,
++ R_SPARC_COPY = 19,
++ R_SPARC_GLOB_DAT = 20,
++ R_SPARC_JMP_SLOT = 21,
++ R_SPARC_RELATIVE = 22,
++ R_SPARC_UA32 = 23,
++ R_SPARC_PLT32 = 24,
++ R_SPARC_HIPLT22 = 25,
++ R_SPARC_LOPLT10 = 26,
++ R_SPARC_PCPLT32 = 27,
++ R_SPARC_PCPLT22 = 28,
++ R_SPARC_PCPLT10 = 29,
++ R_SPARC_10 = 30,
++ R_SPARC_11 = 31,
++ R_SPARC_64 = 32,
++ R_SPARC_OLO10 = 33,
++ R_SPARC_HH22 = 34,
++ R_SPARC_HM10 = 35,
++ R_SPARC_LM22 = 36,
++ R_SPARC_PC_HH22 = 37,
++ R_SPARC_PC_HM10 = 38,
++ R_SPARC_PC_LM22 = 39,
++ R_SPARC_WDISP16 = 40,
++ R_SPARC_WDISP19 = 41,
++ R_SPARC_7 = 43,
++ R_SPARC_5 = 44,
++ R_SPARC_6 = 45,
++ R_SPARC_DISP64 = 46,
++ R_SPARC_PLT64 = 47,
++ R_SPARC_HIX22 = 48,
++ R_SPARC_LOX10 = 49,
++ R_SPARC_H44 = 50,
++ R_SPARC_M44 = 51,
++ R_SPARC_L44 = 52,
++ R_SPARC_REGISTER = 53,
++ R_SPARC_UA64 = 54,
++ R_SPARC_UA16 = 55
++};
++
+ // Section header.
+ struct Elf32_Shdr {
+ Elf32_Word sh_name; // Section name (index into string table)
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198567-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198567-sparc.diff
new file mode 100644
index 0000000..0ce6863
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198567-sparc.diff
@@ -0,0 +1,21 @@
+Pull in r198567 from upstream llvm trunk (by Benjamin Kramer):
+
+ SPARC: Make helper function static.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -130,8 +130,8 @@ static void EmitOR(MCStreamer &OutStreamer, MCOper
+ OutStreamer.EmitInstruction(ORInst);
+ }
+
+-void EmitADD(MCStreamer &OutStreamer,
+- MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
++static void EmitADD(MCStreamer &OutStreamer,
++ MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
+ {
+ MCInst ADDInst;
+ ADDInst.setOpcode(SP::ADDrr);
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198580-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198580-sparc.diff
new file mode 100644
index 0000000..e30cbb2
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198580-sparc.diff
@@ -0,0 +1,460 @@
+Pull in r198580 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add ELF Object Writer for Sparc.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+@@ -12,6 +12,7 @@
+ //===----------------------------------------------------------------------===//
+
+ #define DEBUG_TYPE "mccodeemitter"
++#include "SparcMCExpr.h"
+ #include "SparcMCTargetDesc.h"
+ #include "MCTargetDesc/SparcFixupKinds.h"
+ #include "llvm/MC/MCCodeEmitter.h"
+@@ -92,6 +93,41 @@ getMachineOpValue(const MCInst &MI, const MCOperan
+
+ assert(MO.isExpr());
+ const MCExpr *Expr = MO.getExpr();
++ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
++ switch(SExpr->getKind()) {
++ default: assert(0 && "Unhandled sparc expression!"); break;
++ case SparcMCExpr::VK_Sparc_LO:
++ Fixups.push_back(MCFixup::Create(0, Expr,
++ (MCFixupKind)Sparc::fixup_sparc_lo10));
++ break;
++ case SparcMCExpr::VK_Sparc_HI:
++ Fixups.push_back(MCFixup::Create(0, Expr,
++ (MCFixupKind)Sparc::fixup_sparc_hi22));
++ break;
++ case SparcMCExpr::VK_Sparc_H44:
++ Fixups.push_back(MCFixup::Create(0, Expr,
++ (MCFixupKind)Sparc::fixup_sparc_h44));
++ break;
++ case SparcMCExpr::VK_Sparc_M44:
++ Fixups.push_back(MCFixup::Create(0, Expr,
++ (MCFixupKind)Sparc::fixup_sparc_m44));
++ break;
++ case SparcMCExpr::VK_Sparc_L44:
++ Fixups.push_back(MCFixup::Create(0, Expr,
++ (MCFixupKind)Sparc::fixup_sparc_l44));
++ break;
++ case SparcMCExpr::VK_Sparc_HH:
++ Fixups.push_back(MCFixup::Create(0, Expr,
++ (MCFixupKind)Sparc::fixup_sparc_hh));
++ break;
++ case SparcMCExpr::VK_Sparc_HM:
++ Fixups.push_back(MCFixup::Create(0, Expr,
++ (MCFixupKind)Sparc::fixup_sparc_hm));
++ break;
++ }
++ return 0;
++ }
++
+ int64_t Res;
+ if (Expr->EvaluateAsAbsolute(Res))
+ return Res;
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+@@ -89,6 +89,14 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(S
+ return X;
+ }
+
++static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
++ MCContext &Context, MCAsmBackend &MAB,
++ raw_ostream &OS, MCCodeEmitter *Emitter,
++ bool RelaxAll, bool NoExecStack) {
++ SparcTargetELFStreamer *S = new SparcTargetELFStreamer();
++ return createELFStreamer(Context, S, MAB, OS, Emitter, RelaxAll, NoExecStack);
++}
++
+ static MCStreamer *
+ createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool isVerboseAsm, bool useLoc, bool useCFI,
+@@ -148,6 +156,13 @@ extern "C" void LLVMInitializeSparcTargetMC() {
+ TargetRegistry::RegisterMCAsmBackend(TheSparcV9Target,
+ createSparcAsmBackend);
+
++ // Register the object streamer.
++ TargetRegistry::RegisterMCObjectStreamer(TheSparcTarget,
++ createMCStreamer);
++ TargetRegistry::RegisterMCObjectStreamer(TheSparcV9Target,
++ createMCStreamer);
++
++ // Register the asm streamer.
+ TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
+ createMCAsmStreamer);
+ TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
+Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+@@ -10,6 +10,7 @@
+ #include "llvm/MC/MCAsmBackend.h"
+ #include "MCTargetDesc/SparcMCTargetDesc.h"
+ #include "MCTargetDesc/SparcFixupKinds.h"
++#include "llvm/MC/MCELFObjectWriter.h"
+ #include "llvm/MC/MCFixupKindInfo.h"
+ #include "llvm/MC/MCObjectWriter.h"
+ #include "llvm/Support/TargetRegistry.h"
+@@ -16,11 +17,43 @@
+
+ using namespace llvm;
+
++static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
++ switch (Kind) {
++ default:
++ llvm_unreachable("Unknown fixup kind!");
++ case FK_Data_1:
++ case FK_Data_2:
++ case FK_Data_4:
++ case FK_Data_8:
++ return Value;
++ case Sparc::fixup_sparc_call30:
++ return Value & 0x3fffffff;
++ case Sparc::fixup_sparc_br22:
++ return Value & 0x3fffff;
++ case Sparc::fixup_sparc_br19:
++ return Value & 0x1ffff;
++ case Sparc::fixup_sparc_hi22:
++ return (Value >> 10) & 0x3fffff;
++ case Sparc::fixup_sparc_lo10:
++ return Value & 0x3ff;
++ case Sparc::fixup_sparc_h44:
++ return (Value >> 22) & 0x3fffff;
++ case Sparc::fixup_sparc_m44:
++ return (Value >> 12) & 0x3ff;
++ case Sparc::fixup_sparc_l44:
++ return Value & 0xfff;
++ case Sparc::fixup_sparc_hh:
++ return (Value >> 42) & 0x3fffff;
++ case Sparc::fixup_sparc_hm:
++ return (Value >>32) & 0x3ff;
++ }
++}
++
+ namespace {
+ class SparcAsmBackend : public MCAsmBackend {
+-
++ const Target &TheTarget;
+ public:
+- SparcAsmBackend(const Target &T) : MCAsmBackend() {}
++ SparcAsmBackend(const Target &T) : MCAsmBackend(), TheTarget(T) {}
+
+ unsigned getNumFixupKinds() const {
+ return Sparc::NumTargetFixupKinds;
+@@ -31,7 +64,14 @@ namespace {
+ // name offset bits flags
+ { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
+- { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel }
++ { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_hi22", 0, 22, 0 },
++ { "fixup_sparc_lo10", 0, 10, 0 },
++ { "fixup_sparc_h44", 0, 22, 0 },
++ { "fixup_sparc_m44", 0, 10, 0 },
++ { "fixup_sparc_l44", 0, 12, 0 },
++ { "fixup_sparc_hh", 0, 21, 0 },
++ { "fixup_sparc_hm", 0, 10, 0 },
+ };
+
+ if (Kind < FirstTargetFixupKind)
+@@ -68,21 +108,38 @@ namespace {
+ OW->Write8(0);
+ return true;
+ }
++
++ bool is64Bit() const {
++ StringRef name = TheTarget.getName();
++ return name == "sparcv9";
++ }
+ };
+
+ class ELFSparcAsmBackend : public SparcAsmBackend {
++ Triple::OSType OSType;
+ public:
+ ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
+- SparcAsmBackend(T) { }
++ SparcAsmBackend(T), OSType(OSType) { }
+
+ void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
+ uint64_t Value) const {
+- assert(0 && "applyFixup not implemented yet");
++
++ Value = adjustFixupValue(Fixup.getKind(), Value);
++ if (!Value) return; // Doesn't change encoding.
++
++ unsigned Offset = Fixup.getOffset();
++
++ // For each byte of the fragment that the fixup touches, mask in the bits
++ // from the fixup value. The Value has been "split up" into the
++ // appropriate bitfields above.
++ for (unsigned i = 0; i != 4; ++i)
++ Data[Offset + i] |= uint8_t((Value >> ((4 - i - 1)*8)) & 0xff);
++
+ }
+
+ MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
+- assert(0 && "Object Writer not implemented yet");
+- return 0;
++ uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
++ return createSparcELFObjectWriter(OS, is64Bit(), OSABI);
+ }
+
+ virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
++++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+@@ -22,10 +22,32 @@ namespace llvm {
+ /// branches
+ fixup_sparc_br22,
+
+- /// fixup_sparc_br22 - 22-bit PC relative relocation for
++ /// fixup_sparc_br19 - 19-bit PC relative relocation for
+ /// branches on icc/xcc
+ fixup_sparc_br19,
+
++ /// fixup_sparc_hi22 - 22-bit fixup corresponding to %hi(foo)
++ /// for sethi
++ fixup_sparc_hi22,
++
++ /// fixup_sparc_lo10 - 10-bit fixup corresponding to %lo(foo)
++ fixup_sparc_lo10,
++
++ /// fixup_sparc_h44 - 22-bit fixup corresponding to %h44(foo)
++ fixup_sparc_h44,
++
++ /// fixup_sparc_m44 - 10-bit fixup corresponding to %m44(foo)
++ fixup_sparc_m44,
++
++ /// fixup_sparc_l44 - 12-bit fixup corresponding to %l44(foo)
++ fixup_sparc_l44,
++
++ /// fixup_sparc_hh - 22-bit fixup corresponding to %hh(foo)
++ fixup_sparc_hh,
++
++ /// fixup_sparc_hm - 10-bit fixup corresponding to %hm(foo)
++ fixup_sparc_hm,
++
+ // Marker
+ LastTargetFixupKind,
+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+@@ -0,0 +1,86 @@
++//===-- SparcELFObjectWriter.cpp - Sparc ELF Writer -----------------------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++
++#include "MCTargetDesc/SparcMCTargetDesc.h"
++#include "MCTargetDesc/SparcFixupKinds.h"
++#include "llvm/ADT/STLExtras.h"
++#include "llvm/MC/MCELFObjectWriter.h"
++#include "llvm/MC/MCExpr.h"
++#include "llvm/MC/MCValue.h"
++#include "llvm/Support/ErrorHandling.h"
++
++using namespace llvm;
++
++namespace {
++ class SparcELFObjectWriter : public MCELFObjectTargetWriter {
++ public:
++ SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI)
++ : MCELFObjectTargetWriter(Is64Bit, OSABI,
++ Is64Bit ? ELF::EM_SPARCV9 : ELF::EM_SPARC,
++ /*HasRelocationAddend*/ true) {}
++
++ virtual ~SparcELFObjectWriter() {}
++ protected:
++ virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
++ bool IsPCRel, bool IsRelocWithSymbol,
++ int64_t Addend) const;
++
++ };
++}
++
++
++unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target,
++ const MCFixup &Fixup,
++ bool IsPCRel,
++ bool IsRelocWithSymbol,
++ int64_t Addend) const {
++ if (IsPCRel) {
++ switch((unsigned)Fixup.getKind()) {
++ default:
++ llvm_unreachable("Unimplemented fixup -> relocation");
++ case FK_Data_1: return ELF::R_SPARC_DISP8;
++ case FK_Data_2: return ELF::R_SPARC_DISP16;
++ case FK_Data_4: return ELF::R_SPARC_DISP32;
++ case FK_Data_8: return ELF::R_SPARC_DISP64;
++ case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30;
++ case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22;
++ case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19;
++ }
++ }
++
++ switch((unsigned)Fixup.getKind()) {
++ default:
++ llvm_unreachable("Unimplemented fixup -> relocation");
++ case FK_Data_1: return ELF::R_SPARC_8;
++ case FK_Data_2: return ((Fixup.getOffset() % 2)
++ ? ELF::R_SPARC_UA16
++ : ELF::R_SPARC_16);
++ case FK_Data_4: return ((Fixup.getOffset() % 4)
++ ? ELF::R_SPARC_UA32
++ : ELF::R_SPARC_32);
++ case FK_Data_8: return ((Fixup.getOffset() % 8)
++ ? ELF::R_SPARC_UA64
++ : ELF::R_SPARC_64);
++ case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI22;
++ case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO10;
++ case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H44;
++ case Sparc::fixup_sparc_m44: return ELF::R_SPARC_M44;
++ case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44;
++ case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22;
++ case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10;
++ }
++ return ELF::R_SPARC_NONE;
++}
++
++MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS,
++ bool Is64Bit,
++ uint8_t OSABI) {
++ MCELFObjectTargetWriter *MOTW = new SparcELFObjectWriter(Is64Bit, OSABI);
++ return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false);
++}
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
+@@ -14,15 +14,19 @@
+ #ifndef SPARCMCTARGETDESC_H
+ #define SPARCMCTARGETDESC_H
+
++#include "llvm/Support/DataTypes.h"
++
+ namespace llvm {
+ class MCAsmBackend;
+ class MCCodeEmitter;
+ class MCContext;
+ class MCInstrInfo;
++class MCObjectWriter;
+ class MCRegisterInfo;
+ class MCSubtargetInfo;
+ class Target;
+ class StringRef;
++class raw_ostream;
+
+ extern Target TheSparcTarget;
+ extern Target TheSparcV9Target;
+@@ -35,7 +39,9 @@ MCAsmBackend *createSparcAsmBackend(const Target &
+ const MCRegisterInfo &MRI,
+ StringRef TT,
+ StringRef CPU);
+-
++MCObjectWriter *createSparcELFObjectWriter(raw_ostream &OS,
++ bool Is64Bit,
++ uint8_t OSABI);
+ } // End llvm namespace
+
+ // Defines symbolic names for Sparc registers. This defines a mapping from
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+@@ -70,15 +70,67 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
+ bool
+ SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
+ const MCAsmLayout *Layout) const {
+- assert(0 && "FIXME: Implement SparcMCExpr::EvaluateAsRelocatableImpl");
+ return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
+ }
+
++static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
++ assert(0 && "Implement fixELFSymbolsInTLSFixupsImpl!");
++}
+
+ void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
+- assert(0 && "FIXME: Implement SparcMCExpr::fixELFSymbolsInTLSFixups");
++ switch(getKind()) {
++ default: return;
++ case VK_Sparc_TLS_GD_HI22:
++ case VK_Sparc_TLS_GD_LO10:
++ case VK_Sparc_TLS_GD_ADD:
++ case VK_Sparc_TLS_GD_CALL:
++ case VK_Sparc_TLS_LDM_HI22:
++ case VK_Sparc_TLS_LDM_LO10:
++ case VK_Sparc_TLS_LDM_ADD:
++ case VK_Sparc_TLS_LDM_CALL:
++ case VK_Sparc_TLS_LDO_HIX22:
++ case VK_Sparc_TLS_LDO_LOX10:
++ case VK_Sparc_TLS_LDO_ADD:
++ case VK_Sparc_TLS_IE_HI22:
++ case VK_Sparc_TLS_IE_LO10:
++ case VK_Sparc_TLS_IE_LD:
++ case VK_Sparc_TLS_IE_LDX:
++ case VK_Sparc_TLS_IE_ADD:
++ case VK_Sparc_TLS_LE_HIX22:
++ case VK_Sparc_TLS_LE_LOX10: break;
++ }
++ fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
+ }
+
++// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps
++// that method should be made public?
++// FIXME: really do above: now that at least three other backends are using it.
++static void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) {
++ switch (Value->getKind()) {
++ case MCExpr::Target:
++ llvm_unreachable("Can't handle nested target expr!");
++ break;
++
++ case MCExpr::Constant:
++ break;
++
++ case MCExpr::Binary: {
++ const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
++ AddValueSymbolsImpl(BE->getLHS(), Asm);
++ AddValueSymbolsImpl(BE->getRHS(), Asm);
++ break;
++ }
++
++ case MCExpr::SymbolRef:
++ Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
++ break;
++
++ case MCExpr::Unary:
++ AddValueSymbolsImpl(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm);
++ break;
++ }
++}
++
+ void SparcMCExpr::AddValueSymbols(MCAssembler *Asm) const {
+- assert(0 && "FIXME: Implement SparcMCExpr::AddValueSymbols");
++ AddValueSymbolsImpl(getSubExpr(), Asm);
+ }
+Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
++++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
+@@ -1,5 +1,6 @@
+ add_llvm_library(LLVMSparcDesc
+ SparcAsmBackend.cpp
++ SparcELFObjectWriter.cpp
+ SparcMCAsmInfo.cpp
+ SparcMCCodeEmitter.cpp
+ SparcMCTargetDesc.cpp
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff
new file mode 100644
index 0000000..056cb34
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff
@@ -0,0 +1,762 @@
+Pull in r198591 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add initial implementation of disassembler for sparc
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcInstrFormats.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrFormats.td
++++ lib/Target/Sparc/SparcInstrFormats.td
+@@ -12,6 +12,7 @@ class InstSP<dag outs, dag ins, string asmstr, lis
+ field bits<32> Inst;
+
+ let Namespace = "SP";
++ let Size = 4;
+
+ bits<2> op;
+ let Inst{31-30} = op; // Top two bits are the 'op' field
+@@ -20,6 +21,9 @@ class InstSP<dag outs, dag ins, string asmstr, lis
+ dag InOperandList = ins;
+ let AsmString = asmstr;
+ let Pattern = pattern;
++
++ let DecoderNamespace = "Sparc";
++ field bits<32> SoftFail = 0;
+ }
+
+ //===----------------------------------------------------------------------===//
+@@ -58,6 +62,27 @@ class F2_2<bits<3> op2Val, dag outs, dag ins, stri
+ let Inst{28-25} = cond;
+ }
+
++class F2_3<bits<3> op2Val, bits<2> ccVal, dag outs, dag ins, string asmstr,
++ list<dag> pattern>
++ : InstSP<outs, ins, asmstr, pattern> {
++ bit annul;
++ bits<4> cond;
++ bit pred;
++ bits<19> imm19;
++
++ let op = 0; // op = 0
++
++ bit annul = 0; // currently unused
++ let pred = 1; // default is predict taken
++
++ let Inst{29} = annul;
++ let Inst{28-25} = cond;
++ let Inst{24-22} = op2Val;
++ let Inst{21-20} = ccVal;
++ let Inst{19} = pred;
++ let Inst{18-0} = imm19;
++}
++
+ //===----------------------------------------------------------------------===//
+ // Format #3 instruction classes in the Sparc
+ //===----------------------------------------------------------------------===//
+Index: lib/Target/Sparc/LLVMBuild.txt
+===================================================================
+--- lib/Target/Sparc/LLVMBuild.txt
++++ lib/Target/Sparc/LLVMBuild.txt
+@@ -16,13 +16,15 @@
+ ;===------------------------------------------------------------------------===;
+
+ [common]
+-subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
++subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
+
+ [component_0]
+ type = TargetGroup
+ name = Sparc
+ parent = Target
++has_asmparser = 1
+ has_asmprinter = 1
++has_disassembler = 1
+ has_jit = 1
+
+ [component_1]
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -230,13 +230,13 @@ def FCC_O : FCC_VAL<29>; // Ordered
+ multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode,
+ RegisterClass RC, ValueType Ty, Operand immOp> {
+ def rr : F3_1<2, Op3Val,
+- (outs RC:$dst), (ins RC:$b, RC:$c),
+- !strconcat(OpcStr, " $b, $c, $dst"),
+- [(set Ty:$dst, (OpNode Ty:$b, Ty:$c))]>;
++ (outs RC:$rd), (ins RC:$rs1, RC:$rs2),
++ !strconcat(OpcStr, " $rs1, $rs2, $rd"),
++ [(set Ty:$rd, (OpNode Ty:$rs1, Ty:$rs2))]>;
+ def ri : F3_2<2, Op3Val,
+- (outs RC:$dst), (ins RC:$b, immOp:$c),
+- !strconcat(OpcStr, " $b, $c, $dst"),
+- [(set Ty:$dst, (OpNode Ty:$b, (Ty simm13:$c)))]>;
++ (outs RC:$rd), (ins RC:$rs1, immOp:$simm13),
++ !strconcat(OpcStr, " $rs1, $simm13, $rd"),
++ [(set Ty:$rd, (OpNode Ty:$rs1, (Ty simm13:$simm13)))]>;
+ }
+
+ /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no
+@@ -243,11 +243,11 @@ multiclass F3_12<string OpcStr, bits<6> Op3Val, SD
+ /// pattern.
+ multiclass F3_12np<string OpcStr, bits<6> Op3Val> {
+ def rr : F3_1<2, Op3Val,
+- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
+- !strconcat(OpcStr, " $b, $c, $dst"), []>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
++ !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>;
+ def ri : F3_2<2, Op3Val,
+- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
+- !strconcat(OpcStr, " $b, $c, $dst"), []>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
++ !strconcat(OpcStr, " $rs1, $simm13, $rd"), []>;
+ }
+
+ //===----------------------------------------------------------------------===//
+@@ -488,31 +488,31 @@ let rd = 0, imm22 = 0 in
+ defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>;
+
+ def ANDNrr : F3_1<2, 0b000101,
+- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
+- "andn $b, $c, $dst",
+- [(set i32:$dst, (and i32:$b, (not i32:$c)))]>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
++ "andn $rs1, $rs2, $rd",
++ [(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>;
+ def ANDNri : F3_2<2, 0b000101,
+- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
+- "andn $b, $c, $dst", []>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
++ "andn $rs1, $simm13, $rd", []>;
+
+ defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>;
+
+ def ORNrr : F3_1<2, 0b000110,
+- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
+- "orn $b, $c, $dst",
+- [(set i32:$dst, (or i32:$b, (not i32:$c)))]>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
++ "orn $rs1, $rs2, $rd",
++ [(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>;
+ def ORNri : F3_2<2, 0b000110,
+- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
+- "orn $b, $c, $dst", []>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
++ "orn $rs1, $simm13, $rd", []>;
+ defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>;
+
+ def XNORrr : F3_1<2, 0b000111,
+- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
+- "xnor $b, $c, $dst",
+- [(set i32:$dst, (not (xor i32:$b, i32:$c)))]>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
++ "xnor $rs1, $rs2, $rd",
++ [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>;
+ def XNORri : F3_2<2, 0b000111,
+- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
+- "xnor $b, $c, $dst", []>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
++ "xnor $rs1, $simm13, $rd", []>;
+
+ // Section B.12 - Shift Instructions, p. 107
+ defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>;
+@@ -545,21 +545,15 @@ let Defs = [ICC] in
+
+ let Defs = [ICC], rd = 0 in {
+ def CMPrr : F3_1<2, 0b010100,
+- (outs), (ins IntRegs:$b, IntRegs:$c),
+- "cmp $b, $c",
+- [(SPcmpicc i32:$b, i32:$c)]>;
++ (outs), (ins IntRegs:$rs1, IntRegs:$rs2),
++ "cmp $rs1, $rs2",
++ [(SPcmpicc i32:$rs1, i32:$rs2)]>;
+ def CMPri : F3_2<2, 0b010100,
+- (outs), (ins IntRegs:$b, i32imm:$c),
+- "cmp $b, $c",
+- [(SPcmpicc i32:$b, (i32 simm13:$c))]>;
++ (outs), (ins IntRegs:$rs1, i32imm:$simm13),
++ "cmp $rs1, $simm13",
++ [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>;
+ }
+
+-let Uses = [ICC], Defs = [ICC] in
+- def SUBXCCrr: F3_1<2, 0b011100,
+- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
+- "subxcc $b, $c, $dst", []>;
+-
+-
+ // Section B.18 - Multiply Instructions, p. 113
+ let Defs = [Y] in {
+ defm UMUL : F3_12np<"umul", 0b001010>;
+@@ -858,7 +852,7 @@ let Defs = [FCC] in {
+ //===----------------------------------------------------------------------===//
+ // Instructions for Thread Local Storage(TLS).
+ //===----------------------------------------------------------------------===//
+-
++let isCodeGenOnly = 1, isAsmParserOnly = 1 in {
+ def TLS_ADDrr : F3_1<2, 0b000000,
+ (outs IntRegs:$rd),
+ (ins IntRegs:$rs1, IntRegs:$rs2, TLSSym:$sym),
+@@ -882,6 +876,7 @@ let Uses = [O6], isCall = 1, hasDelaySlot = 1 in
+ let op = 1;
+ let Inst{29-0} = disp;
+ }
++}
+
+ //===----------------------------------------------------------------------===//
+ // V9 Instructions
+Index: lib/Target/Sparc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/CMakeLists.txt
++++ lib/Target/Sparc/CMakeLists.txt
+@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td)
+ tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
+ tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
+ tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
++tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler)
+ tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter)
+ tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
+ tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
+@@ -34,3 +35,4 @@ add_subdirectory(TargetInfo)
+ add_subdirectory(MCTargetDesc)
+ add_subdirectory(InstPrinter)
+ add_subdirectory(AsmParser)
++add_subdirectory(Disassembler)
+Index: lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+===================================================================
+--- lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
++++ lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+@@ -0,0 +1,228 @@
++//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This file is part of the Sparc Disassembler.
++//
++//===----------------------------------------------------------------------===//
++
++#define DEBUG_TYPE "sparc-disassembler"
++
++#include "Sparc.h"
++#include "SparcRegisterInfo.h"
++#include "SparcSubtarget.h"
++#include "llvm/MC/MCDisassembler.h"
++#include "llvm/MC/MCFixedLenDisassembler.h"
++#include "llvm/Support/MemoryObject.h"
++#include "llvm/Support/TargetRegistry.h"
++
++using namespace llvm;
++
++typedef MCDisassembler::DecodeStatus DecodeStatus;
++
++namespace {
++
++/// SparcDisassembler - a disassembler class for Sparc.
++class SparcDisassembler : public MCDisassembler {
++public:
++ /// Constructor - Initializes the disassembler.
++ ///
++ SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) :
++ MCDisassembler(STI), RegInfo(Info)
++ {}
++ virtual ~SparcDisassembler() {}
++
++ const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
++
++ /// getInstruction - See MCDisassembler.
++ virtual DecodeStatus getInstruction(MCInst &instr,
++ uint64_t &size,
++ const MemoryObject &region,
++ uint64_t address,
++ raw_ostream &vStream,
++ raw_ostream &cStream) const;
++private:
++ OwningPtr<const MCRegisterInfo> RegInfo;
++};
++
++}
++
++namespace llvm {
++ extern Target TheSparcTarget, TheSparcV9Target;
++}
++
++static MCDisassembler *createSparcDisassembler(
++ const Target &T,
++ const MCSubtargetInfo &STI) {
++ return new SparcDisassembler(STI, T.createMCRegInfo(""));
++}
++
++
++extern "C" void LLVMInitializeSparcDisassembler() {
++ // Register the disassembler.
++ TargetRegistry::RegisterMCDisassembler(TheSparcTarget,
++ createSparcDisassembler);
++ TargetRegistry::RegisterMCDisassembler(TheSparcV9Target,
++ createSparcDisassembler);
++}
++
++
++
++static const unsigned IntRegDecoderTable[] = {
++ SP::G0, SP::G1, SP::G2, SP::G3,
++ SP::G4, SP::G5, SP::G6, SP::G7,
++ SP::O0, SP::O1, SP::O2, SP::O3,
++ SP::O4, SP::O5, SP::O6, SP::O7,
++ SP::L0, SP::L1, SP::L2, SP::L3,
++ SP::L4, SP::L5, SP::L6, SP::L7,
++ SP::I0, SP::I1, SP::I2, SP::I3,
++ SP::I4, SP::I5, SP::I6, SP::I7 };
++
++static const unsigned FPRegDecoderTable[] = {
++ SP::F0, SP::F1, SP::F2, SP::F3,
++ SP::F4, SP::F5, SP::F6, SP::F7,
++ SP::F8, SP::F9, SP::F10, SP::F11,
++ SP::F12, SP::F13, SP::F14, SP::F15,
++ SP::F16, SP::F17, SP::F18, SP::F19,
++ SP::F20, SP::F21, SP::F22, SP::F23,
++ SP::F24, SP::F25, SP::F26, SP::F27,
++ SP::F28, SP::F29, SP::F30, SP::F31 };
++
++static const unsigned DFPRegDecoderTable[] = {
++ SP::D0, SP::D16, SP::D1, SP::D17,
++ SP::D2, SP::D18, SP::D3, SP::D19,
++ SP::D4, SP::D20, SP::D5, SP::D21,
++ SP::D6, SP::D22, SP::D7, SP::D23,
++ SP::D8, SP::D24, SP::D9, SP::D25,
++ SP::D10, SP::D26, SP::D11, SP::D27,
++ SP::D12, SP::D28, SP::D13, SP::D29,
++ SP::D14, SP::D30, SP::D15, SP::D31 };
++
++static const unsigned QFPRegDecoderTable[] = {
++ SP::Q0, SP::Q8, -1, -1,
++ SP::Q1, SP::Q9, -1, -1,
++ SP::Q2, SP::Q10, -1, -1,
++ SP::Q3, SP::Q11, -1, -1,
++ SP::Q4, SP::Q12, -1, -1,
++ SP::Q5, SP::Q13, -1, -1,
++ SP::Q6, SP::Q14, -1, -1,
++ SP::Q7, SP::Q15, -1, -1 } ;
++
++static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
++ unsigned RegNo,
++ uint64_t Address,
++ const void *Decoder) {
++ if (RegNo > 31)
++ return MCDisassembler::Fail;
++ unsigned Reg = IntRegDecoderTable[RegNo];
++ Inst.addOperand(MCOperand::CreateReg(Reg));
++ return MCDisassembler::Success;
++}
++
++static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,
++ unsigned RegNo,
++ uint64_t Address,
++ const void *Decoder) {
++ if (RegNo > 31)
++ return MCDisassembler::Fail;
++ unsigned Reg = IntRegDecoderTable[RegNo];
++ Inst.addOperand(MCOperand::CreateReg(Reg));
++ return MCDisassembler::Success;
++}
++
++
++static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,
++ unsigned RegNo,
++ uint64_t Address,
++ const void *Decoder) {
++ if (RegNo > 31)
++ return MCDisassembler::Fail;
++ unsigned Reg = FPRegDecoderTable[RegNo];
++ Inst.addOperand(MCOperand::CreateReg(Reg));
++ return MCDisassembler::Success;
++}
++
++
++static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,
++ unsigned RegNo,
++ uint64_t Address,
++ const void *Decoder) {
++ if (RegNo > 31)
++ return MCDisassembler::Fail;
++ unsigned Reg = DFPRegDecoderTable[RegNo];
++ Inst.addOperand(MCOperand::CreateReg(Reg));
++ return MCDisassembler::Success;
++}
++
++
++static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
++ unsigned RegNo,
++ uint64_t Address,
++ const void *Decoder) {
++ if (RegNo > 31)
++ return MCDisassembler::Fail;
++
++ unsigned Reg = QFPRegDecoderTable[RegNo];
++ if (Reg == (unsigned)-1)
++ return MCDisassembler::Fail;
++ Inst.addOperand(MCOperand::CreateReg(Reg));
++ return MCDisassembler::Success;
++}
++
++
++#include "SparcGenDisassemblerTables.inc"
++
++/// readInstruction - read four bytes from the MemoryObject
++/// and return 32 bit word.
++static DecodeStatus readInstruction32(const MemoryObject &region,
++ uint64_t address,
++ uint64_t &size,
++ uint32_t &insn) {
++ uint8_t Bytes[4];
++
++ // We want to read exactly 4 Bytes of data.
++ if (region.readBytes(address, 4, Bytes) == -1) {
++ size = 0;
++ return MCDisassembler::Fail;
++ }
++
++ // Encoded as a big-endian 32-bit word in the stream.
++ insn = (Bytes[3] << 0) |
++ (Bytes[2] << 8) |
++ (Bytes[1] << 16) |
++ (Bytes[0] << 24);
++
++ return MCDisassembler::Success;
++}
++
++
++DecodeStatus
++SparcDisassembler::getInstruction(MCInst &instr,
++ uint64_t &Size,
++ const MemoryObject &Region,
++ uint64_t Address,
++ raw_ostream &vStream,
++ raw_ostream &cStream) const {
++ uint32_t Insn;
++
++ DecodeStatus Result = readInstruction32(Region, Address, Size, Insn);
++ if (Result == MCDisassembler::Fail)
++ return MCDisassembler::Fail;
++
++
++ // Calling the auto-generated decoder function.
++ Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address,
++ this, STI);
++
++ if (Result != MCDisassembler::Fail) {
++ Size = 4;
++ return Result;
++ }
++
++ return MCDisassembler::Fail;
++}
+Index: lib/Target/Sparc/Disassembler/LLVMBuild.txt
+===================================================================
+--- lib/Target/Sparc/Disassembler/LLVMBuild.txt
++++ lib/Target/Sparc/Disassembler/LLVMBuild.txt
+@@ -0,0 +1,23 @@
++;===- ./lib/Target/Sparc/Disassembler/LLVMBuild.txt ------------*- Conf -*--===;
++;
++; The LLVM Compiler Infrastructure
++;
++; This file is distributed under the University of Illinois Open Source
++; License. See LICENSE.TXT for details.
++;
++;===------------------------------------------------------------------------===;
++;
++; This is an LLVMBuild description file for the components in this subdirectory.
++;
++; For more information on the LLVMBuild system, please see:
++;
++; http://llvm.org/docs/LLVMBuild.html
++;
++;===------------------------------------------------------------------------===;
++
++[component_0]
++type = Library
++name = SparcDisassembler
++parent = Sparc
++required_libraries = MC Support SparcInfo
++add_to_library_groups = Sparc
+Index: lib/Target/Sparc/Disassembler/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/Disassembler/CMakeLists.txt
++++ lib/Target/Sparc/Disassembler/CMakeLists.txt
+@@ -0,0 +1,12 @@
++add_llvm_library(LLVMSparcDisassembler
++ SparcDisassembler.cpp
++ )
++
++# workaround for hanging compilation on MSVC9 and 10
++if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500
++ OR MSVC_VERSION EQUAL 1600 )
++set_property(
++ SOURCE SparcDisassembler.cpp
++ PROPERTY COMPILE_FLAGS "/Od"
++ )
++endif()
+Index: lib/Target/Sparc/Disassembler/Makefile
+===================================================================
+--- lib/Target/Sparc/Disassembler/Makefile
++++ lib/Target/Sparc/Disassembler/Makefile
+@@ -0,0 +1,16 @@
++##===- lib/Target/Sparc/Disassembler/Makefile --------------*- Makefile -*-===##
++#
++# The LLVM Compiler Infrastructure
++#
++# This file is distributed under the University of Illinois Open Source
++# License. See LICENSE.TXT for details.
++#
++##===----------------------------------------------------------------------===##
++
++LEVEL = ../../../..
++LIBRARYNAME = LLVMSparcDisassembler
++
++# Hack: we need to include 'main' Sparc target directory to grab private headers
++CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
++
++include $(LEVEL)/Makefile.common
+Index: lib/Target/Sparc/Makefile
+===================================================================
+--- lib/Target/Sparc/Makefile
++++ lib/Target/Sparc/Makefile
+@@ -14,11 +14,11 @@ TARGET = Sparc
+ # Make sure that tblgen is run, first thing.
+ BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
+ SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
+- SparcGenDAGISel.inc \
++ SparcGenDAGISel.inc SparcGenDisassemblerTables.inc \
+ SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
+ SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc
+
+-DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
++DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
+
+ include $(LEVEL)/Makefile.common
+
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -141,6 +141,7 @@ def : Pat<(i64 imm:$val),
+ let Predicates = [Is64Bit] in {
+
+ // Register-register instructions.
++let isCodeGenOnly = 1 in {
+ defm ANDX : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>;
+ defm ORX : F3_12<"or", 0b000010, or, I64Regs, i64, i64imm>;
+ defm XORX : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>;
+@@ -161,8 +162,6 @@ def XNORXrr : F3_1<2, 0b000111,
+ defm ADDX : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>;
+ defm SUBX : F3_12<"sub", 0b000100, sub, I64Regs, i64, i64imm>;
+
+-def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>;
+-
+ def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd),
+ (ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym),
+ "add $rs1, $rs2, $rd, $sym",
+@@ -169,18 +168,17 @@ def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$
+ [(set i64:$rd,
+ (tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>;
+
+-// Register-immediate instructions.
+-
+-def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>;
+-
+-def : Pat<(ctpop i64:$src), (POPCrr $src)>;
+-
+ // "LEA" form of add
+-let isCodeGenOnly = 1 in
+ def LEAX_ADDri : F3_2<2, 0b000000,
+ (outs I64Regs:$dst), (ins MEMri:$addr),
+ "add ${addr:arith}, $dst",
+ [(set iPTR:$dst, ADDRri:$addr)]>;
++}
++
++def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>;
++def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>;
++def : Pat<(ctpop i64:$src), (POPCrr $src)>;
++
+ } // Predicates = [Is64Bit]
+
+
+@@ -245,7 +243,7 @@ def LDXri : F3_2<3, 0b001011,
+ (outs I64Regs:$dst), (ins MEMri:$addr),
+ "ldx [$addr], $dst",
+ [(set i64:$dst, (load ADDRri:$addr))]>;
+-let mayLoad = 1 in
++let mayLoad = 1, isCodeGenOnly = 1, isAsmParserOnly = 1 in
+ def TLS_LDXrr : F3_1<3, 0b001011,
+ (outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym),
+ "ldx [$addr], $dst, $sym",
+@@ -278,11 +276,11 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr
+ def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>;
+
+ // Sign-extending load of i32 into i64 is a new SPARC v9 instruction.
+-def LDSWrr : F3_1<3, 0b001011,
++def LDSWrr : F3_1<3, 0b001000,
+ (outs I64Regs:$dst), (ins MEMrr:$addr),
+ "ldsw [$addr], $dst",
+ [(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>;
+-def LDSWri : F3_2<3, 0b001011,
++def LDSWri : F3_2<3, 0b001000,
+ (outs I64Regs:$dst), (ins MEMri:$addr),
+ "ldsw [$addr], $dst",
+ [(set i64:$dst, (sextloadi32 ADDRri:$addr))]>;
+@@ -289,13 +287,13 @@ def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri
+
+ // 64-bit stores.
+ def STXrr : F3_1<3, 0b001110,
+- (outs), (ins MEMrr:$addr, I64Regs:$src),
+- "stx $src, [$addr]",
+- [(store i64:$src, ADDRrr:$addr)]>;
++ (outs), (ins MEMrr:$addr, I64Regs:$rd),
++ "stx $rd, [$addr]",
++ [(store i64:$rd, ADDRrr:$addr)]>;
+ def STXri : F3_2<3, 0b001110,
+- (outs), (ins MEMri:$addr, I64Regs:$src),
+- "stx $src, [$addr]",
+- [(store i64:$src, ADDRri:$addr)]>;
++ (outs), (ins MEMri:$addr, I64Regs:$rd),
++ "stx $rd, [$addr]",
++ [(store i64:$rd, ADDRri:$addr)]>;
+
+ // Truncating stores from i64 are identical to the i32 stores.
+ def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>;
+@@ -315,6 +313,15 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADD
+ //===----------------------------------------------------------------------===//
+ // 64-bit Conditionals.
+ //===----------------------------------------------------------------------===//
++
++// Conditional branch class on %xcc:
++class XBranchSP<dag ins, string asmstr, list<dag> pattern>
++ : F2_3<0b001, 0b10, (outs), ins, asmstr, pattern> {
++ let isBranch = 1;
++ let isTerminator = 1;
++ let hasDelaySlot = 1;
++}
++
+ //
+ // Flag-setting instructions like subcc and addcc set both icc and xcc flags.
+ // The icc flags correspond to the 32-bit result, and the xcc are for the
+@@ -326,7 +333,7 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADD
+ let Predicates = [Is64Bit] in {
+
+ let Uses = [ICC] in
+-def BPXCC : BranchSP<(ins brtarget:$imm22, CCOp:$cond),
++def BPXCC : XBranchSP<(ins brtarget:$imm22, CCOp:$cond),
+ "b$cond %xcc, $imm22",
+ [(SPbrxcc bb:$imm22, imm:$cond)]>;
+
+@@ -409,7 +416,7 @@ def : Pat<(SPselectfcc (i64 simm11:$t), i64:$f, im
+
+
+ // 64 bit SETHI
+-let Predicates = [Is64Bit] in {
++let Predicates = [Is64Bit], isCodeGenOnly = 1 in {
+ def SETHIXi : F2_1<0b100,
+ (outs IntRegs:$rd), (ins i64imm:$imm22),
+ "sethi $imm22, $rd",
+Index: test/MC/Disassembler/Sparc/lit.local.cfg
+===================================================================
+--- test/MC/Disassembler/Sparc/lit.local.cfg
++++ test/MC/Disassembler/Sparc/lit.local.cfg
+@@ -0,0 +1,4 @@
++targets = set(config.root.targets_to_build.split())
++if not 'Sparc' in targets:
++ config.unsupported = True
++
+Index: test/MC/Disassembler/Sparc/sparc.txt
+===================================================================
+--- test/MC/Disassembler/Sparc/sparc.txt
++++ test/MC/Disassembler/Sparc/sparc.txt
+@@ -0,0 +1,82 @@
++# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux | FileCheck %s
++
++# CHECK: add %g0, %g0, %g0
++0x80 0x00 0x00 0x00
++
++# CHECK: add %g1, %g2, %g3
++0x86 0x00 0x40 0x02
++
++# CHECK: add %o0, %o1, %l0
++0xa0 0x02 0x00 0x09
++
++# CHECK: add %o0, 10, %l0
++0xa0 0x02 0x20 0x0a
++
++# CHECK: addcc %g1, %g2, %g3
++0x86 0x80 0x40 0x02
++
++# CHECK: addxcc %g1, %g2, %g3
++0x86 0xc0 0x40 0x02
++
++# CHECK: udiv %g1, %g2, %g3
++0x86 0x70 0x40 0x02
++
++# CHECK: sdiv %g1, %g2, %g3
++0x86 0x78 0x40 0x02
++
++# CHECK: and %g1, %g2, %g3
++0x86 0x08 0x40 0x02
++
++# CHECK: andn %g1, %g2, %g3
++0x86 0x28 0x40 0x02
++
++# CHECK: or %g1, %g2, %g3
++0x86 0x10 0x40 0x02
++
++# CHECK: orn %g1, %g2, %g3
++0x86 0x30 0x40 0x02
++
++# CHECK: xor %g1, %g2, %g3
++0x86 0x18 0x40 0x02
++
++# CHECK: xnor %g1, %g2, %g3
++0x86 0x38 0x40 0x02
++
++# CHECK: umul %g1, %g2, %g3
++0x86 0x50 0x40 0x02
++
++# CHECK: smul %g1, %g2, %g3
++0x86 0x58 0x40 0x02
++
++# CHECK: nop
++0x01 0x00 0x00 0x00
++
++# CHECK: sethi 10, %l0
++0x21 0x00 0x00 0x0a
++
++# CHECK: sll %g1, %g2, %g3
++0x87 0x28 0x40 0x02
++
++# CHECK: sll %g1, 31, %g3
++0x87 0x28 0x60 0x1f
++
++# CHECK: srl %g1, %g2, %g3
++0x87 0x30 0x40 0x02
++
++# CHECK: srl %g1, 31, %g3
++0x87 0x30 0x60 0x1f
++
++# CHECK: sra %g1, %g2, %g3
++0x87 0x38 0x40 0x02
++
++# CHECK: sra %g1, 31, %g3
++0x87 0x38 0x60 0x1f
++
++# CHECK: sub %g1, %g2, %g3
++0x86 0x20 0x40 0x02
++
++# CHECK: subcc %g1, %g2, %g3
++0x86 0xa0 0x40 0x02
++
++# CHECK: subxcc %g1, %g2, %g3
++0x86 0xe0 0x40 0x02
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198592-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198592-sparc.diff
new file mode 100644
index 0000000..722290e
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198592-sparc.diff
@@ -0,0 +1,33 @@
+Pull in r198592 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Explicitly cast -1 to unsigned to fix buildbot errors.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+===================================================================
+--- lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
++++ lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+@@ -104,14 +104,14 @@ static const unsigned DFPRegDecoderTable[] = {
+ SP::D14, SP::D30, SP::D15, SP::D31 };
+
+ static const unsigned QFPRegDecoderTable[] = {
+- SP::Q0, SP::Q8, -1, -1,
+- SP::Q1, SP::Q9, -1, -1,
+- SP::Q2, SP::Q10, -1, -1,
+- SP::Q3, SP::Q11, -1, -1,
+- SP::Q4, SP::Q12, -1, -1,
+- SP::Q5, SP::Q13, -1, -1,
+- SP::Q6, SP::Q14, -1, -1,
+- SP::Q7, SP::Q15, -1, -1 } ;
++ SP::Q0, SP::Q8, (unsigned)-1, (unsigned)-1,
++ SP::Q1, SP::Q9, (unsigned)-1, (unsigned)-1,
++ SP::Q2, SP::Q10, (unsigned)-1, (unsigned)-1,
++ SP::Q3, SP::Q11, (unsigned)-1, (unsigned)-1,
++ SP::Q4, SP::Q12, (unsigned)-1, (unsigned)-1,
++ SP::Q5, SP::Q13, (unsigned)-1, (unsigned)-1,
++ SP::Q6, SP::Q14, (unsigned)-1, (unsigned)-1,
++ SP::Q7, SP::Q15, (unsigned)-1, (unsigned)-1 } ;
+
+ static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
+ unsigned RegNo,
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff
new file mode 100644
index 0000000..b7eb2a2
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff
@@ -0,0 +1,359 @@
+Pull in r198658 from upstream llvm trunk:
+
+ [Sparc] Add support for parsing memory operands in sparc AsmParser.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/MC/Sparc/sparc-ctrl-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-ctrl-instructions.s
++++ test/MC/Sparc/sparc-ctrl-instructions.s
+@@ -0,0 +1,23 @@
++! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
++
++ ! CHECK: call foo
++ call foo
++
++ ! CHECK: call %g1+%i2
++ call %g1 + %i2
++
++ ! CHECK: call %o1+8
++ call %o1 + 8
++
++ ! CHECK: call %g1
++ call %g1
++
++ ! CHECK: jmp %g1+%i2
++ jmp %g1 + %i2
++
++ ! CHECK: jmp %o1+8
++ jmp %o1 + 8
++
++ ! CHECK: jmp %g1
++ jmp %g1
+Index: test/MC/Sparc/sparc-mem-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-mem-instructions.s
++++ test/MC/Sparc/sparc-mem-instructions.s
+@@ -0,0 +1,58 @@
++! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
++
++ ! CHECK: ldsb [%i0+%l6], %o2 ! encoding: [0xd4,0x4e,0x00,0x16]
++ ldsb [%i0 + %l6], %o2
++ ! CHECK: ldsb [%i0+32], %o2 ! encoding: [0xd4,0x4e,0x20,0x20]
++ ldsb [%i0 + 32], %o2
++ ! CHECK: ldsb [%g1], %o4 ! encoding: [0xd8,0x48,0x60,0x00]
++ ldsb [%g1], %o4
++
++ ! CHECK: ldsh [%i0+%l6], %o2 ! encoding: [0xd4,0x56,0x00,0x16]
++ ldsh [%i0 + %l6], %o2
++ ! CHECK: ldsh [%i0+32], %o2 ! encoding: [0xd4,0x56,0x20,0x20]
++ ldsh [%i0 + 32], %o2
++ ! CHECK: ldsh [%g1], %o4 ! encoding: [0xd8,0x50,0x60,0x00]
++ ldsh [%g1], %o4
++
++ ! CHECK: ldub [%i0+%l6], %o2 ! encoding: [0xd4,0x0e,0x00,0x16]
++ ldub [%i0 + %l6], %o2
++ ! CHECK: ldub [%i0+32], %o2 ! encoding: [0xd4,0x0e,0x20,0x20]
++ ldub [%i0 + 32], %o2
++ ! CHECK: ldub [%g1], %o2 ! encoding: [0xd4,0x08,0x60,0x00]
++ ldub [%g1], %o2
++
++ ! CHECK: lduh [%i0+%l6], %o2 ! encoding: [0xd4,0x16,0x00,0x16]
++ lduh [%i0 + %l6], %o2
++ ! CHECK: lduh [%i0+32], %o2 ! encoding: [0xd4,0x16,0x20,0x20]
++ lduh [%i0 + 32], %o2
++ ! CHECK: lduh [%g1], %o2 ! encoding: [0xd4,0x10,0x60,0x00]
++ lduh [%g1], %o2
++
++ ! CHECK: ld [%i0+%l6], %o2 ! encoding: [0xd4,0x06,0x00,0x16]
++ ld [%i0 + %l6], %o2
++ ! CHECK: ld [%i0+32], %o2 ! encoding: [0xd4,0x06,0x20,0x20]
++ ld [%i0 + 32], %o2
++ ! CHECK: ld [%g1], %o2 ! encoding: [0xd4,0x00,0x60,0x00]
++ ld [%g1], %o2
++
++ ! CHECK: stb %o2, [%i0+%l6] ! encoding: [0xd4,0x2e,0x00,0x16]
++ stb %o2, [%i0 + %l6]
++ ! CHECK: stb %o2, [%i0+32] ! encoding: [0xd4,0x2e,0x20,0x20]
++ stb %o2, [%i0 + 32]
++ ! CHECK: stb %o2, [%g1] ! encoding: [0xd4,0x28,0x60,0x00]
++ stb %o2, [%g1]
++
++ ! CHECK: sth %o2, [%i0+%l6] ! encoding: [0xd4,0x36,0x00,0x16]
++ sth %o2, [%i0 + %l6]
++ ! CHECK: sth %o2, [%i0+32] ! encoding: [0xd4,0x36,0x20,0x20]
++ sth %o2, [%i0 + 32]
++ ! CHECK: sth %o2, [%g1] ! encoding: [0xd4,0x30,0x60,0x00]
++ sth %o2, [%g1]
++
++ ! CHECK: st %o2, [%i0+%l6] ! encoding: [0xd4,0x26,0x00,0x16]
++ st %o2, [%i0 + %l6]
++ ! CHECK: st %o2, [%i0+32] ! encoding: [0xd4,0x26,0x20,0x20]
++ st %o2, [%i0 + 32]
++ ! CHECK: st %o2, [%g1] ! encoding: [0xd4,0x20,0x60,0x00]
++ st %o2, [%g1]
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -28,6 +28,7 @@ namespace llvm {
+ }
+
+ namespace {
++class SparcOperand;
+ class SparcAsmParser : public MCTargetAsmParser {
+
+ MCSubtargetInfo &STI;
+@@ -55,18 +56,15 @@ class SparcAsmParser : public MCTargetAsmParser {
+
+ // Custom parse functions for Sparc specific operands.
+ OperandMatchResultTy
+- parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+- OperandMatchResultTy
+- parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
++ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ OperandMatchResultTy
+- parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+- int ImmOffsetOrReg);
+-
+- OperandMatchResultTy
+ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ StringRef Name);
+
++ OperandMatchResultTy
++ parseSparcAsmOperand(SparcOperand *&Operand);
++
+ // returns true if Tok is matched to a register and returns register in RegNo.
+ bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
+ bool isQFP);
+@@ -298,7 +296,35 @@ class SparcOperand : public MCParsedAsmOperand {
+ return Op;
+ }
+
++ static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
++ unsigned offsetReg = Op->getReg();
++ Op->Kind = k_MemoryReg;
++ Op->Mem.Base = Base;
++ Op->Mem.OffsetReg = offsetReg;
++ Op->Mem.Off = 0;
++ return Op;
++ }
+
++ static SparcOperand *CreateMEMri(unsigned Base,
++ const MCExpr *Off,
++ SMLoc S, SMLoc E) {
++ SparcOperand *Op = new SparcOperand(k_MemoryImm);
++ Op->Mem.Base = Base;
++ Op->Mem.OffsetReg = 0;
++ Op->Mem.Off = Off;
++ Op->StartLoc = S;
++ Op->EndLoc = E;
++ return Op;
++ }
++
++ static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) {
++ const MCExpr *Imm = Op->getImm();
++ Op->Kind = k_MemoryImm;
++ Op->Mem.Base = Base;
++ Op->Mem.OffsetReg = 0;
++ Op->Mem.Off = Imm;
++ return Op;
++ }
+ };
+
+ } // end namespace
+@@ -412,23 +438,42 @@ ParseDirective(AsmToken DirectiveID)
+ }
+
+ SparcAsmParser::OperandMatchResultTy SparcAsmParser::
+-parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+- int ImmOffsetOrReg)
++parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
+ {
+- // FIXME: Implement memory operand parsing here.
+- return MatchOperand_NoMatch;
+-}
+
+-SparcAsmParser::OperandMatchResultTy SparcAsmParser::
+-parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
+-{
+- return parseMEMOperand(Operands, 2);
+-}
++ SMLoc S, E;
++ unsigned BaseReg = 0;
+
+-SparcAsmParser::OperandMatchResultTy SparcAsmParser::
+-parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
+-{
+- return parseMEMOperand(Operands, 1);
++ if (ParseRegister(BaseReg, S, E)) {
++ return MatchOperand_NoMatch;
++ }
++
++ switch (getLexer().getKind()) {
++ default: return MatchOperand_NoMatch;
++
++ case AsmToken::RBrac:
++ case AsmToken::EndOfStatement:
++ Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
++ return MatchOperand_Success;
++
++ case AsmToken:: Plus:
++ Parser.Lex(); // Eat the '+'
++ break;
++ case AsmToken::Minus:
++ break;
++ }
++
++ SparcOperand *Offset = 0;
++ OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
++ if (ResTy != MatchOperand_Success || !Offset)
++ return MatchOperand_NoMatch;
++
++ Offset = (Offset->isImm()
++ ? SparcOperand::MorphToMEMri(BaseReg, Offset)
++ : SparcOperand::MorphToMEMrr(BaseReg, Offset));
++
++ Operands.push_back(Offset);
++ return MatchOperand_Success;
+ }
+
+ SparcAsmParser::OperandMatchResultTy SparcAsmParser::
+@@ -435,20 +480,57 @@ SparcAsmParser::OperandMatchResultTy SparcAsmParse
+ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ StringRef Mnemonic)
+ {
++
+ OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
+- if (ResTy == MatchOperand_Success)
+- return ResTy;
++
+ // If there wasn't a custom match, try the generic matcher below. Otherwise,
+ // there was a match, but an error occurred, in which case, just return that
+ // the operand parsing failed.
+- if (ResTy == MatchOperand_ParseFail)
++ if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
+ return ResTy;
+
++ if (getLexer().is(AsmToken::LBrac)) {
++ // Memory operand
++ Operands.push_back(SparcOperand::CreateToken("[",
++ Parser.getTok().getLoc()));
++ Parser.Lex(); // Eat the [
++
++ ResTy = parseMEMOperand(Operands);
++ if (ResTy != MatchOperand_Success)
++ return ResTy;
++
++ if (!getLexer().is(AsmToken::RBrac))
++ return MatchOperand_ParseFail;
++
++ Operands.push_back(SparcOperand::CreateToken("]",
++ Parser.getTok().getLoc()));
++ Parser.Lex(); // Eat the ]
++ return MatchOperand_Success;
++ }
++
++ SparcOperand *Op = 0;
++ ResTy = parseSparcAsmOperand(Op);
++ if (ResTy != MatchOperand_Success || !Op)
++ return MatchOperand_ParseFail;
++
++ // Push the parsed operand into the list of operands
++ Operands.push_back(Op);
++
++ return MatchOperand_Success;
++}
++
++SparcAsmParser::OperandMatchResultTy
++SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
++{
++
+ SMLoc S = Parser.getTok().getLoc();
+ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ const MCExpr *EVal;
+- SparcOperand *Op;
++
++ Op = 0;
+ switch (getLexer().getKind()) {
++ default: break;
++
+ case AsmToken::Percent:
+ Parser.Lex(); // Eat the '%'.
+ unsigned RegNo;
+@@ -458,40 +540,30 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*>
+ break;
+ }
+ // FIXME: Handle modifiers like %hi, %lo etc.,
+- return MatchOperand_ParseFail;
++ break;
+
+ case AsmToken::Minus:
+ case AsmToken::Integer:
+- if (getParser().parseExpression(EVal))
+- return MatchOperand_ParseFail;
+-
+- Op = SparcOperand::CreateImm(EVal, S, E);
++ if (!getParser().parseExpression(EVal))
++ Op = SparcOperand::CreateImm(EVal, S, E);
+ break;
+
+ case AsmToken::Identifier: {
+ StringRef Identifier;
+- if (getParser().parseIdentifier(Identifier))
+- return MatchOperand_ParseFail;
+- SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+- MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
++ if (!getParser().parseIdentifier(Identifier)) {
++ SMLoc E = SMLoc::getFromPointer(Parser.getTok().
++ getLoc().getPointer() - 1);
++ MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
+
+- // Otherwise create a symbol reference.
+- const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
+- getContext());
++ const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
++ getContext());
+
+- Op = SparcOperand::CreateImm(Res, S, E);
++ Op = SparcOperand::CreateImm(Res, S, E);
++ }
+ break;
+ }
+-
+- case AsmToken::LBrac: // handle [
+- return parseMEMOperand(Operands, 0);
+-
+- default:
+- return MatchOperand_ParseFail;
+ }
+- // Push the parsed operand into the list of operands
+- Operands.push_back(Op);
+- return MatchOperand_Success;
++ return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
+ }
+
+ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -78,12 +78,12 @@ def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri
+ // Address operands
+ def SparcMEMrrAsmOperand : AsmOperandClass {
+ let Name = "MEMrr";
+- let ParserMethod = "parseMEMrrOperand";
++ let ParserMethod = "parseMEMOperand";
+ }
+
+ def SparcMEMriAsmOperand : AsmOperandClass {
+ let Name = "MEMri";
+- let ParserMethod = "parseMEMriOperand";
++ let ParserMethod = "parseMEMOperand";
+ }
+
+ def MEMrr : Operand<iPTR> {
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198681-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198681-sparc.diff
new file mode 100644
index 0000000..4bd12d2
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198681-sparc.diff
@@ -0,0 +1,298 @@
+Pull in r198681 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add support for parsing sparc asm modifiers such as %hi, %lo etc.,
+ Also, correct the offsets for FixupsKindInfo.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+@@ -27,11 +27,11 @@ static unsigned adjustFixupValue(unsigned Kind, ui
+ case FK_Data_8:
+ return Value;
+ case Sparc::fixup_sparc_call30:
+- return Value & 0x3fffffff;
++ return (Value >> 2) & 0x3fffffff;
+ case Sparc::fixup_sparc_br22:
+- return Value & 0x3fffff;
++ return (Value >> 2) & 0x3fffff;
+ case Sparc::fixup_sparc_br19:
+- return Value & 0x1ffff;
++ return (Value >> 2) & 0x1ffff;
+ case Sparc::fixup_sparc_hi22:
+ return (Value >> 10) & 0x3fffff;
+ case Sparc::fixup_sparc_lo10:
+@@ -45,7 +45,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui
+ case Sparc::fixup_sparc_hh:
+ return (Value >> 42) & 0x3fffff;
+ case Sparc::fixup_sparc_hm:
+- return (Value >>32) & 0x3ff;
++ return (Value >> 32) & 0x3ff;
+ }
+ }
+
+@@ -62,16 +62,16 @@ namespace {
+ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
+ const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = {
+ // name offset bits flags
+- { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
+- { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
+- { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
+- { "fixup_sparc_hi22", 0, 22, 0 },
+- { "fixup_sparc_lo10", 0, 10, 0 },
+- { "fixup_sparc_h44", 0, 22, 0 },
+- { "fixup_sparc_m44", 0, 10, 0 },
+- { "fixup_sparc_l44", 0, 12, 0 },
+- { "fixup_sparc_hh", 0, 21, 0 },
+- { "fixup_sparc_hm", 0, 10, 0 },
++ { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_hi22", 10, 22, 0 },
++ { "fixup_sparc_lo10", 22, 10, 0 },
++ { "fixup_sparc_h44", 10, 22, 0 },
++ { "fixup_sparc_m44", 22, 10, 0 },
++ { "fixup_sparc_l44", 20, 12, 0 },
++ { "fixup_sparc_hh", 10, 22, 0 },
++ { "fixup_sparc_hm", 22, 10, 0 },
+ };
+
+ if (Kind < FirstTargetFixupKind)
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+@@ -67,6 +67,37 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
+ OS << ')';
+ }
+
++SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
++{
++ return StringSwitch<SparcMCExpr::VariantKind>(name)
++ .Case("lo", VK_Sparc_LO)
++ .Case("hi", VK_Sparc_HI)
++ .Case("h44", VK_Sparc_H44)
++ .Case("m44", VK_Sparc_M44)
++ .Case("l44", VK_Sparc_L44)
++ .Case("hh", VK_Sparc_HH)
++ .Case("hm", VK_Sparc_HM)
++ .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
++ .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
++ .Case("tgd_add", VK_Sparc_TLS_GD_ADD)
++ .Case("tgd_call", VK_Sparc_TLS_GD_CALL)
++ .Case("tldm_hi22", VK_Sparc_TLS_LDM_HI22)
++ .Case("tldm_lo10", VK_Sparc_TLS_LDM_LO10)
++ .Case("tldm_add", VK_Sparc_TLS_LDM_ADD)
++ .Case("tldm_call", VK_Sparc_TLS_LDM_CALL)
++ .Case("tldo_hix22", VK_Sparc_TLS_LDO_HIX22)
++ .Case("tldo_lox10", VK_Sparc_TLS_LDO_LOX10)
++ .Case("tldo_add", VK_Sparc_TLS_LDO_ADD)
++ .Case("tie_hi22", VK_Sparc_TLS_IE_HI22)
++ .Case("tie_lo10", VK_Sparc_TLS_IE_LO10)
++ .Case("tie_ld", VK_Sparc_TLS_IE_LD)
++ .Case("tie_ldx", VK_Sparc_TLS_IE_LDX)
++ .Case("tie_add", VK_Sparc_TLS_IE_ADD)
++ .Case("tle_hix22", VK_Sparc_TLS_LE_HIX22)
++ .Case("tle_lox10", VK_Sparc_TLS_LE_LOX10)
++ .Default(VK_Sparc_None);
++}
++
+ bool
+ SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
+ const MCAsmLayout *Layout) const {
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+@@ -19,6 +19,7 @@
+
+ namespace llvm {
+
++class StringRef;
+ class SparcMCExpr : public MCTargetExpr {
+ public:
+ enum VariantKind {
+@@ -90,6 +91,7 @@ class SparcMCExpr : public MCTargetExpr {
+
+ static bool classof(const SparcMCExpr *) { return true; }
+
++ static VariantKind parseVariantKind(StringRef name);
+
+ };
+
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -8,6 +8,7 @@
+ //===----------------------------------------------------------------------===//
+
+ #include "MCTargetDesc/SparcMCTargetDesc.h"
++#include "MCTargetDesc/SparcMCExpr.h"
+ #include "llvm/ADT/STLExtras.h"
+ #include "llvm/MC/MCContext.h"
+ #include "llvm/MC/MCInst.h"
+@@ -68,6 +69,7 @@ class SparcAsmParser : public MCTargetAsmParser {
+ // returns true if Tok is matched to a register and returns register in RegNo.
+ bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
+ bool isQFP);
++ bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
+
+ public:
+ SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
+@@ -536,15 +538,19 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
+ unsigned RegNo;
+ if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
+ Parser.Lex(); // Eat the identifier token.
++ E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
+ break;
+ }
+- // FIXME: Handle modifiers like %hi, %lo etc.,
++ if (matchSparcAsmModifiers(EVal, E)) {
++ E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
++ Op = SparcOperand::CreateImm(EVal, S, E);
++ }
+ break;
+
+ case AsmToken::Minus:
+ case AsmToken::Integer:
+- if (!getParser().parseExpression(EVal))
++ if (!getParser().parseExpression(EVal, E))
+ Op = SparcOperand::CreateImm(EVal, S, E);
+ break;
+
+@@ -551,13 +557,11 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
+ case AsmToken::Identifier: {
+ StringRef Identifier;
+ if (!getParser().parseIdentifier(Identifier)) {
+- SMLoc E = SMLoc::getFromPointer(Parser.getTok().
+- getLoc().getPointer() - 1);
++ E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
+
+ const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
+ getContext());
+-
+ Op = SparcOperand::CreateImm(Res, S, E);
+ }
+ break;
+@@ -675,7 +679,33 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ }
+
+
++bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
++ SMLoc &EndLoc)
++{
++ AsmToken Tok = Parser.getTok();
++ if (!Tok.is(AsmToken::Identifier))
++ return false;
+
++ StringRef name = Tok.getString();
++
++ SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
++
++ if (VK == SparcMCExpr::VK_Sparc_None)
++ return false;
++
++ Parser.Lex(); // Eat the identifier.
++ if (Parser.getTok().getKind() != AsmToken::LParen)
++ return false;
++
++ Parser.Lex(); // Eat the LParen token.
++ const MCExpr *subExpr;
++ if (Parser.parseParenExpression(subExpr, EndLoc))
++ return false;
++ EVal = SparcMCExpr::Create(VK, subExpr, getContext());
++ return true;
++}
++
++
+ extern "C" void LLVMInitializeSparcAsmParser() {
+ RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
+ RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
+Index: test/MC/Sparc/sparc-relocations.s
+===================================================================
+--- test/MC/Sparc/sparc-relocations.s
++++ test/MC/Sparc/sparc-relocations.s
+@@ -0,0 +1,33 @@
++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
++
++ ! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
++ ! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
++ call foo
++
++ ! CHECK: or %g1, %lo(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
++ ! CHECK-NEXT ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
++ or %g1, %lo(sym), %g3
++
++ ! CHECK: sethi %hi(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: %hi(sym), kind: fixup_sparc_hi22
++ sethi %hi(sym), %l0
++
++ ! CHECK: sethi %h44(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: %h44(sym), kind: fixup_sparc_h44
++ sethi %h44(sym), %l0
++
++ ! CHECK: or %g1, %m44(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
++ ! CHECK-NEXT ! fixup A - offset: 0, value: %m44(sym), kind: fixup_sparc_m44
++ or %g1, %m44(sym), %g3
++
++ ! CHECK: or %g1, %l44(sym), %g3 ! encoding: [0x86,0x10,0b0110AAAA,A]
++ ! CHECK-NEXT ! fixup A - offset: 0, value: %l44(sym), kind: fixup_sparc_l44
++ or %g1, %l44(sym), %g3
++
++ ! CHECK: sethi %hh(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: %hh(sym), kind: fixup_sparc_hh
++ sethi %hh(sym), %l0
++
++ ! CHECK: or %g1, %hm(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
++ ! CHECK-NEXT ! fixup A - offset: 0, value: %hm(sym), kind: fixup_sparc_hm
++ or %g1, %hm(sym), %g3
+Index: test/MC/Sparc/sparc-ctrl-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-ctrl-instructions.s
++++ test/MC/Sparc/sparc-ctrl-instructions.s
+@@ -1,23 +1,33 @@
+ ! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
+ ! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
+
+- ! CHECK: call foo
++ ! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
++ ! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
+ call foo
+
+- ! CHECK: call %g1+%i2
++ ! CHECK: call %g1+%i2 ! encoding: [0x9f,0xc0,0x40,0x1a]
+ call %g1 + %i2
+
+- ! CHECK: call %o1+8
++ ! CHECK: call %o1+8 ! encoding: [0x9f,0xc2,0x60,0x08]
+ call %o1 + 8
+
+- ! CHECK: call %g1
++ ! CHECK: call %g1 ! encoding: [0x9f,0xc0,0x60,0x00]
+ call %g1
+
+- ! CHECK: jmp %g1+%i2
++ ! CHECK: call %g1+%lo(sym) ! encoding: [0x9f,0xc0,0b011000AA,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
++ call %g1+%lo(sym)
++
++ ! CHECK: jmp %g1+%i2 ! encoding: [0x81,0xc0,0x40,0x1a]
+ jmp %g1 + %i2
+
+- ! CHECK: jmp %o1+8
++ ! CHECK: jmp %o1+8 ! encoding: [0x81,0xc2,0x60,0x08]
+ jmp %o1 + 8
+
+- ! CHECK: jmp %g1
++ ! CHECK: jmp %g1 ! encoding: [0x81,0xc0,0x60,0x00]
+ jmp %g1
++
++ ! CHECK: jmp %g1+%lo(sym) ! encoding: [0x81,0xc0,0b011000AA,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
++ jmp %g1+%lo(sym)
++
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198738-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198738-sparc.diff
new file mode 100644
index 0000000..87637a7
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198738-sparc.diff
@@ -0,0 +1,734 @@
+Pull in r198738 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add support for parsing branch instructions and conditional moves.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/MC/Disassembler/Sparc/sparc.txt
+===================================================================
+--- test/MC/Disassembler/Sparc/sparc.txt
++++ test/MC/Disassembler/Sparc/sparc.txt
+@@ -80,3 +80,90 @@
+
+ # CHECK: subxcc %g1, %g2, %g3
+ 0x86 0xe0 0x40 0x02
++
++# CHECK: ba 4194303
++0x10 0xbf 0xff 0xff
++
++# CHECK: bne 4194303
++0x12 0xbf 0xff 0xff
++
++# CHECK: be 4194303
++0x02 0xbf 0xff 0xff
++
++# CHECK: bg 4194303
++0x14 0xbf 0xff 0xff
++
++# CHECK: ble 4194303
++0x04 0xbf 0xff 0xff
++
++# CHECK: bge 4194303
++0x16 0xbf 0xff 0xff
++
++# CHECK: bl 4194303
++0x06 0xbf 0xff 0xff
++
++# CHECK: bgu 4194303
++0x18 0xbf 0xff 0xff
++
++# CHECK: bleu 4194303
++0x08 0xbf 0xff 0xff
++
++# CHECK: bcc 4194303
++0x1a 0xbf 0xff 0xff
++
++# CHECK: bcs 4194303
++0x0a 0xbf 0xff 0xff
++
++# CHECK: bpos 4194303
++0x1c 0xbf 0xff 0xff
++
++# CHECK: bneg 4194303
++0x0c 0xbf 0xff 0xff
++
++# CHECK: bvc 4194303
++0x1e 0xbf 0xff 0xff
++
++# CHECK: bvs 4194303
++0x0e 0xbf 0xff 0xff
++
++# CHECK: fbu 4194303
++0x0f 0xbf 0xff 0xff
++
++# CHECK: fbg 4194303
++0x0d 0xbf 0xff 0xff
++
++# CHECK: fbug 4194303
++0x0b 0xbf 0xff 0xff
++
++# CHECK: fbl 4194303
++0x09 0xbf 0xff 0xff
++
++# CHECK: fbul 4194303
++0x07 0xbf 0xff 0xff
++
++# CHECK: fblg 4194303
++0x05 0xbf 0xff 0xff
++
++# CHECK: fbne 4194303
++0x03 0xbf 0xff 0xff
++
++# CHECK: fbe 4194303
++0x13 0xbf 0xff 0xff
++
++# CHECK: fbue 4194303
++0x15 0xbf 0xff 0xff
++
++# CHECK: fbge 4194303
++0x17 0xbf 0xff 0xff
++
++# CHECK: fbuge 4194303
++0x19 0xbf 0xff 0xff
++
++# CHECK: fble 4194303
++0x1b 0xbf 0xff 0xff
++
++# CHECK: fbule 4194303
++0x1d 0xbf 0xff 0xff
++
++# CHECK: fbo 4194303
++0x1f 0xbf 0xff 0xff
+Index: test/MC/Sparc/sparc-ctrl-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-ctrl-instructions.s
++++ test/MC/Sparc/sparc-ctrl-instructions.s
+@@ -31,3 +31,117 @@
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
+ jmp %g1+%lo(sym)
+
++ ! CHECK: ba .BB0 ! encoding: [0x10,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ ba .BB0
++
++ ! CHECK: bne .BB0 ! encoding: [0x12,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bne .BB0
++
++ ! CHECK: be .BB0 ! encoding: [0x02,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ be .BB0
++
++ ! CHECK: bg .BB0 ! encoding: [0x14,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bg .BB0
++
++ ! CHECK: ble .BB0 ! encoding: [0x04,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ ble .BB0
++
++ ! CHECK: bge .BB0 ! encoding: [0x16,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bge .BB0
++
++ ! CHECK: bl .BB0 ! encoding: [0x06,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bl .BB0
++
++ ! CHECK: bgu .BB0 ! encoding: [0x18,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bgu .BB0
++
++ ! CHECK: bleu .BB0 ! encoding: [0x08,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bleu .BB0
++
++ ! CHECK: bcc .BB0 ! encoding: [0x1a,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bcc .BB0
++
++ ! CHECK: bcs .BB0 ! encoding: [0x0a,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bcs .BB0
++
++ ! CHECK: bpos .BB0 ! encoding: [0x1c,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bpos .BB0
++
++ ! CHECK: bneg .BB0 ! encoding: [0x0c,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bneg .BB0
++
++ ! CHECK: bvc .BB0 ! encoding: [0x1e,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bvc .BB0
++
++ ! CHECK: bvs .BB0 ! encoding: [0x0e,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ bvs .BB0
++
++ ! CHECK: fbu .BB0 ! encoding: [0x0f,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbu .BB0
++
++ ! CHECK: fbg .BB0 ! encoding: [0x0d,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbg .BB0
++ ! CHECK: fbug .BB0 ! encoding: [0x0b,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbug .BB0
++
++ ! CHECK: fbl .BB0 ! encoding: [0x09,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbl .BB0
++
++ ! CHECK: fbul .BB0 ! encoding: [0x07,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbul .BB0
++
++ ! CHECK: fblg .BB0 ! encoding: [0x05,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fblg .BB0
++
++ ! CHECK: fbne .BB0 ! encoding: [0x03,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbne .BB0
++
++ ! CHECK: fbe .BB0 ! encoding: [0x13,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbe .BB0
++
++ ! CHECK: fbue .BB0 ! encoding: [0x15,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbue .BB0
++
++ ! CHECK: fbge .BB0 ! encoding: [0x17,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbge .BB0
++
++ ! CHECK: fbuge .BB0 ! encoding: [0x19,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbuge .BB0
++
++ ! CHECK: fble .BB0 ! encoding: [0x1b,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fble .BB0
++
++ ! CHECK: fbule .BB0 ! encoding: [0x1d,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbule .BB0
++
++ ! CHECK: fbo .BB0 ! encoding: [0x1f,0b10AAAAAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
++ fbo .BB0
+Index: test/MC/Sparc/sparc64-ctrl-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc64-ctrl-instructions.s
++++ test/MC/Sparc/sparc64-ctrl-instructions.s
+@@ -0,0 +1,235 @@
++! RUN: llvm-mc %s -triple=sparc64-unknown-linux-gnu -show-encoding | FileCheck %s
++
++
++ ! CHECK: bne %xcc, .BB0 ! encoding: [0x12,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bne %xcc, .BB0
++
++ ! CHECK: be %xcc, .BB0 ! encoding: [0x02,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ be %xcc, .BB0
++
++ ! CHECK: bg %xcc, .BB0 ! encoding: [0x14,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bg %xcc, .BB0
++
++ ! CHECK: ble %xcc, .BB0 ! encoding: [0x04,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ ble %xcc, .BB0
++
++ ! CHECK: bge %xcc, .BB0 ! encoding: [0x16,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bge %xcc, .BB0
++
++ ! CHECK: bl %xcc, .BB0 ! encoding: [0x06,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bl %xcc, .BB0
++
++ ! CHECK: bgu %xcc, .BB0 ! encoding: [0x18,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bgu %xcc, .BB0
++
++ ! CHECK: bleu %xcc, .BB0 ! encoding: [0x08,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bleu %xcc, .BB0
++
++ ! CHECK: bcc %xcc, .BB0 ! encoding: [0x1a,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bcc %xcc, .BB0
++
++ ! CHECK: bcs %xcc, .BB0 ! encoding: [0x0a,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bcs %xcc, .BB0
++
++ ! CHECK: bpos %xcc, .BB0 ! encoding: [0x1c,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bpos %xcc, .BB0
++
++ ! CHECK: bneg %xcc, .BB0 ! encoding: [0x0c,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bneg %xcc, .BB0
++
++ ! CHECK: bvc %xcc, .BB0 ! encoding: [0x1e,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bvc %xcc, .BB0
++
++ ! CHECK: bvs %xcc, .BB0 ! encoding: [0x0e,0b01101AAA,A,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
++ bvs %xcc, .BB0
++
++
++ ! CHECK: movne %icc, %g1, %g2 ! encoding: [0x85,0x66,0x40,0x01]
++ ! CHECK: move %icc, %g1, %g2 ! encoding: [0x85,0x64,0x40,0x01]
++ ! CHECK: movg %icc, %g1, %g2 ! encoding: [0x85,0x66,0x80,0x01]
++ ! CHECK: movle %icc, %g1, %g2 ! encoding: [0x85,0x64,0x80,0x01]
++ ! CHECK: movge %icc, %g1, %g2 ! encoding: [0x85,0x66,0xc0,0x01]
++ ! CHECK: movl %icc, %g1, %g2 ! encoding: [0x85,0x64,0xc0,0x01]
++ ! CHECK: movgu %icc, %g1, %g2 ! encoding: [0x85,0x67,0x00,0x01]
++ ! CHECK: movleu %icc, %g1, %g2 ! encoding: [0x85,0x65,0x00,0x01]
++ ! CHECK: movcc %icc, %g1, %g2 ! encoding: [0x85,0x67,0x40,0x01]
++ ! CHECK: movcs %icc, %g1, %g2 ! encoding: [0x85,0x65,0x40,0x01]
++ ! CHECK: movpos %icc, %g1, %g2 ! encoding: [0x85,0x67,0x80,0x01]
++ ! CHECK: movneg %icc, %g1, %g2 ! encoding: [0x85,0x65,0x80,0x01]
++ ! CHECK: movvc %icc, %g1, %g2 ! encoding: [0x85,0x67,0xc0,0x01]
++ ! CHECK: movvs %icc, %g1, %g2 ! encoding: [0x85,0x65,0xc0,0x01]
++ movne %icc, %g1, %g2
++ move %icc, %g1, %g2
++ movg %icc, %g1, %g2
++ movle %icc, %g1, %g2
++ movge %icc, %g1, %g2
++ movl %icc, %g1, %g2
++ movgu %icc, %g1, %g2
++ movleu %icc, %g1, %g2
++ movcc %icc, %g1, %g2
++ movcs %icc, %g1, %g2
++ movpos %icc, %g1, %g2
++ movneg %icc, %g1, %g2
++ movvc %icc, %g1, %g2
++ movvs %icc, %g1, %g2
++
++ ! CHECK: movne %xcc, %g1, %g2 ! encoding: [0x85,0x66,0x50,0x01]
++ ! CHECK: move %xcc, %g1, %g2 ! encoding: [0x85,0x64,0x50,0x01]
++ ! CHECK: movg %xcc, %g1, %g2 ! encoding: [0x85,0x66,0x90,0x01]
++ ! CHECK: movle %xcc, %g1, %g2 ! encoding: [0x85,0x64,0x90,0x01]
++ ! CHECK: movge %xcc, %g1, %g2 ! encoding: [0x85,0x66,0xd0,0x01]
++ ! CHECK: movl %xcc, %g1, %g2 ! encoding: [0x85,0x64,0xd0,0x01]
++ ! CHECK: movgu %xcc, %g1, %g2 ! encoding: [0x85,0x67,0x10,0x01]
++ ! CHECK: movleu %xcc, %g1, %g2 ! encoding: [0x85,0x65,0x10,0x01]
++ ! CHECK: movcc %xcc, %g1, %g2 ! encoding: [0x85,0x67,0x50,0x01]
++ ! CHECK: movcs %xcc, %g1, %g2 ! encoding: [0x85,0x65,0x50,0x01]
++ ! CHECK: movpos %xcc, %g1, %g2 ! encoding: [0x85,0x67,0x90,0x01]
++ ! CHECK: movneg %xcc, %g1, %g2 ! encoding: [0x85,0x65,0x90,0x01]
++ ! CHECK: movvc %xcc, %g1, %g2 ! encoding: [0x85,0x67,0xd0,0x01]
++ ! CHECK: movvs %xcc, %g1, %g2 ! encoding: [0x85,0x65,0xd0,0x01]
++ movne %xcc, %g1, %g2
++ move %xcc, %g1, %g2
++ movg %xcc, %g1, %g2
++ movle %xcc, %g1, %g2
++ movge %xcc, %g1, %g2
++ movl %xcc, %g1, %g2
++ movgu %xcc, %g1, %g2
++ movleu %xcc, %g1, %g2
++ movcc %xcc, %g1, %g2
++ movcs %xcc, %g1, %g2
++ movpos %xcc, %g1, %g2
++ movneg %xcc, %g1, %g2
++ movvc %xcc, %g1, %g2
++ movvs %xcc, %g1, %g2
++
++ ! CHECK: movu %fcc0, %g1, %g2 ! encoding: [0x85,0x61,0xc0,0x01]
++ ! CHECK: movg %fcc0, %g1, %g2 ! encoding: [0x85,0x61,0x80,0x01]
++ ! CHECK: movug %fcc0, %g1, %g2 ! encoding: [0x85,0x61,0x40,0x01]
++ ! CHECK: movl %fcc0, %g1, %g2 ! encoding: [0x85,0x61,0x00,0x01]
++ ! CHECK: movul %fcc0, %g1, %g2 ! encoding: [0x85,0x60,0xc0,0x01]
++ ! CHECK: movlg %fcc0, %g1, %g2 ! encoding: [0x85,0x60,0x80,0x01]
++ ! CHECK: movne %fcc0, %g1, %g2 ! encoding: [0x85,0x60,0x40,0x01]
++ ! CHECK: move %fcc0, %g1, %g2 ! encoding: [0x85,0x62,0x40,0x01]
++ ! CHECK: movue %fcc0, %g1, %g2 ! encoding: [0x85,0x62,0x80,0x01]
++ ! CHECK: movge %fcc0, %g1, %g2 ! encoding: [0x85,0x62,0xc0,0x01]
++ ! CHECK: movuge %fcc0, %g1, %g2 ! encoding: [0x85,0x63,0x00,0x01]
++ ! CHECK: movle %fcc0, %g1, %g2 ! encoding: [0x85,0x63,0x40,0x01]
++ ! CHECK: movule %fcc0, %g1, %g2 ! encoding: [0x85,0x63,0x80,0x01]
++ ! CHECK: movo %fcc0, %g1, %g2 ! encoding: [0x85,0x63,0xc0,0x01]
++ movu %fcc0, %g1, %g2
++ movg %fcc0, %g1, %g2
++ movug %fcc0, %g1, %g2
++ movl %fcc0, %g1, %g2
++ movul %fcc0, %g1, %g2
++ movlg %fcc0, %g1, %g2
++ movne %fcc0, %g1, %g2
++ move %fcc0, %g1, %g2
++ movue %fcc0, %g1, %g2
++ movge %fcc0, %g1, %g2
++ movuge %fcc0, %g1, %g2
++ movle %fcc0, %g1, %g2
++ movule %fcc0, %g1, %g2
++ movo %fcc0, %g1, %g2
++
++
++ ! CHECK fmovsne %icc, %f1, %f2 ! encoding: [0x85,0xaa,0x60,0x21]
++ ! CHECK fmovse %icc, %f1, %f2 ! encoding: [0x85,0xa8,0x60,0x21]
++ ! CHECK fmovsg %icc, %f1, %f2 ! encoding: [0x85,0xaa,0xa0,0x21]
++ ! CHECK fmovsle %icc, %f1, %f2 ! encoding: [0x85,0xa8,0xa0,0x21]
++ ! CHECK fmovsge %icc, %f1, %f2 ! encoding: [0x85,0xaa,0xe0,0x21]
++ ! CHECK fmovsl %icc, %f1, %f2 ! encoding: [0x85,0xa8,0xe0,0x21]
++ ! CHECK fmovsgu %icc, %f1, %f2 ! encoding: [0x85,0xab,0x20,0x21]
++ ! CHECK fmovsleu %icc, %f1, %f2 ! encoding: [0x85,0xa9,0x20,0x21]
++ ! CHECK fmovscc %icc, %f1, %f2 ! encoding: [0x85,0xab,0x60,0x21]
++ ! CHECK fmovscs %icc, %f1, %f2 ! encoding: [0x85,0xa9,0x60,0x21]
++ ! CHECK fmovspos %icc, %f1, %f2 ! encoding: [0x85,0xab,0xa0,0x21]
++ ! CHECK fmovsneg %icc, %f1, %f2 ! encoding: [0x85,0xa9,0xa0,0x21]
++ ! CHECK fmovsvc %icc, %f1, %f2 ! encoding: [0x85,0xab,0xe0,0x21]
++ ! CHECK fmovsvs %icc, %f1, %f2 ! encoding: [0x85,0xa9,0xe0,0x21]
++ fmovsne %icc, %f1, %f2
++ fmovse %icc, %f1, %f2
++ fmovsg %icc, %f1, %f2
++ fmovsle %icc, %f1, %f2
++ fmovsge %icc, %f1, %f2
++ fmovsl %icc, %f1, %f2
++ fmovsgu %icc, %f1, %f2
++ fmovsleu %icc, %f1, %f2
++ fmovscc %icc, %f1, %f2
++ fmovscs %icc, %f1, %f2
++ fmovspos %icc, %f1, %f2
++ fmovsneg %icc, %f1, %f2
++ fmovsvc %icc, %f1, %f2
++ fmovsvs %icc, %f1, %f2
++
++ ! CHECK fmovsne %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0x70,0x21]
++ ! CHECK fmovse %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0x70,0x21]
++ ! CHECK fmovsg %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0xb0,0x21]
++ ! CHECK fmovsle %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0xb0,0x21]
++ ! CHECK fmovsge %xcc, %f1, %f2 ! encoding: [0x85,0xaa,0xf0,0x21]
++ ! CHECK fmovsl %xcc, %f1, %f2 ! encoding: [0x85,0xa8,0xf0,0x21]
++ ! CHECK fmovsgu %xcc, %f1, %f2 ! encoding: [0x85,0xab,0x30,0x21]
++ ! CHECK fmovsleu %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0x30,0x21]
++ ! CHECK fmovscc %xcc, %f1, %f2 ! encoding: [0x85,0xab,0x70,0x21]
++ ! CHECK fmovscs %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0x70,0x21]
++ ! CHECK fmovspos %xcc, %f1, %f2 ! encoding: [0x85,0xab,0xb0,0x21]
++ ! CHECK fmovsneg %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0xb0,0x21]
++ ! CHECK fmovsvc %xcc, %f1, %f2 ! encoding: [0x85,0xab,0xf0,0x21]
++ ! CHECK fmovsvs %xcc, %f1, %f2 ! encoding: [0x85,0xa9,0xf0,0x21]
++ fmovsne %xcc, %f1, %f2
++ fmovse %xcc, %f1, %f2
++ fmovsg %xcc, %f1, %f2
++ fmovsle %xcc, %f1, %f2
++ fmovsge %xcc, %f1, %f2
++ fmovsl %xcc, %f1, %f2
++ fmovsgu %xcc, %f1, %f2
++ fmovsleu %xcc, %f1, %f2
++ fmovscc %xcc, %f1, %f2
++ fmovscs %xcc, %f1, %f2
++ fmovspos %xcc, %f1, %f2
++ fmovsneg %xcc, %f1, %f2
++ fmovsvc %xcc, %f1, %f2
++ fmovsvs %xcc, %f1, %f2
++
++ ! CHECK fmovsu %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0xc0,0x21]
++ ! CHECK fmovsg %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x80,0x21]
++ ! CHECK fmovsug %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x40,0x21]
++ ! CHECK fmovsl %fcc0, %f1, %f2 ! encoding: [0x85,0xa9,0x00,0x21]
++ ! CHECK fmovsul %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0xc0,0x21]
++ ! CHECK fmovslg %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0x80,0x21]
++ ! CHECK fmovsne %fcc0, %f1, %f2 ! encoding: [0x85,0xa8,0x40,0x21]
++ ! CHECK fmovse %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0x40,0x21]
++ ! CHECK fmovsue %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0x80,0x21]
++ ! CHECK fmovsge %fcc0, %f1, %f2 ! encoding: [0x85,0xaa,0xc0,0x21]
++ ! CHECK fmovsuge %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x00,0x21]
++ ! CHECK fmovsle %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x40,0x21]
++ ! CHECK fmovsule %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0x80,0x21]
++ ! CHECK fmovso %fcc0, %f1, %f2 ! encoding: [0x85,0xab,0xc0,0x21]
++ fmovsu %fcc0, %f1, %f2
++ fmovsg %fcc0, %f1, %f2
++ fmovsug %fcc0, %f1, %f2
++ fmovsl %fcc0, %f1, %f2
++ fmovsul %fcc0, %f1, %f2
++ fmovslg %fcc0, %f1, %f2
++ fmovsne %fcc0, %f1, %f2
++ fmovse %fcc0, %f1, %f2
++ fmovsue %fcc0, %f1, %f2
++ fmovsge %fcc0, %f1, %f2
++ fmovsuge %fcc0, %f1, %f2
++ fmovsle %fcc0, %f1, %f2
++ fmovsule %fcc0, %f1, %f2
++ fmovso %fcc0, %f1, %f2
++
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -333,32 +333,42 @@ class XBranchSP<dag ins, string asmstr, list<dag>
+ let Predicates = [Is64Bit] in {
+
+ let Uses = [ICC] in
+-def BPXCC : XBranchSP<(ins brtarget:$imm22, CCOp:$cond),
+- "b$cond %xcc, $imm22",
+- [(SPbrxcc bb:$imm22, imm:$cond)]>;
++def BPXCC : XBranchSP<(ins brtarget:$imm19, CCOp:$cond),
++ "b$cond %xcc, $imm19",
++ [(SPbrxcc bb:$imm19, imm:$cond)]>;
+
+ // Conditional moves on %xcc.
+ let Uses = [ICC], Constraints = "$f = $rd" in {
+-def MOVXCCrr : Pseudo<(outs IntRegs:$rd),
++let cc = 0b110 in {
++def MOVXCCrr : F4_1<0b101100, (outs IntRegs:$rd),
+ (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond),
+ "mov$cond %xcc, $rs2, $rd",
+ [(set i32:$rd,
+ (SPselectxcc i32:$rs2, i32:$f, imm:$cond))]>;
+-def MOVXCCri : Pseudo<(outs IntRegs:$rd),
+- (ins i32imm:$i, IntRegs:$f, CCOp:$cond),
+- "mov$cond %xcc, $i, $rd",
++def MOVXCCri : F4_2<0b101100, (outs IntRegs:$rd),
++ (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond),
++ "mov$cond %xcc, $simm11, $rd",
+ [(set i32:$rd,
+- (SPselectxcc simm11:$i, i32:$f, imm:$cond))]>;
+-def FMOVS_XCC : Pseudo<(outs FPRegs:$rd),
++ (SPselectxcc simm11:$simm11, i32:$f, imm:$cond))]>;
++} // cc
++
++let opf_cc = 0b110 in {
++def FMOVS_XCC : F4_3<0b110101, 0b000001, (outs FPRegs:$rd),
+ (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond),
+ "fmovs$cond %xcc, $rs2, $rd",
+ [(set f32:$rd,
+ (SPselectxcc f32:$rs2, f32:$f, imm:$cond))]>;
+-def FMOVD_XCC : Pseudo<(outs DFPRegs:$rd),
++def FMOVD_XCC : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd),
+ (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond),
+ "fmovd$cond %xcc, $rs2, $rd",
+ [(set f64:$rd,
+ (SPselectxcc f64:$rs2, f64:$f, imm:$cond))]>;
++def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd),
++ (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond),
++ "fmovq$cond %xcc, $rs2, $rd",
++ [(set f128:$rd,
++ (SPselectxcc f128:$rs2, f128:$f, imm:$cond))]>;
++} // opf_cc
+ } // Uses, Constraints
+
+ //===----------------------------------------------------------------------===//
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -928,8 +928,9 @@ let Predicates = [HasV9], Constraints = "$f = $rd"
+ def FMOVQ_ICC
+ : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd),
+ (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond),
+- "fmovd$cond %icc, $rs2, $rd",
+- [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>;
++ "fmovq$cond %icc, $rs2, $rd",
++ [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>,
++ Requires<[HasHardQuad]>;
+ }
+
+ let Uses = [FCC], opf_cc = 0b000 in {
+@@ -946,8 +947,9 @@ let Predicates = [HasV9], Constraints = "$f = $rd"
+ def FMOVQ_FCC
+ : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd),
+ (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond),
+- "fmovd$cond %fcc0, $rs2, $rd",
+- [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>;
++ "fmovq$cond %fcc0, $rs2, $rd",
++ [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>,
++ Requires<[HasHardQuad]>;
+ }
+
+ }
+@@ -1092,3 +1094,4 @@ def : Pat<(atomic_store ADDRri:$dst, i32:$val), (S
+
+
+ include "SparcInstr64Bit.td"
++include "SparcInstrAliases.td"
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -537,9 +537,29 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
+ Parser.Lex(); // Eat the '%'.
+ unsigned RegNo;
+ if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
++ StringRef name = Parser.getTok().getString();
+ Parser.Lex(); // Eat the identifier token.
+ E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+- Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
++ switch (RegNo) {
++ default:
++ Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
++ break;
++ case Sparc::Y:
++ Op = SparcOperand::CreateToken("%y", S);
++ break;
++
++ case Sparc::ICC:
++ if (name == "xcc")
++ Op = SparcOperand::CreateToken("%xcc", S);
++ else
++ Op = SparcOperand::CreateToken("%icc", S);
++ break;
++
++ case Sparc::FCC:
++ assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet");
++ Op = SparcOperand::CreateToken("%fcc0", S);
++ break;
++ }
+ break;
+ }
+ if (matchSparcAsmModifiers(EVal, E)) {
+Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+@@ -83,6 +83,17 @@ void SparcInstPrinter::printCCOperand(const MCInst
+ raw_ostream &O)
+ {
+ int CC = (int)MI->getOperand(opNum).getImm();
++ switch (MI->getOpcode()) {
++ default: break;
++ case SP::FBCOND:
++ case SP::MOVFCCrr:
++ case SP::MOVFCCri:
++ case SP::FMOVS_FCC:
++ case SP::FMOVD_FCC:
++ case SP::FMOVQ_FCC: // Make sure CC is a fp conditional flag.
++ CC = (CC < 16) ? (CC + 16) : CC;
++ break;
++ }
+ O << SPARCCondCodeToString((SPCC::CondCodes)CC);
+ }
+
+Index: lib/Target/Sparc/SparcInstrAliases.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrAliases.td
++++ lib/Target/Sparc/SparcInstrAliases.td
+@@ -0,0 +1,119 @@
++//===-- SparcInstrAliases.td - Instruction Aliases for Sparc Target -------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// This file contains instruction aliases for Sparc.
++//===----------------------------------------------------------------------===//
++
++// Instruction aliases for conditional moves.
++
++// mov<cond> <ccreg> rs2, rd
++multiclass cond_mov_alias<string cond, int condVal, string ccreg,
++ Instruction movrr, Instruction movri,
++ Instruction fmovs, Instruction fmovd> {
++
++ // mov<cond> (%icc|%xcc|%fcc0), rs2, rd
++ def : InstAlias<!strconcat(!strconcat(!strconcat("mov", cond), ccreg),
++ ", $rs2, $rd"),
++ (movrr IntRegs:$rd, IntRegs:$rs2, condVal)>;
++
++ // mov<cond> (%icc|%xcc|%fcc0), simm11, rd
++ def : InstAlias<!strconcat(!strconcat(!strconcat("mov", cond), ccreg),
++ ", $simm11, $rd"),
++ (movri IntRegs:$rd, i32imm:$simm11, condVal)>;
++
++ // fmovs<cond> (%icc|%xcc|%fcc0), $rs2, $rd
++ def : InstAlias<!strconcat(!strconcat(!strconcat("fmovs", cond), ccreg),
++ ", $rs2, $rd"),
++ (fmovs FPRegs:$rd, FPRegs:$rs2, condVal)>;
++
++ // fmovd<cond> (%icc|%xcc|%fcc0), $rs2, $rd
++ def : InstAlias<!strconcat(!strconcat(!strconcat("fmovd", cond), ccreg),
++ ", $rs2, $rd"),
++ (fmovd DFPRegs:$rd, DFPRegs:$rs2, condVal)>;
++}
++
++
++// Instruction aliases for integer conditional branches and moves.
++multiclass int_cond_alias<string cond, int condVal> {
++
++ // b<cond> $imm
++ def : InstAlias<!strconcat(!strconcat("b", cond), " $imm"),
++ (BCOND brtarget:$imm, condVal)>;
++
++ // b<cond> %xcc, $imm
++ def : InstAlias<!strconcat(!strconcat("b", cond), " %xcc, $imm"),
++ (BPXCC brtarget:$imm, condVal)>, Requires<[Is64Bit]>;
++
++ defm : cond_mov_alias<cond, condVal, " %icc",
++ MOVICCrr, MOVICCri,
++ FMOVS_ICC, FMOVD_ICC>, Requires<[HasV9]>;
++
++ defm : cond_mov_alias<cond, condVal, " %xcc",
++ MOVXCCrr, MOVXCCri,
++ FMOVS_XCC, FMOVD_XCC>, Requires<[Is64Bit]>;
++
++ // fmovq<cond> (%icc|%xcc), $rs2, $rd
++ def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %icc, $rs2, $rd"),
++ (FMOVQ_ICC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
++ Requires<[HasV9, HasHardQuad]>;
++ def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %xcc, $rs2, $rd"),
++ (FMOVQ_XCC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
++ Requires<[Is64Bit, HasHardQuad]>;
++
++}
++
++
++// Instruction aliases for floating point conditional branches and moves.
++multiclass fp_cond_alias<string cond, int condVal> {
++
++ // fb<cond> $imm
++ def : InstAlias<!strconcat(!strconcat("fb", cond), " $imm"),
++ (FBCOND brtarget:$imm, condVal), 0>;
++
++ defm : cond_mov_alias<cond, condVal, " %fcc0",
++ MOVFCCrr, MOVFCCri,
++ FMOVS_FCC, FMOVD_FCC>, Requires<[HasV9]>;
++
++ // fmovq<cond> %fcc0, $rs2, $rd
++ def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %fcc0, $rs2, $rd"),
++ (FMOVQ_ICC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
++ Requires<[HasV9, HasHardQuad]>;
++}
++
++defm : int_cond_alias<"a", 0b1000>;
++defm : int_cond_alias<"n", 0b0000>;
++defm : int_cond_alias<"ne", 0b1001>;
++defm : int_cond_alias<"e", 0b0001>;
++defm : int_cond_alias<"g", 0b1010>;
++defm : int_cond_alias<"le", 0b0010>;
++defm : int_cond_alias<"ge", 0b1011>;
++defm : int_cond_alias<"l", 0b0011>;
++defm : int_cond_alias<"gu", 0b1100>;
++defm : int_cond_alias<"leu", 0b0100>;
++defm : int_cond_alias<"cc", 0b1101>;
++defm : int_cond_alias<"cs", 0b0101>;
++defm : int_cond_alias<"pos", 0b1110>;
++defm : int_cond_alias<"neg", 0b0110>;
++defm : int_cond_alias<"vc", 0b1111>;
++defm : int_cond_alias<"vs", 0b0111>;
++
++defm : fp_cond_alias<"u", 0b0111>;
++defm : fp_cond_alias<"g", 0b0110>;
++defm : fp_cond_alias<"ug", 0b0101>;
++defm : fp_cond_alias<"l", 0b0100>;
++defm : fp_cond_alias<"ul", 0b0011>;
++defm : fp_cond_alias<"lg", 0b0010>;
++defm : fp_cond_alias<"ne", 0b0001>;
++defm : fp_cond_alias<"e", 0b1001>;
++defm : fp_cond_alias<"ue", 0b1010>;
++defm : fp_cond_alias<"ge", 0b1011>;
++defm : fp_cond_alias<"uge", 0b1100>;
++defm : fp_cond_alias<"le", 0b1101>;
++defm : fp_cond_alias<"ule", 0b1110>;
++defm : fp_cond_alias<"o", 0b1111>;
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198739-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198739-sparc.diff
new file mode 100644
index 0000000..f7b884c
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198739-sparc.diff
@@ -0,0 +1,19 @@
+Pull in r198739 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Correct the mask for fixup_sparc_br19.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+@@ -31,7 +31,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui
+ case Sparc::fixup_sparc_br22:
+ return (Value >> 2) & 0x3fffff;
+ case Sparc::fixup_sparc_br19:
+- return (Value >> 2) & 0x1ffff;
++ return (Value >> 2) & 0x7ffff;
+ case Sparc::fixup_sparc_hi22:
+ return (Value >> 10) & 0x3fffff;
+ case Sparc::fixup_sparc_lo10:
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198740-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198740-sparc.diff
new file mode 100644
index 0000000..ff9bfd5
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198740-sparc.diff
@@ -0,0 +1,115 @@
+Pull in r198740 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9] Rename operands in some sparc64 instructions so that TableGen can encode them correctly.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/MC/Sparc/sparc64-alu-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc64-alu-instructions.s
++++ test/MC/Sparc/sparc64-alu-instructions.s
+@@ -0,0 +1,38 @@
++! RUN: llvm-mc %s -triple=sparc64-unknown-linux-gnu -show-encoding | FileCheck %s
++
++ ! CHECK: sllx %g1, %i2, %i0 ! encoding: [0xb1,0x28,0x50,0x1a]
++ sllx %g1, %i2, %i0
++
++ ! CHECK: sllx %g1, 63, %i0 ! encoding: [0xb1,0x28,0x70,0x3f]
++ sllx %g1, 63, %i0
++
++ ! CHECK: srlx %g1, %i2, %i0 ! encoding: [0xb1,0x30,0x50,0x1a]
++ srlx %g1, %i2, %i0
++
++ ! CHECK: srlx %g1, 63, %i0 ! encoding: [0xb1,0x30,0x70,0x3f]
++ srlx %g1, 63, %i0
++
++ ! CHECK: srax %g1, %i2, %i0 ! encoding: [0xb1,0x38,0x50,0x1a]
++ srax %g1, %i2, %i0
++
++ ! CHECK: srax %g1, 63, %i0 ! encoding: [0xb1,0x38,0x70,0x3f]
++ srax %g1, 63, %i0
++
++ ! CHECK: mulx %g1, %i2, %i0 ! encoding: [0xb0,0x48,0x40,0x1a]
++ mulx %g1, %i2, %i0
++
++ ! CHECK: mulx %g1, 63, %i0 ! encoding: [0xb0,0x48,0x60,0x3f]
++ mulx %g1, 63, %i0
++
++ ! CHECK: sdivx %g1, %i2, %i0 ! encoding: [0xb1,0x68,0x40,0x1a]
++ sdivx %g1, %i2, %i0
++
++ ! CHECK: sdivx %g1, 63, %i0 ! encoding: [0xb1,0x68,0x60,0x3f]
++ sdivx %g1, 63, %i0
++
++ ! CHECK: udivx %g1, %i2, %i0 ! encoding: [0xb0,0x68,0x40,0x1a]
++ udivx %g1, %i2, %i0
++
++ ! CHECK: udivx %g1, 63, %i0 ! encoding: [0xb0,0x68,0x60,0x3f]
++ udivx %g1, 63, %i0
++
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -193,9 +193,9 @@ def MULXrr : F3_1<2, 0b001001,
+ "mulx $rs1, $rs2, $rd",
+ [(set i64:$rd, (mul i64:$rs1, i64:$rs2))]>;
+ def MULXri : F3_2<2, 0b001001,
+- (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$i),
+- "mulx $rs1, $i, $rd",
+- [(set i64:$rd, (mul i64:$rs1, (i64 simm13:$i)))]>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13),
++ "mulx $rs1, $simm13, $rd",
++ [(set i64:$rd, (mul i64:$rs1, (i64 simm13:$simm13)))]>;
+
+ // Division can trap.
+ let hasSideEffects = 1 in {
+@@ -204,9 +204,9 @@ def SDIVXrr : F3_1<2, 0b101101,
+ "sdivx $rs1, $rs2, $rd",
+ [(set i64:$rd, (sdiv i64:$rs1, i64:$rs2))]>;
+ def SDIVXri : F3_2<2, 0b101101,
+- (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$i),
+- "sdivx $rs1, $i, $rd",
+- [(set i64:$rd, (sdiv i64:$rs1, (i64 simm13:$i)))]>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13),
++ "sdivx $rs1, $simm13, $rd",
++ [(set i64:$rd, (sdiv i64:$rs1, (i64 simm13:$simm13)))]>;
+
+ def UDIVXrr : F3_1<2, 0b001101,
+ (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2),
+@@ -213,9 +213,9 @@ def UDIVXrr : F3_1<2, 0b001101,
+ "udivx $rs1, $rs2, $rd",
+ [(set i64:$rd, (udiv i64:$rs1, i64:$rs2))]>;
+ def UDIVXri : F3_2<2, 0b001101,
+- (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$i),
+- "udivx $rs1, $i, $rd",
+- [(set i64:$rd, (udiv i64:$rs1, (i64 simm13:$i)))]>;
++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13),
++ "udivx $rs1, $simm13, $rd",
++ [(set i64:$rd, (udiv i64:$rs1, (i64 simm13:$simm13)))]>;
+ } // hasSideEffects = 1
+
+ } // Predicates = [Is64Bit]
+Index: lib/Target/Sparc/SparcInstrFormats.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrFormats.td
++++ lib/Target/Sparc/SparcInstrFormats.td
+@@ -193,12 +193,12 @@ class F3_Si<bits<2> opVal, bits<6> op3val, bit xVa
+ // Define rr and ri shift instructions with patterns.
+ multiclass F3_S<string OpcStr, bits<6> Op3Val, bit XVal, SDNode OpNode,
+ ValueType VT, RegisterClass RC> {
+- def rr : F3_Sr<2, Op3Val, XVal, (outs RC:$rd), (ins RC:$rs, IntRegs:$rs2),
+- !strconcat(OpcStr, " $rs, $rs2, $rd"),
+- [(set VT:$rd, (OpNode VT:$rs, i32:$rs2))]>;
+- def ri : F3_Si<2, Op3Val, XVal, (outs RC:$rd), (ins RC:$rs, i32imm:$shcnt),
+- !strconcat(OpcStr, " $rs, $shcnt, $rd"),
+- [(set VT:$rd, (OpNode VT:$rs, (i32 imm:$shcnt)))]>;
++ def rr : F3_Sr<2, Op3Val, XVal, (outs RC:$rd), (ins RC:$rs1, IntRegs:$rs2),
++ !strconcat(OpcStr, " $rs1, $rs2, $rd"),
++ [(set VT:$rd, (OpNode VT:$rs1, i32:$rs2))]>;
++ def ri : F3_Si<2, Op3Val, XVal, (outs RC:$rd), (ins RC:$rs1, i32imm:$shcnt),
++ !strconcat(OpcStr, " $rs1, $shcnt, $rd"),
++ [(set VT:$rd, (OpNode VT:$rs1, (i32 imm:$shcnt)))]>;
+ }
+
+ class F4<bits<6> op3, dag outs, dag ins, string asmstr, list<dag> pattern>
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198893-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198893-sparc.diff
new file mode 100644
index 0000000..a1434c0
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198893-sparc.diff
@@ -0,0 +1,236 @@
+Pull in r198893 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Multiclass for loads/stores. No functionality change intended.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -235,14 +235,8 @@ def UDIVXri : F3_2<2, 0b001101,
+ let Predicates = [Is64Bit] in {
+
+ // 64-bit loads.
+-def LDXrr : F3_1<3, 0b001011,
+- (outs I64Regs:$dst), (ins MEMrr:$addr),
+- "ldx [$addr], $dst",
+- [(set i64:$dst, (load ADDRrr:$addr))]>;
+-def LDXri : F3_2<3, 0b001011,
+- (outs I64Regs:$dst), (ins MEMri:$addr),
+- "ldx [$addr], $dst",
+- [(set i64:$dst, (load ADDRri:$addr))]>;
++defm LDX : Load<"ldx", 0b001011, load, I64Regs, i64>;
++
+ let mayLoad = 1, isCodeGenOnly = 1, isAsmParserOnly = 1 in
+ def TLS_LDXrr : F3_1<3, 0b001011,
+ (outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym),
+@@ -276,24 +270,10 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr
+ def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>;
+
+ // Sign-extending load of i32 into i64 is a new SPARC v9 instruction.
+-def LDSWrr : F3_1<3, 0b001000,
+- (outs I64Regs:$dst), (ins MEMrr:$addr),
+- "ldsw [$addr], $dst",
+- [(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>;
+-def LDSWri : F3_2<3, 0b001000,
+- (outs I64Regs:$dst), (ins MEMri:$addr),
+- "ldsw [$addr], $dst",
+- [(set i64:$dst, (sextloadi32 ADDRri:$addr))]>;
++defm LDSW : Load<"ldsw", 0b001000, sextloadi32, I64Regs, i64>;
+
+ // 64-bit stores.
+-def STXrr : F3_1<3, 0b001110,
+- (outs), (ins MEMrr:$addr, I64Regs:$rd),
+- "stx $rd, [$addr]",
+- [(store i64:$rd, ADDRrr:$addr)]>;
+-def STXri : F3_2<3, 0b001110,
+- (outs), (ins MEMri:$addr, I64Regs:$rd),
+- "stx $rd, [$addr]",
+- [(store i64:$rd, ADDRri:$addr)]>;
++defm STX : Store<"stx", 0b001110, store, I64Regs, i64>;
+
+ // Truncating stores from i64 are identical to the i32 stores.
+ def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>;
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -250,6 +250,32 @@ multiclass F3_12np<string OpcStr, bits<6> Op3Val>
+ !strconcat(OpcStr, " $rs1, $simm13, $rd"), []>;
+ }
+
++// Load multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot.
++multiclass Load<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode,
++ RegisterClass RC, ValueType Ty> {
++ def rr : F3_1<3, Op3Val,
++ (outs RC:$dst), (ins MEMrr:$addr),
++ !strconcat(OpcStr, " [$addr], $dst"),
++ [(set Ty:$dst, (OpNode ADDRrr:$addr))]>;
++ def ri : F3_2<3, Op3Val,
++ (outs RC:$dst), (ins MEMri:$addr),
++ !strconcat(OpcStr, " [$addr], $dst"),
++ [(set Ty:$dst, (OpNode ADDRri:$addr))]>;
++}
++
++// Store multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot.
++multiclass Store<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode,
++ RegisterClass RC, ValueType Ty> {
++ def rr : F3_1<3, Op3Val,
++ (outs), (ins MEMrr:$addr, RC:$rd),
++ !strconcat(OpcStr, " $rd, [$addr]"),
++ [(OpNode Ty:$rd, ADDRrr:$addr)]>;
++ def ri : F3_2<3, Op3Val,
++ (outs), (ins MEMri:$addr, RC:$rd),
++ !strconcat(OpcStr, " $rd, [$addr]"),
++ [(OpNode Ty:$rd, ADDRri:$addr)]>;
++}
++
+ //===----------------------------------------------------------------------===//
+ // Instructions
+ //===----------------------------------------------------------------------===//
+@@ -350,128 +376,28 @@ let isReturn = 1, isTerminator = 1, hasDelaySlot =
+ }
+
+ // Section B.1 - Load Integer Instructions, p. 90
+-def LDSBrr : F3_1<3, 0b001001,
+- (outs IntRegs:$dst), (ins MEMrr:$addr),
+- "ldsb [$addr], $dst",
+- [(set i32:$dst, (sextloadi8 ADDRrr:$addr))]>;
+-def LDSBri : F3_2<3, 0b001001,
+- (outs IntRegs:$dst), (ins MEMri:$addr),
+- "ldsb [$addr], $dst",
+- [(set i32:$dst, (sextloadi8 ADDRri:$addr))]>;
+-def LDSHrr : F3_1<3, 0b001010,
+- (outs IntRegs:$dst), (ins MEMrr:$addr),
+- "ldsh [$addr], $dst",
+- [(set i32:$dst, (sextloadi16 ADDRrr:$addr))]>;
+-def LDSHri : F3_2<3, 0b001010,
+- (outs IntRegs:$dst), (ins MEMri:$addr),
+- "ldsh [$addr], $dst",
+- [(set i32:$dst, (sextloadi16 ADDRri:$addr))]>;
+-def LDUBrr : F3_1<3, 0b000001,
+- (outs IntRegs:$dst), (ins MEMrr:$addr),
+- "ldub [$addr], $dst",
+- [(set i32:$dst, (zextloadi8 ADDRrr:$addr))]>;
+-def LDUBri : F3_2<3, 0b000001,
+- (outs IntRegs:$dst), (ins MEMri:$addr),
+- "ldub [$addr], $dst",
+- [(set i32:$dst, (zextloadi8 ADDRri:$addr))]>;
+-def LDUHrr : F3_1<3, 0b000010,
+- (outs IntRegs:$dst), (ins MEMrr:$addr),
+- "lduh [$addr], $dst",
+- [(set i32:$dst, (zextloadi16 ADDRrr:$addr))]>;
+-def LDUHri : F3_2<3, 0b000010,
+- (outs IntRegs:$dst), (ins MEMri:$addr),
+- "lduh [$addr], $dst",
+- [(set i32:$dst, (zextloadi16 ADDRri:$addr))]>;
+-def LDrr : F3_1<3, 0b000000,
+- (outs IntRegs:$dst), (ins MEMrr:$addr),
+- "ld [$addr], $dst",
+- [(set i32:$dst, (load ADDRrr:$addr))]>;
+-def LDri : F3_2<3, 0b000000,
+- (outs IntRegs:$dst), (ins MEMri:$addr),
+- "ld [$addr], $dst",
+- [(set i32:$dst, (load ADDRri:$addr))]>;
++defm LDSB : Load<"ldsb", 0b001001, sextloadi8, IntRegs, i32>;
++defm LDSH : Load<"ldsh", 0b001010, sextloadi16, IntRegs, i32>;
++defm LDUB : Load<"ldub", 0b000001, zextloadi8, IntRegs, i32>;
++defm LDUH : Load<"lduh", 0b000010, zextloadi16, IntRegs, i32>;
++defm LD : Load<"ld", 0b000000, load, IntRegs, i32>;
+
+ // Section B.2 - Load Floating-point Instructions, p. 92
+-def LDFrr : F3_1<3, 0b100000,
+- (outs FPRegs:$dst), (ins MEMrr:$addr),
+- "ld [$addr], $dst",
+- [(set f32:$dst, (load ADDRrr:$addr))]>;
+-def LDFri : F3_2<3, 0b100000,
+- (outs FPRegs:$dst), (ins MEMri:$addr),
+- "ld [$addr], $dst",
+- [(set f32:$dst, (load ADDRri:$addr))]>;
+-def LDDFrr : F3_1<3, 0b100011,
+- (outs DFPRegs:$dst), (ins MEMrr:$addr),
+- "ldd [$addr], $dst",
+- [(set f64:$dst, (load ADDRrr:$addr))]>;
+-def LDDFri : F3_2<3, 0b100011,
+- (outs DFPRegs:$dst), (ins MEMri:$addr),
+- "ldd [$addr], $dst",
+- [(set f64:$dst, (load ADDRri:$addr))]>;
+-def LDQFrr : F3_1<3, 0b100010,
+- (outs QFPRegs:$dst), (ins MEMrr:$addr),
+- "ldq [$addr], $dst",
+- [(set f128:$dst, (load ADDRrr:$addr))]>,
+- Requires<[HasV9, HasHardQuad]>;
+-def LDQFri : F3_2<3, 0b100010,
+- (outs QFPRegs:$dst), (ins MEMri:$addr),
+- "ldq [$addr], $dst",
+- [(set f128:$dst, (load ADDRri:$addr))]>,
+- Requires<[HasV9, HasHardQuad]>;
++defm LDF : Load<"ld", 0b100000, load, FPRegs, f32>;
++defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64>;
++defm LDQF : Load<"ldq", 0b100010, load, QFPRegs, f128>,
++ Requires<[HasV9, HasHardQuad]>;
+
+ // Section B.4 - Store Integer Instructions, p. 95
+-def STBrr : F3_1<3, 0b000101,
+- (outs), (ins MEMrr:$addr, IntRegs:$rd),
+- "stb $rd, [$addr]",
+- [(truncstorei8 i32:$rd, ADDRrr:$addr)]>;
+-def STBri : F3_2<3, 0b000101,
+- (outs), (ins MEMri:$addr, IntRegs:$rd),
+- "stb $rd, [$addr]",
+- [(truncstorei8 i32:$rd, ADDRri:$addr)]>;
+-def STHrr : F3_1<3, 0b000110,
+- (outs), (ins MEMrr:$addr, IntRegs:$rd),
+- "sth $rd, [$addr]",
+- [(truncstorei16 i32:$rd, ADDRrr:$addr)]>;
+-def STHri : F3_2<3, 0b000110,
+- (outs), (ins MEMri:$addr, IntRegs:$rd),
+- "sth $rd, [$addr]",
+- [(truncstorei16 i32:$rd, ADDRri:$addr)]>;
+-def STrr : F3_1<3, 0b000100,
+- (outs), (ins MEMrr:$addr, IntRegs:$rd),
+- "st $rd, [$addr]",
+- [(store i32:$rd, ADDRrr:$addr)]>;
+-def STri : F3_2<3, 0b000100,
+- (outs), (ins MEMri:$addr, IntRegs:$rd),
+- "st $rd, [$addr]",
+- [(store i32:$rd, ADDRri:$addr)]>;
++defm STB : Store<"stb", 0b000101, truncstorei8, IntRegs, i32>;
++defm STH : Store<"sth", 0b000110, truncstorei16, IntRegs, i32>;
++defm ST : Store<"st", 0b000100, store, IntRegs, i32>;
+
+ // Section B.5 - Store Floating-point Instructions, p. 97
+-def STFrr : F3_1<3, 0b100100,
+- (outs), (ins MEMrr:$addr, FPRegs:$rd),
+- "st $rd, [$addr]",
+- [(store f32:$rd, ADDRrr:$addr)]>;
+-def STFri : F3_2<3, 0b100100,
+- (outs), (ins MEMri:$addr, FPRegs:$rd),
+- "st $rd, [$addr]",
+- [(store f32:$rd, ADDRri:$addr)]>;
+-def STDFrr : F3_1<3, 0b100111,
+- (outs), (ins MEMrr:$addr, DFPRegs:$rd),
+- "std $rd, [$addr]",
+- [(store f64:$rd, ADDRrr:$addr)]>;
+-def STDFri : F3_2<3, 0b100111,
+- (outs), (ins MEMri:$addr, DFPRegs:$rd),
+- "std $rd, [$addr]",
+- [(store f64:$rd, ADDRri:$addr)]>;
+-def STQFrr : F3_1<3, 0b100110,
+- (outs), (ins MEMrr:$addr, QFPRegs:$rd),
+- "stq $rd, [$addr]",
+- [(store f128:$rd, ADDRrr:$addr)]>,
+- Requires<[HasV9, HasHardQuad]>;
+-def STQFri : F3_2<3, 0b100110,
+- (outs), (ins MEMri:$addr, QFPRegs:$rd),
+- "stq $rd, [$addr]",
+- [(store f128:$rd, ADDRri:$addr)]>,
+- Requires<[HasV9, HasHardQuad]>;
++defm STF : Store<"st", 0b100100, store, FPRegs, f32>;
++defm STDF : Store<"std", 0b100111, store, DFPRegs, f64>;
++defm STQF : Store<"stq", 0b100110, store, QFPRegs, f128>,
++ Requires<[HasV9, HasHardQuad]>;
+
+ // Section B.9 - SETHI Instruction, p. 104
+ def SETHIi: F2_1<0b100,
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff
new file mode 100644
index 0000000..e4fb0f3
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff
@@ -0,0 +1,229 @@
+Pull in r198909 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add support for parsing jmpl instruction and make indirect call and jmp instructions as aliases to jmpl.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -453,6 +453,7 @@ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand
+ switch (getLexer().getKind()) {
+ default: return MatchOperand_NoMatch;
+
++ case AsmToken::Comma:
+ case AsmToken::RBrac:
+ case AsmToken::EndOfStatement:
+ Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
+Index: lib/Target/Sparc/SparcInstrAliases.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrAliases.td
++++ lib/Target/Sparc/SparcInstrAliases.td
+@@ -117,3 +117,14 @@ defm : fp_cond_alias<"uge", 0b1100>;
+ defm : fp_cond_alias<"le", 0b1101>;
+ defm : fp_cond_alias<"ule", 0b1110>;
+ defm : fp_cond_alias<"o", 0b1111>;
++
++
++// Instruction aliases for JMPL.
++
++// jmp addr -> jmpl addr, %g0
++def : InstAlias<"jmp $addr", (JMPLrr G0, MEMrr:$addr)>;
++def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$addr)>;
++
++// call addr -> jmpl addr, %o7
++def : InstAlias<"call $addr", (JMPLrr O7, MEMrr:$addr)>;
++def : InstAlias<"call $addr", (JMPLri O7, MEMri:$addr)>;
+Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+@@ -23,6 +23,7 @@
+ using namespace llvm;
+
+ #define GET_INSTRUCTION_NAME
++#define PRINT_ALIAS_INSTR
+ #include "SparcGenAsmWriter.inc"
+
+ void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
+@@ -33,10 +34,34 @@ void SparcInstPrinter::printRegName(raw_ostream &O
+ void SparcInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
+ StringRef Annot)
+ {
+- printInstruction(MI, O);
++ if (!printAliasInstr(MI, O) && !printSparcAliasInstr(MI, O))
++ printInstruction(MI, O);
+ printAnnotation(O, Annot);
+ }
+
++bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O)
++{
++ switch (MI->getOpcode()) {
++ default: return false;
++ case SP::JMPLrr:
++ case SP::JMPLri: {
++ if (MI->getNumOperands() != 3)
++ return false;
++ if (!MI->getOperand(0).isReg())
++ return false;
++ switch (MI->getOperand(0).getReg()) {
++ default: return false;
++ case SP::G0: // jmp $addr
++ O << "\tjmp "; printMemOperand(MI, 1, O);
++ return true;
++ case SP::O7: // call $addr
++ O << "\tcall "; printMemOperand(MI, 1, O);
++ return true;
++ }
++ }
++ }
++}
++
+ void SparcInstPrinter::printOperand(const MCInst *MI, int opNum,
+ raw_ostream &O)
+ {
+Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
+===================================================================
+--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
+@@ -29,9 +29,11 @@ class SparcInstPrinter : public MCInstPrinter {
+
+ virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
+ virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
++ bool printSparcAliasInstr(const MCInst *MI, raw_ostream &OS);
+
+ // Autogenerated by tblgen.
+ void printInstruction(const MCInst *MI, raw_ostream &O);
++ bool printAliasInstr(const MCInst *MI, raw_ostream &O);
+ static const char *getRegisterName(unsigned RegNo);
+
+ void printOperand(const MCInst *MI, int opNum, raw_ostream &OS);
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -362,10 +362,18 @@ let usesCustomInserter = 1, Uses = [FCC] in {
+ [(set f128:$dst, (SPselectfcc f128:$T, f128:$F, imm:$Cond))]>;
+ }
+
++// JMPL Instruction.
++let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in {
++ def JMPLrr: F3_1<2, 0b111000, (outs IntRegs:$dst), (ins MEMrr:$addr),
++ "jmpl $addr, $dst", []>;
++ def JMPLri: F3_2<2, 0b111000, (outs IntRegs:$dst), (ins MEMri:$addr),
++ "jmpl $addr, $dst", []>;
++}
+
+ // Section A.3 - Synthetic Instructions, p. 85
+ // special cases of JMPL:
+-let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in {
++let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
++ isCodeGenOnly = 1 in {
+ let rd = 0, rs1 = 15 in
+ def RETL: F3_2<2, 0b111000, (outs), (ins i32imm:$val),
+ "jmp %o7+$val", [(retflag simm13:$val)]>;
+@@ -519,9 +527,8 @@ class BranchSP<dag ins, string asmstr, list<dag> p
+ }
+
+ // Indirect branch instructions.
+-let isTerminator = 1, isBarrier = 1,
+- hasDelaySlot = 1, isBranch =1,
+- isIndirectBranch = 1, rd = 0 in {
++let isTerminator = 1, isBarrier = 1, hasDelaySlot = 1, isBranch =1,
++ isIndirectBranch = 1, rd = 0, isCodeGenOnly = 1 in {
+ def BINDrr : F3_1<2, 0b111000,
+ (outs), (ins MEMrr:$ptr),
+ "jmp $ptr",
+@@ -564,15 +571,17 @@ let Uses = [O6],
+ let Inst{29-0} = disp;
+ }
+
+- // indirect calls
+- def JMPLrr : F3_1<2, 0b111000,
+- (outs), (ins MEMrr:$ptr, variable_ops),
+- "call $ptr",
+- [(call ADDRrr:$ptr)]> { let rd = 15; }
+- def JMPLri : F3_2<2, 0b111000,
+- (outs), (ins MEMri:$ptr, variable_ops),
+- "call $ptr",
+- [(call ADDRri:$ptr)]> { let rd = 15; }
++ // indirect calls: special cases of JMPL.
++ let isCodeGenOnly = 1, rd = 15 in {
++ def CALLrr : F3_1<2, 0b111000,
++ (outs), (ins MEMrr:$ptr, variable_ops),
++ "call $ptr",
++ [(call ADDRrr:$ptr)]>;
++ def CALLri : F3_2<2, 0b111000,
++ (outs), (ins MEMri:$ptr, variable_ops),
++ "call $ptr",
++ [(call ADDRri:$ptr)]>;
++ }
+ }
+
+ // Section B.28 - Read State Register Instructions
+Index: lib/Target/Sparc/DelaySlotFiller.cpp
+===================================================================
+--- lib/Target/Sparc/DelaySlotFiller.cpp
++++ lib/Target/Sparc/DelaySlotFiller.cpp
+@@ -278,19 +278,19 @@ void Filler::insertCallDefsUses(MachineBasicBlock:
+ switch(MI->getOpcode()) {
+ default: llvm_unreachable("Unknown opcode.");
+ case SP::CALL: break;
+- case SP::JMPLrr:
+- case SP::JMPLri:
++ case SP::CALLrr:
++ case SP::CALLri:
+ assert(MI->getNumOperands() >= 2);
+ const MachineOperand &Reg = MI->getOperand(0);
+- assert(Reg.isReg() && "JMPL first operand is not a register.");
+- assert(Reg.isUse() && "JMPL first operand is not a use.");
++ assert(Reg.isReg() && "CALL first operand is not a register.");
++ assert(Reg.isUse() && "CALL first operand is not a use.");
+ RegUses.insert(Reg.getReg());
+
+ const MachineOperand &RegOrImm = MI->getOperand(1);
+ if (RegOrImm.isImm())
+ break;
+- assert(RegOrImm.isReg() && "JMPLrr second operand is not a register.");
+- assert(RegOrImm.isUse() && "JMPLrr second operand is not a use.");
++ assert(RegOrImm.isReg() && "CALLrr second operand is not a register.");
++ assert(RegOrImm.isUse() && "CALLrr second operand is not a use.");
+ RegUses.insert(RegOrImm.getReg());
+ break;
+ }
+@@ -353,8 +353,8 @@ bool Filler::needsUnimp(MachineBasicBlock::iterato
+ switch (I->getOpcode()) {
+ default: llvm_unreachable("Unknown call opcode.");
+ case SP::CALL: structSizeOpNum = 1; break;
+- case SP::JMPLrr:
+- case SP::JMPLri: structSizeOpNum = 2; break;
++ case SP::CALLrr:
++ case SP::CALLri: structSizeOpNum = 2; break;
+ case SP::TLS_CALL: return false;
+ }
+
+Index: test/MC/Sparc/sparc-ctrl-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-ctrl-instructions.s
++++ test/MC/Sparc/sparc-ctrl-instructions.s
+@@ -31,6 +31,19 @@
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
+ jmp %g1+%lo(sym)
+
++ ! CHECK: jmpl %g1+%i2, %g2 ! encoding: [0x85,0xc0,0x40,0x1a]
++ jmpl %g1 + %i2, %g2
++
++ ! CHECK: jmpl %o1+8, %g2 ! encoding: [0x85,0xc2,0x60,0x08]
++ jmpl %o1 + 8, %g2
++
++ ! CHECK: jmpl %g1, %g2 ! encoding: [0x85,0xc0,0x60,0x00]
++ jmpl %g1, %g2
++
++ ! CHECK: jmpl %g1+%lo(sym), %g2 ! encoding: [0x85,0xc0,0b011000AA,A]
++ ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
++ jmpl %g1+%lo(sym), %g2
++
+ ! CHECK: ba .BB0 ! encoding: [0x10,0b10AAAAAA,A,A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+ ba .BB0
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198910-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198910-sparc.diff
new file mode 100644
index 0000000..94b320c
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198910-sparc.diff
@@ -0,0 +1,463 @@
+Pull in r198910 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Emit retl/ret instead of jmp instruction. It improves the readability of the assembly generated.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/CodeGen/SPARC/ctpop.ll
+===================================================================
+--- test/CodeGen/SPARC/ctpop.ll
++++ test/CodeGen/SPARC/ctpop.ll
+@@ -9,12 +9,12 @@ declare i32 @llvm.ctpop.i32(i32)
+
+ ; V9-LABEL: test
+ ; V9: srl %o0, 0, %o0
+-; V9-NEXT: jmp %o7+8
++; V9-NEXT: retl
+ ; V9-NEXT: popc %o0, %o0
+
+ ; SPARC64-LABEL: test
+ ; SPARC64: srl %o0, 0, %o0
+-; SPARC64: jmp %o7+8
++; SPARC64: retl
+ ; SPARC64: popc %o0, %o0
+
+ define i32 @test(i32 %X) {
+Index: test/CodeGen/SPARC/2011-01-11-Call.ll
+===================================================================
+--- test/CodeGen/SPARC/2011-01-11-Call.ll
++++ test/CodeGen/SPARC/2011-01-11-Call.ll
+@@ -8,7 +8,7 @@
+ ; V8-NEXT: nop
+ ; V8: call bar
+ ; V8-NEXT: nop
+-; V8: jmp %i7+8
++; V8: ret
+ ; V8-NEXT: restore
+
+ ; V9-LABEL: test
+@@ -17,7 +17,7 @@
+ ; V9-NEXT: nop
+ ; V9: call bar
+ ; V9-NEXT: nop
+-; V9: jmp %i7+8
++; V9: ret
+ ; V9-NEXT: restore
+
+ define void @test() nounwind {
+@@ -36,7 +36,7 @@ declare void @bar(...)
+ ; V8: save %sp
+ ; V8: call foo
+ ; V8-NEXT: nop
+-; V8: jmp %i7+8
++; V8: ret
+ ; V8-NEXT: restore %g0, %o0, %o0
+
+ ; V9-LABEL: test_tail_call_with_return
+@@ -43,7 +43,7 @@ declare void @bar(...)
+ ; V9: save %sp
+ ; V9: call foo
+ ; V9-NEXT: nop
+-; V9: jmp %i7+8
++; V9: ret
+ ; V9-NEXT: restore %g0, %o0, %o0
+
+ define i32 @test_tail_call_with_return() nounwind {
+Index: test/CodeGen/SPARC/leafproc.ll
+===================================================================
+--- test/CodeGen/SPARC/leafproc.ll
++++ test/CodeGen/SPARC/leafproc.ll
+@@ -1,7 +1,7 @@
+ ; RUN: llc -march=sparc -disable-sparc-leaf-proc=0 < %s | FileCheck %s
+
+ ; CHECK-LABEL: func_nobody:
+-; CHECK: jmp %o7+8
++; CHECK: retl
+ ; CHECK-NEXT: nop
+ define void @func_nobody() {
+ entry:
+@@ -10,7 +10,7 @@ entry:
+
+
+ ; CHECK-LABEL: return_int_const:
+-; CHECK: jmp %o7+8
++; CHECK: retl
+ ; CHECK-NEXT: or %g0, 1729, %o0
+ define i32 @return_int_const() {
+ entry:
+@@ -19,7 +19,7 @@ entry:
+
+ ; CHECK-LABEL: return_double_const:
+ ; CHECK: sethi
+-; CHECK: jmp %o7+8
++; CHECK: retl
+ ; CHECK-NEXT: ldd {{.*}}, %f0
+
+ define double @return_double_const() {
+@@ -29,7 +29,7 @@ entry:
+
+ ; CHECK-LABEL: leaf_proc_with_args:
+ ; CHECK: add {{%o[0-1]}}, {{%o[0-1]}}, [[R:%[go][0-7]]]
+-; CHECK: jmp %o7+8
++; CHECK: retl
+ ; CHECK-NEXT: add [[R]], %o2, %o0
+
+ define i32 @leaf_proc_with_args(i32 %a, i32 %b, i32 %c) {
+@@ -42,7 +42,7 @@ entry:
+ ; CHECK-LABEL: leaf_proc_with_args_in_stack:
+ ; CHECK-DAG: ld [%sp+92], {{%[go][0-7]}}
+ ; CHECK-DAG: ld [%sp+96], {{%[go][0-7]}}
+-; CHECK: jmp %o7+8
++; CHECK: retl
+ ; CHECK-NEXT: add {{.*}}, %o0
+ define i32 @leaf_proc_with_args_in_stack(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) {
+ entry:
+@@ -63,7 +63,7 @@ entry:
+ ; CHECK: or %g0, 2, [[R2:%[go][0-7]]]
+ ; CHECK: st [[R2]], [%sp+100]
+ ; CHECK: ld {{.+}}, %o0
+-; CHECK: jmp %o7+8
++; CHECK: retl
+ ; CHECK-NEXT: add %sp, 104, %sp
+
+ define i32 @leaf_proc_with_local_array(i32 %a, i32 %b, i32 %c) {
+Index: test/CodeGen/SPARC/fp128.ll
+===================================================================
+--- test/CodeGen/SPARC/fp128.ll
++++ test/CodeGen/SPARC/fp128.ll
+@@ -45,7 +45,7 @@ entry:
+ ; HARD: std %f{{.+}}, [%[[S1:.+]]]
+ ; HARD-DAG: ldd [%[[S0]]], %f{{.+}}
+ ; HARD-DAG: ldd [%[[S1]]], %f{{.+}}
+-; HARD: jmp
++; HARD: jmp %o7+12
+
+ ; SOFT-LABEL: f128_spill
+ ; SOFT: std %f{{.+}}, [%[[S0:.+]]]
+@@ -52,7 +52,7 @@ entry:
+ ; SOFT: std %f{{.+}}, [%[[S1:.+]]]
+ ; SOFT-DAG: ldd [%[[S0]]], %f{{.+}}
+ ; SOFT-DAG: ldd [%[[S1]]], %f{{.+}}
+-; SOFT: jmp
++; SOFT: jmp %o7+12
+
+ define void @f128_spill(fp128* noalias sret %scalar.result, fp128* byval %a) {
+ entry:
+@@ -132,13 +132,13 @@ entry:
+ ; HARD: ldub
+ ; HARD: faddq
+ ; HARD: stb
+-; HARD: jmp
++; HARD: ret
+
+ ; SOFT-LABEL: fp128_unaligned
+ ; SOFT: ldub
+ ; SOFT: call _Q_add
+ ; SOFT: stb
+-; SOFT: jmp
++; SOFT: ret
+
+ define void @fp128_unaligned(fp128* %a, fp128* %b, fp128* %c) {
+ entry:
+Index: test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
+===================================================================
+--- test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
++++ test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
+@@ -9,18 +9,18 @@ define i8* @frameaddr() nounwind readnone {
+ entry:
+ ;V8-LABEL: frameaddr:
+ ;V8: save %sp, -96, %sp
+-;V8: jmp %i7+8
++;V8: ret
+ ;V8: restore %g0, %fp, %o0
+
+ ;V9-LABEL: frameaddr:
+ ;V9: save %sp, -96, %sp
+-;V9: jmp %i7+8
++;V9: ret
+ ;V9: restore %g0, %fp, %o0
+
+ ;SPARC64-LABEL: frameaddr
+ ;SPARC64: save %sp, -128, %sp
+ ;SPARC64: add %fp, 2047, %i0
+-;SPARC64: jmp %i7+8
++;SPARC64: ret
+ ;SPARC64: restore %g0, %g0, %g0
+
+ %0 = tail call i8* @llvm.frameaddress(i32 0)
+Index: test/CodeGen/SPARC/constpool.ll
+===================================================================
+--- test/CodeGen/SPARC/constpool.ll
++++ test/CodeGen/SPARC/constpool.ll
+@@ -12,7 +12,7 @@ entry:
+
+ ; abs32: floatCP
+ ; abs32: sethi %hi(.LCPI0_0), %[[R:[gilo][0-7]]]
+-; abs32: jmp %o7+8
++; abs32: retl
+ ; abs32: ld [%[[R]]+%lo(.LCPI0_0)], %f
+
+
+@@ -20,7 +20,7 @@ entry:
+ ; abs44: sethi %h44(.LCPI0_0), %[[R1:[gilo][0-7]]]
+ ; abs44: add %[[R1]], %m44(.LCPI0_0), %[[R2:[gilo][0-7]]]
+ ; abs44: sllx %[[R2]], 12, %[[R3:[gilo][0-7]]]
+-; abs44: jmp %o7+8
++; abs44: retl
+ ; abs44: ld [%[[R3]]+%l44(.LCPI0_0)], %f1
+
+
+@@ -30,7 +30,7 @@ entry:
+ ; abs64: sethi %hh(.LCPI0_0), %[[R3:[gilo][0-7]]]
+ ; abs64: add %[[R3]], %hm(.LCPI0_0), %[[R4:[gilo][0-7]]]
+ ; abs64: sllx %[[R4]], 32, %[[R5:[gilo][0-7]]]
+-; abs64: jmp %o7+8
++; abs64: retl
+ ; abs64: ld [%[[R5]]+%[[R2]]], %f1
+
+
+@@ -40,7 +40,7 @@ entry:
+ ; v8pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]]
+ ; v8pic32: ld [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]]
+ ; v8pic32: ld [%[[Gaddr]]], %f0
+-; v8pic32: jmp %i7+8
++; v8pic32: ret
+ ; v8pic32: restore
+
+
+@@ -51,7 +51,7 @@ entry:
+ ; v9pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]]
+ ; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]]
+ ; v9pic32: ld [%[[Gaddr]]], %f1
+-; v9pic32: jmp %i7+8
++; v9pic32: ret
+ ; v9pic32: restore
+
+
+Index: test/CodeGen/SPARC/globals.ll
+===================================================================
+--- test/CodeGen/SPARC/globals.ll
++++ test/CodeGen/SPARC/globals.ll
+@@ -14,7 +14,7 @@ define zeroext i8 @loadG() {
+
+ ; abs32: loadG
+ ; abs32: sethi %hi(G), %[[R:[gilo][0-7]]]
+-; abs32: jmp %o7+8
++; abs32: retl
+ ; abs32: ldub [%[[R]]+%lo(G)], %o0
+
+
+@@ -22,7 +22,7 @@ define zeroext i8 @loadG() {
+ ; abs44: sethi %h44(G), %[[R1:[gilo][0-7]]]
+ ; abs44: add %[[R1]], %m44(G), %[[R2:[gilo][0-7]]]
+ ; abs44: sllx %[[R2]], 12, %[[R3:[gilo][0-7]]]
+-; abs44: jmp %o7+8
++; abs44: retl
+ ; abs44: ldub [%[[R3]]+%l44(G)], %o0
+
+
+@@ -32,7 +32,7 @@ define zeroext i8 @loadG() {
+ ; abs64: sethi %hh(G), %[[R3:[gilo][0-7]]]
+ ; abs64: add %[[R3]], %hm(G), %[[R4:[gilo][0-7]]]
+ ; abs64: sllx %[[R4]], 32, %[[R5:[gilo][0-7]]]
+-; abs64: jmp %o7+8
++; abs64: retl
+ ; abs64: ldub [%[[R5]]+%[[R2]]], %o0
+
+
+@@ -42,7 +42,7 @@ define zeroext i8 @loadG() {
+ ; v8pic32: add %[[R1]], %lo(G), %[[Goffs:[gilo][0-7]]]
+ ; v8pic32: ld [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]]
+ ; v8pic32: ldub [%[[Gaddr]]], %i0
+-; v8pic32: jmp %i7+8
++; v8pic32: ret
+ ; v8pic32: restore
+
+
+@@ -52,6 +52,6 @@ define zeroext i8 @loadG() {
+ ; v9pic32: add %[[R1]], %lo(G), %[[Goffs:[gilo][0-7]]]
+ ; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]]
+ ; v9pic32: ldub [%[[Gaddr]]], %i0
+-; v9pic32: jmp %i7+8
++; v9pic32: ret
+ ; v9pic32: restore
+
+Index: test/CodeGen/SPARC/rem.ll
+===================================================================
+--- test/CodeGen/SPARC/rem.ll
++++ test/CodeGen/SPARC/rem.ll
+@@ -3,7 +3,7 @@
+ ; CHECK-LABEL: test1:
+ ; CHECK: sdivx %o0, %o1, %o2
+ ; CHECK-NEXT: mulx %o2, %o1, %o1
+-; CHECK-NEXT: jmp %o7+8
++; CHECK-NEXT: retl
+ ; CHECK-NEXT: sub %o0, %o1, %o0
+
+ define i64 @test1(i64 %X, i64 %Y) {
+@@ -14,7 +14,7 @@ define i64 @test1(i64 %X, i64 %Y) {
+ ; CHECK-LABEL: test2:
+ ; CHECK: udivx %o0, %o1, %o2
+ ; CHECK-NEXT: mulx %o2, %o1, %o1
+-; CHECK-NEXT: jmp %o7+8
++; CHECK-NEXT: retl
+ ; CHECK-NEXT: sub %o0, %o1, %o0
+
+ define i64 @test2(i64 %X, i64 %Y) {
+Index: test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
+===================================================================
+--- test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
++++ test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
+@@ -7,7 +7,7 @@ entry:
+ ; CHECK: test
+ ; CHECK: call bar
+ ; CHECK-NOT: nop
+-; CHECK: jmp
++; CHECK: ret
+ ; CHECK-NEXT: restore
+ %0 = tail call i32 @bar(i32 %a) nounwind
+ ret i32 %0
+@@ -18,7 +18,7 @@ entry:
+ ; CHECK: test_jmpl
+ ; CHECK: call
+ ; CHECK-NOT: nop
+-; CHECK: jmp
++; CHECK: ret
+ ; CHECK-NEXT: restore
+ %0 = tail call i32 %f(i32 %a, i32 %b) nounwind
+ ret i32 %0
+@@ -47,7 +47,7 @@ bb:
+
+ bb5: ; preds = %bb, %entry
+ %a_addr.1.lcssa = phi i32 [ %a, %entry ], [ %a_addr.0, %bb ]
+-;CHECK: jmp
++;CHECK: retl
+ ;CHECK-NOT: restore
+ ret i32 %a_addr.1.lcssa
+ }
+@@ -110,7 +110,7 @@ declare i32 @func(i32*)
+ define i32 @restore_add(i32 %a, i32 %b) {
+ entry:
+ ;CHECK-LABEL: restore_add:
+-;CHECK: jmp %i7+8
++;CHECK: ret
+ ;CHECK: restore %o0, %i1, %o0
+ %0 = tail call i32 @bar(i32 %a) nounwind
+ %1 = add nsw i32 %0, %b
+@@ -120,7 +120,7 @@ entry:
+ define i32 @restore_add_imm(i32 %a) {
+ entry:
+ ;CHECK-LABEL: restore_add_imm:
+-;CHECK: jmp %i7+8
++;CHECK: ret
+ ;CHECK: restore %o0, 20, %o0
+ %0 = tail call i32 @bar(i32 %a) nounwind
+ %1 = add nsw i32 %0, 20
+@@ -130,7 +130,7 @@ entry:
+ define i32 @restore_or(i32 %a) {
+ entry:
+ ;CHECK-LABEL: restore_or:
+-;CHECK: jmp %i7+8
++;CHECK: ret
+ ;CHECK: restore %g0, %o0, %o0
+ %0 = tail call i32 @bar(i32 %a) nounwind
+ ret i32 %0
+@@ -140,7 +140,7 @@ define i32 @restore_or_imm(i32 %a) {
+ entry:
+ ;CHECK-LABEL: restore_or_imm:
+ ;CHECK: or %o0, 20, %i0
+-;CHECK: jmp %i7+8
++;CHECK: ret
+ ;CHECK: restore %g0, %g0, %g0
+ %0 = tail call i32 @bar(i32 %a) nounwind
+ %1 = or i32 %0, 20
+Index: test/CodeGen/SPARC/64bit.ll
+===================================================================
+--- test/CodeGen/SPARC/64bit.ll
++++ test/CodeGen/SPARC/64bit.ll
+@@ -5,7 +5,7 @@
+ ; CHECK: or %g0, %i1, %i0
+
+ ; OPT-LABEL: ret2:
+-; OPT: jmp %o7+8
++; OPT: retl
+ ; OPT: or %g0, %o1, %o0
+ define i64 @ret2(i64 %a, i64 %b) {
+ ret i64 %b
+@@ -15,7 +15,7 @@ define i64 @ret2(i64 %a, i64 %b) {
+ ; CHECK: sllx %i0, 7, %i0
+
+ ; OPT-LABEL: shl_imm:
+-; OPT: jmp %o7+8
++; OPT: retl
+ ; OPT: sllx %o0, 7, %o0
+ define i64 @shl_imm(i64 %a) {
+ %x = shl i64 %a, 7
+@@ -26,7 +26,7 @@ define i64 @shl_imm(i64 %a) {
+ ; CHECK: srax %i0, %i1, %i0
+
+ ; OPT-LABEL: sra_reg:
+-; OPT: jmp %o7+8
++; OPT: retl
+ ; OPT: srax %o0, %o1, %o0
+ define i64 @sra_reg(i64 %a, i64 %b) {
+ %x = ashr i64 %a, %b
+@@ -42,7 +42,7 @@ define i64 @sra_reg(i64 %a, i64 %b) {
+ ; CHECK: or %g0, 0, %i0
+
+ ; OPT: ret_imm0
+-; OPT: jmp %o7+8
++; OPT: retl
+ ; OPT: or %g0, 0, %o0
+ define i64 @ret_imm0() {
+ ret i64 0
+@@ -52,7 +52,7 @@ define i64 @ret_imm0() {
+ ; CHECK: or %g0, -4096, %i0
+
+ ; OPT: ret_simm13
+-; OPT: jmp %o7+8
++; OPT: retl
+ ; OPT: or %g0, -4096, %o0
+ define i64 @ret_simm13() {
+ ret i64 -4096
+@@ -64,7 +64,7 @@ define i64 @ret_simm13() {
+ ; CHECK: restore
+
+ ; OPT: ret_sethi
+-; OPT: jmp %o7+8
++; OPT: retl
+ ; OPT: sethi 4, %o0
+ define i64 @ret_sethi() {
+ ret i64 4096
+@@ -76,7 +76,7 @@ define i64 @ret_sethi() {
+
+ ; OPT: ret_sethi_or
+ ; OPT: sethi 4, [[R:%[go][0-7]]]
+-; OPT: jmp %o7+8
++; OPT: retl
+ ; OPT: or [[R]], 1, %o0
+
+ define i64 @ret_sethi_or() {
+@@ -89,7 +89,7 @@ define i64 @ret_sethi_or() {
+
+ ; OPT: ret_nimm33
+ ; OPT: sethi 4, [[R:%[go][0-7]]]
+-; OPT: jmp %o7+8
++; OPT: retl
+ ; OPT: xor [[R]], -4, %o0
+
+ define i64 @ret_nimm33() {
+Index: lib/Target/Sparc/SparcInstrAliases.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrAliases.td
++++ lib/Target/Sparc/SparcInstrAliases.td
+@@ -128,3 +128,9 @@ def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$ad
+ // call addr -> jmpl addr, %o7
+ def : InstAlias<"call $addr", (JMPLrr O7, MEMrr:$addr)>;
+ def : InstAlias<"call $addr", (JMPLri O7, MEMri:$addr)>;
++
++// retl -> RETL 8
++def : InstAlias<"retl", (RETL 8)>;
++
++// ret -> RET 8
++def : InstAlias<"ret", (RET 8)>;
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199014-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199014-sparc.diff
new file mode 100644
index 0000000..6db27a06
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199014-sparc.diff
@@ -0,0 +1,133 @@
+Pull in r199014 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Bundle instruction with delay slow and its filler. Now, we can use -verify-machineinstrs with SPARC backend.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/DelaySlotFiller.cpp
+===================================================================
+--- lib/Target/Sparc/DelaySlotFiller.cpp
++++ lib/Target/Sparc/DelaySlotFiller.cpp
+@@ -19,6 +19,7 @@
+ #include "llvm/ADT/Statistic.h"
+ #include "llvm/CodeGen/MachineFunctionPass.h"
+ #include "llvm/CodeGen/MachineInstrBuilder.h"
++#include "llvm/CodeGen/MachineRegisterInfo.h"
+ #include "llvm/Support/CommandLine.h"
+ #include "llvm/Target/TargetInstrInfo.h"
+ #include "llvm/Target/TargetMachine.h"
+@@ -55,6 +56,11 @@ namespace {
+ bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
+ bool runOnMachineFunction(MachineFunction &F) {
+ bool Changed = false;
++
++ // This pass invalidates liveness information when it reorders
++ // instructions to fill delay slot.
++ F.getRegInfo().invalidateLiveness();
++
+ for (MachineFunction::iterator FI = F.begin(), FE = F.end();
+ FI != FE; ++FI)
+ Changed |= runOnMachineBasicBlock(*FI);
+@@ -61,9 +67,6 @@ namespace {
+ return Changed;
+ }
+
+- bool isDelayFiller(MachineBasicBlock &MBB,
+- MachineBasicBlock::iterator candidate);
+-
+ void insertCallDefsUses(MachineBasicBlock::iterator MI,
+ SmallSet<unsigned, 32>& RegDefs,
+ SmallSet<unsigned, 32>& RegUses);
+@@ -152,6 +155,10 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBl
+ assert (J != MBB.end() && "MI needs a delay instruction.");
+ BuildMI(MBB, ++J, MI->getDebugLoc(),
+ TII->get(SP::UNIMP)).addImm(structSize);
++ // Bundle the delay filler and unimp with the instruction.
++ MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), J);
++ } else {
++ MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), I);
+ }
+ }
+ return Changed;
+@@ -209,7 +216,7 @@ Filler::findDelayInstr(MachineBasicBlock &MBB,
+ || I->isInlineAsm()
+ || I->isLabel()
+ || I->hasDelaySlot()
+- || isDelayFiller(MBB, I))
++ || I->isBundledWithSucc())
+ break;
+
+ if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
+@@ -332,18 +339,6 @@ bool Filler::IsRegInSet(SmallSet<unsigned, 32>& Re
+ return false;
+ }
+
+-// return true if the candidate is a delay filler.
+-bool Filler::isDelayFiller(MachineBasicBlock &MBB,
+- MachineBasicBlock::iterator candidate)
+-{
+- if (candidate == MBB.begin())
+- return false;
+- if (candidate->getOpcode() == SP::UNIMP)
+- return true;
+- --candidate;
+- return candidate->hasDelaySlot();
+-}
+-
+ bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
+ {
+ if (!I->isCall())
+@@ -484,10 +479,10 @@ bool Filler::tryCombineRestoreWithPrevInst(Machine
+ && MBBI->getOperand(1).getReg() == SP::G0
+ && MBBI->getOperand(2).getReg() == SP::G0);
+
+- MachineBasicBlock::iterator PrevInst = MBBI; --PrevInst;
++ MachineBasicBlock::iterator PrevInst = llvm::prior(MBBI);
+
+- // It cannot combine with a delay filler.
+- if (isDelayFiller(MBB, PrevInst))
++ // It cannot be combined with a bundled instruction.
++ if (PrevInst->isBundledWithSucc())
+ return false;
+
+ const TargetInstrInfo *TII = TM.getInstrInfo();
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -184,7 +184,6 @@ static void LowerGETPCXAndEmitMCInsts(const Machin
+
+ void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
+ {
+- MCInst TmpInst;
+
+ switch (MI->getOpcode()) {
+ default: break;
+@@ -195,8 +194,13 @@ void SparcAsmPrinter::EmitInstruction(const Machin
+ LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
+ return;
+ }
+- LowerSparcMachineInstrToMCInst(MI, TmpInst, *this);
+- OutStreamer.EmitInstruction(TmpInst);
++ MachineBasicBlock::const_instr_iterator I = MI;
++ MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
++ do {
++ MCInst TmpInst;
++ LowerSparcMachineInstrToMCInst(I, TmpInst, *this);
++ OutStreamer.EmitInstruction(TmpInst);
++ } while ((++I != E) && I->isInsideBundle()); // Delay slot check.
+ }
+
+ void SparcAsmPrinter::EmitFunctionBodyStart() {
+Index: test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
+===================================================================
+--- test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
++++ test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
+@@ -1,5 +1,5 @@
+-;RUN: llc -march=sparc < %s | FileCheck %s
+-;RUN: llc -march=sparc -O0 < %s | FileCheck %s -check-prefix=UNOPT
++;RUN: llc -march=sparc < %s -verify-machineinstrs | FileCheck %s
++;RUN: llc -march=sparc -O0 < %s -verify-machineinstrs | FileCheck %s -check-prefix=UNOPT
+
+
+ define i32 @test(i32 %a) nounwind {
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199024-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199024-sparc.diff
new file mode 100644
index 0000000..35bfc2b
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199024-sparc.diff
@@ -0,0 +1,69 @@
+Pull in r199024 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add missing processor types: v7 and niagara
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/Sparc.td
+===================================================================
+--- lib/Target/Sparc/Sparc.td
++++ lib/Target/Sparc/Sparc.td
+@@ -56,6 +56,7 @@ class Proc<string Name, list<SubtargetFeature> Fea
+ : Processor<Name, NoItineraries, Features>;
+
+ def : Proc<"generic", []>;
++def : Proc<"v7", []>;
+ def : Proc<"v8", []>;
+ def : Proc<"supersparc", []>;
+ def : Proc<"sparclite", []>;
+@@ -67,7 +68,10 @@ def : Proc<"tsc701", []>;
+ def : Proc<"v9", [FeatureV9]>;
+ def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated]>;
+ def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>;
+-def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>;
++def : Proc<"niagara", [FeatureV9, FeatureV8Deprecated]>;
++def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated]>;
++def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated]>;
++def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated]>;
+
+ def SparcAsmWriter : AsmWriter {
+ string AsmWriterClassName = "InstPrinter";
+Index: lib/Target/Sparc/SparcSubtarget.cpp
+===================================================================
+--- lib/Target/Sparc/SparcSubtarget.cpp
++++ lib/Target/Sparc/SparcSubtarget.cpp
+@@ -35,13 +35,8 @@ SparcSubtarget::SparcSubtarget(const std::string &
+
+ // Determine default and user specified characteristics
+ std::string CPUName = CPU;
+- if (CPUName.empty()) {
+- if (is64Bit)
+- CPUName = "v9";
+- else
+- CPUName = "v8";
+- }
+- IsV9 = CPUName == "v9";
++ if (CPUName.empty())
++ CPUName = (is64Bit) ? "v9" : "v8";
+
+ // Parse features string.
+ ParseSubtargetFeatures(CPUName, FS);
+Index: test/CodeGen/SPARC/ctpop.ll
+===================================================================
+--- test/CodeGen/SPARC/ctpop.ll
++++ test/CodeGen/SPARC/ctpop.ll
+@@ -1,6 +1,13 @@
+ ; RUN: llc < %s -march=sparc -mattr=-v9 | FileCheck %s -check-prefix=V8
+ ; RUN: llc < %s -march=sparc -mattr=+v9 | FileCheck %s -check-prefix=V9
+-; RUN: llc < %s -march=sparcv9 | FileCheck %s -check-prefix=SPARC64
++; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparc -mcpu=ultrasparc | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparc -mcpu=niagara | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparc -mcpu=niagara2 | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparc -mcpu=niagara3 | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparc -mcpu=niagara4 | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparcv9 | FileCheck %s -check-prefix=SPARC64
+
+ declare i32 @llvm.ctpop.i32(i32)
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199028-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199028-sparc.diff
new file mode 100644
index 0000000..78bcc61
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199028-sparc.diff
@@ -0,0 +1,147 @@
+Pull in r199028 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ The SPARCv9 ABI returns a float in %f0.
+
+ This is different from the argument passing convention which puts the
+ first float argument in %f1.
+
+ With this patch, all returned floats are treated as if the 'inreg' flag
+ were set. This means multiple float return values get packed in %f0,
+ %f1, %f2, ...
+
+ Note that when returning a struct in registers, clang will set the
+ 'inreg' flag on the return value, so that behavior is unchanged. This
+ also happens when returning a float _Complex.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/CodeGen/SPARC/64abi.ll
+===================================================================
+--- test/CodeGen/SPARC/64abi.ll
++++ test/CodeGen/SPARC/64abi.ll
+@@ -180,7 +180,7 @@ define void @call_inreg_fi(i32* %p, i32 %i1, float
+ }
+
+ ; CHECK: inreg_ff
+-; CHECK: fsubs %f0, %f1, %f1
++; CHECK: fsubs %f0, %f1, %f0
+ define float @inreg_ff(float inreg %a0, ; %f0
+ float inreg %a1) { ; %f1
+ %rv = fsub float %a0, %a1
+@@ -262,10 +262,10 @@ define void @call_ret_i64_pair(i64* %i0) {
+ ret void
+ }
+
+-; This is not a C struct, each member uses 8 bytes.
++; This is not a C struct, the i32 member uses 8 bytes, but the float only 4.
+ ; CHECK: ret_i32_float_pair
+ ; CHECK: ld [%i2], %i0
+-; CHECK: ld [%i3], %f3
++; CHECK: ld [%i3], %f2
+ define { i32, float } @ret_i32_float_pair(i32 %a0, i32 %a1,
+ i32* %p, float* %q) {
+ %r1 = load i32* %p
+@@ -279,7 +279,7 @@ define { i32, float } @ret_i32_float_pair(i32 %a0,
+ ; CHECK: call_ret_i32_float_pair
+ ; CHECK: call ret_i32_float_pair
+ ; CHECK: st %o0, [%i0]
+-; CHECK: st %f3, [%i1]
++; CHECK: st %f2, [%i1]
+ define void @call_ret_i32_float_pair(i32* %i0, float* %i1) {
+ %rv = call { i32, float } @ret_i32_float_pair(i32 undef, i32 undef,
+ i32* undef, float* undef)
+Index: test/CodeGen/SPARC/constpool.ll
+===================================================================
+--- test/CodeGen/SPARC/constpool.ll
++++ test/CodeGen/SPARC/constpool.ll
+@@ -21,7 +21,7 @@ entry:
+ ; abs44: add %[[R1]], %m44(.LCPI0_0), %[[R2:[gilo][0-7]]]
+ ; abs44: sllx %[[R2]], 12, %[[R3:[gilo][0-7]]]
+ ; abs44: retl
+-; abs44: ld [%[[R3]]+%l44(.LCPI0_0)], %f1
++; abs44: ld [%[[R3]]+%l44(.LCPI0_0)], %f0
+
+
+ ; abs64: floatCP
+@@ -31,7 +31,7 @@ entry:
+ ; abs64: add %[[R3]], %hm(.LCPI0_0), %[[R4:[gilo][0-7]]]
+ ; abs64: sllx %[[R4]], 32, %[[R5:[gilo][0-7]]]
+ ; abs64: retl
+-; abs64: ld [%[[R5]]+%[[R2]]], %f1
++; abs64: ld [%[[R5]]+%[[R2]]], %f0
+
+
+ ; v8pic32: floatCP
+@@ -50,7 +50,7 @@ entry:
+ ; v9pic32: sethi %hi(.LCPI0_0), %[[R1:[gilo][0-7]]]
+ ; v9pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]]
+ ; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]]
+-; v9pic32: ld [%[[Gaddr]]], %f1
++; v9pic32: ld [%[[Gaddr]]], %f0
+ ; v9pic32: ret
+ ; v9pic32: restore
+
+Index: test/CodeGen/SPARC/64cond.ll
+===================================================================
+--- test/CodeGen/SPARC/64cond.ll
++++ test/CodeGen/SPARC/64cond.ll
+@@ -80,7 +80,7 @@ entry:
+ ; CHECK: selectf32_xcc
+ ; CHECK: cmp %i0, %i1
+ ; CHECK: fmovsg %xcc, %f5, %f7
+-; CHECK: fmovs %f7, %f1
++; CHECK: fmovs %f7, %f0
+ define float @selectf32_xcc(i64 %x, i64 %y, float %a, float %b) {
+ entry:
+ %tobool = icmp sgt i64 %x, %y
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -254,7 +254,7 @@ SparcTargetLowering::LowerReturn_64(SDValue Chain,
+ DAG.getTarget(), RVLocs, *DAG.getContext());
+
+ // Analyze return values.
+- CCInfo.AnalyzeReturn(Outs, CC_Sparc64);
++ CCInfo.AnalyzeReturn(Outs, RetCC_Sparc64);
+
+ SDValue Flag;
+ SmallVector<SDValue, 4> RetOps(1, Chain);
+@@ -1258,7 +1258,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::
+ if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && CLI.CS == 0)
+ CLI.Ins[0].Flags.setInReg();
+
+- RVInfo.AnalyzeCallResult(CLI.Ins, CC_Sparc64);
++ RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_Sparc64);
+
+ // Copy all of the result registers out of their specified physreg.
+ for (unsigned i = 0; i != RVLocs.size(); ++i) {
+Index: lib/Target/Sparc/SparcCallingConv.td
+===================================================================
+--- lib/Target/Sparc/SparcCallingConv.td
++++ lib/Target/Sparc/SparcCallingConv.td
+@@ -103,7 +103,7 @@ def RetCC_Sparc32 : CallingConv<[
+ // Function return values are passed exactly like function arguments, except a
+ // struct up to 32 bytes in size can be returned in registers.
+
+-// Function arguments AND return values.
++// Function arguments AND most return values.
+ def CC_Sparc64 : CallingConv<[
+ // The frontend uses the inreg flag to indicate i32 and float arguments from
+ // structs. These arguments are not promoted to 64 bits, but they can still
+@@ -118,6 +118,15 @@ def CC_Sparc64 : CallingConv<[
+ CCCustom<"CC_Sparc64_Full">
+ ]>;
+
++def RetCC_Sparc64 : CallingConv<[
++ // A single f32 return value always goes in %f0. The ABI doesn't specify what
++ // happens to multiple f32 return values outside a struct.
++ CCIfType<[f32], CCCustom<"CC_Sparc64_Half">>,
++
++ // Otherwise, return values are passed exactly like arguments.
++ CCDelegateTo<CC_Sparc64>
++]>;
++
+ // Callee-saved registers are handled by the register window mechanism.
+ def CSR : CalleeSavedRegs<(add)> {
+ let OtherPreserved = (add (sequence "I%u", 0, 7),
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199031-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199031-sparc.diff
new file mode 100644
index 0000000..5eb9549
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199031-sparc.diff
@@ -0,0 +1,42 @@
+Pull in r199031 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Replace (unsigned)-1 with ~OU as suggested by Reid Kleckner.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+===================================================================
+--- lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
++++ lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+@@ -104,14 +104,14 @@ static const unsigned DFPRegDecoderTable[] = {
+ SP::D14, SP::D30, SP::D15, SP::D31 };
+
+ static const unsigned QFPRegDecoderTable[] = {
+- SP::Q0, SP::Q8, (unsigned)-1, (unsigned)-1,
+- SP::Q1, SP::Q9, (unsigned)-1, (unsigned)-1,
+- SP::Q2, SP::Q10, (unsigned)-1, (unsigned)-1,
+- SP::Q3, SP::Q11, (unsigned)-1, (unsigned)-1,
+- SP::Q4, SP::Q12, (unsigned)-1, (unsigned)-1,
+- SP::Q5, SP::Q13, (unsigned)-1, (unsigned)-1,
+- SP::Q6, SP::Q14, (unsigned)-1, (unsigned)-1,
+- SP::Q7, SP::Q15, (unsigned)-1, (unsigned)-1 } ;
++ SP::Q0, SP::Q8, ~0U, ~0U,
++ SP::Q1, SP::Q9, ~0U, ~0U,
++ SP::Q2, SP::Q10, ~0U, ~0U,
++ SP::Q3, SP::Q11, ~0U, ~0U,
++ SP::Q4, SP::Q12, ~0U, ~0U,
++ SP::Q5, SP::Q13, ~0U, ~0U,
++ SP::Q6, SP::Q14, ~0U, ~0U,
++ SP::Q7, SP::Q15, ~0U, ~0U } ;
+
+ static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+@@ -168,7 +168,7 @@ static DecodeStatus DecodeQFPRegsRegisterClass(MCI
+ return MCDisassembler::Fail;
+
+ unsigned Reg = QFPRegDecoderTable[RegNo];
+- if (Reg == (unsigned)-1)
++ if (Reg == ~0U)
+ return MCDisassembler::Fail;
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ return MCDisassembler::Success;
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff
new file mode 100644
index 0000000..c4b3438
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199033-sparc.diff
@@ -0,0 +1,944 @@
+Pull in r199033 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add support for parsing floating point instructions.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -601,91 +601,91 @@ let Defs = [Y], rd = 0 in {
+ }
+ // Convert Integer to Floating-point Instructions, p. 141
+ def FITOS : F3_3u<2, 0b110100, 0b011000100,
+- (outs FPRegs:$dst), (ins FPRegs:$src),
+- "fitos $src, $dst",
+- [(set FPRegs:$dst, (SPitof FPRegs:$src))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs2),
++ "fitos $rs2, $rd",
++ [(set FPRegs:$rd, (SPitof FPRegs:$rs2))]>;
+ def FITOD : F3_3u<2, 0b110100, 0b011001000,
+- (outs DFPRegs:$dst), (ins FPRegs:$src),
+- "fitod $src, $dst",
+- [(set DFPRegs:$dst, (SPitof FPRegs:$src))]>;
++ (outs DFPRegs:$rd), (ins FPRegs:$rs2),
++ "fitod $rs2, $rd",
++ [(set DFPRegs:$rd, (SPitof FPRegs:$rs2))]>;
+ def FITOQ : F3_3u<2, 0b110100, 0b011001100,
+- (outs QFPRegs:$dst), (ins FPRegs:$src),
+- "fitoq $src, $dst",
+- [(set QFPRegs:$dst, (SPitof FPRegs:$src))]>,
++ (outs QFPRegs:$rd), (ins FPRegs:$rs2),
++ "fitoq $rs2, $rd",
++ [(set QFPRegs:$rd, (SPitof FPRegs:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+ // Convert Floating-point to Integer Instructions, p. 142
+ def FSTOI : F3_3u<2, 0b110100, 0b011010001,
+- (outs FPRegs:$dst), (ins FPRegs:$src),
+- "fstoi $src, $dst",
+- [(set FPRegs:$dst, (SPftoi FPRegs:$src))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs2),
++ "fstoi $rs2, $rd",
++ [(set FPRegs:$rd, (SPftoi FPRegs:$rs2))]>;
+ def FDTOI : F3_3u<2, 0b110100, 0b011010010,
+- (outs FPRegs:$dst), (ins DFPRegs:$src),
+- "fdtoi $src, $dst",
+- [(set FPRegs:$dst, (SPftoi DFPRegs:$src))]>;
++ (outs FPRegs:$rd), (ins DFPRegs:$rs2),
++ "fdtoi $rs2, $rd",
++ [(set FPRegs:$rd, (SPftoi DFPRegs:$rs2))]>;
+ def FQTOI : F3_3u<2, 0b110100, 0b011010011,
+- (outs FPRegs:$dst), (ins QFPRegs:$src),
+- "fqtoi $src, $dst",
+- [(set FPRegs:$dst, (SPftoi QFPRegs:$src))]>,
++ (outs FPRegs:$rd), (ins QFPRegs:$rs2),
++ "fqtoi $rs2, $rd",
++ [(set FPRegs:$rd, (SPftoi QFPRegs:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+ // Convert between Floating-point Formats Instructions, p. 143
+ def FSTOD : F3_3u<2, 0b110100, 0b011001001,
+- (outs DFPRegs:$dst), (ins FPRegs:$src),
+- "fstod $src, $dst",
+- [(set f64:$dst, (fextend f32:$src))]>;
++ (outs DFPRegs:$rd), (ins FPRegs:$rs2),
++ "fstod $rs2, $rd",
++ [(set f64:$rd, (fextend f32:$rs2))]>;
+ def FSTOQ : F3_3u<2, 0b110100, 0b011001101,
+- (outs QFPRegs:$dst), (ins FPRegs:$src),
+- "fstoq $src, $dst",
+- [(set f128:$dst, (fextend f32:$src))]>,
++ (outs QFPRegs:$rd), (ins FPRegs:$rs2),
++ "fstoq $rs2, $rd",
++ [(set f128:$rd, (fextend f32:$rs2))]>,
+ Requires<[HasHardQuad]>;
+ def FDTOS : F3_3u<2, 0b110100, 0b011000110,
+- (outs FPRegs:$dst), (ins DFPRegs:$src),
+- "fdtos $src, $dst",
+- [(set f32:$dst, (fround f64:$src))]>;
+-def FDTOQ : F3_3u<2, 0b110100, 0b01101110,
+- (outs QFPRegs:$dst), (ins DFPRegs:$src),
+- "fdtoq $src, $dst",
+- [(set f128:$dst, (fextend f64:$src))]>,
++ (outs FPRegs:$rd), (ins DFPRegs:$rs2),
++ "fdtos $rs2, $rd",
++ [(set f32:$rd, (fround f64:$rs2))]>;
++def FDTOQ : F3_3u<2, 0b110100, 0b011001110,
++ (outs QFPRegs:$rd), (ins DFPRegs:$rs2),
++ "fdtoq $rs2, $rd",
++ [(set f128:$rd, (fextend f64:$rs2))]>,
+ Requires<[HasHardQuad]>;
+ def FQTOS : F3_3u<2, 0b110100, 0b011000111,
+- (outs FPRegs:$dst), (ins QFPRegs:$src),
+- "fqtos $src, $dst",
+- [(set f32:$dst, (fround f128:$src))]>,
++ (outs FPRegs:$rd), (ins QFPRegs:$rs2),
++ "fqtos $rs2, $rd",
++ [(set f32:$rd, (fround f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+ def FQTOD : F3_3u<2, 0b110100, 0b011001011,
+- (outs DFPRegs:$dst), (ins QFPRegs:$src),
+- "fqtod $src, $dst",
+- [(set f64:$dst, (fround f128:$src))]>,
++ (outs DFPRegs:$rd), (ins QFPRegs:$rs2),
++ "fqtod $rs2, $rd",
++ [(set f64:$rd, (fround f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+ // Floating-point Move Instructions, p. 144
+ def FMOVS : F3_3u<2, 0b110100, 0b000000001,
+- (outs FPRegs:$dst), (ins FPRegs:$src),
+- "fmovs $src, $dst", []>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs2),
++ "fmovs $rs2, $rd", []>;
+ def FNEGS : F3_3u<2, 0b110100, 0b000000101,
+- (outs FPRegs:$dst), (ins FPRegs:$src),
+- "fnegs $src, $dst",
+- [(set f32:$dst, (fneg f32:$src))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs2),
++ "fnegs $rs2, $rd",
++ [(set f32:$rd, (fneg f32:$rs2))]>;
+ def FABSS : F3_3u<2, 0b110100, 0b000001001,
+- (outs FPRegs:$dst), (ins FPRegs:$src),
+- "fabss $src, $dst",
+- [(set f32:$dst, (fabs f32:$src))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs2),
++ "fabss $rs2, $rd",
++ [(set f32:$rd, (fabs f32:$rs2))]>;
+
+
+ // Floating-point Square Root Instructions, p.145
+ def FSQRTS : F3_3u<2, 0b110100, 0b000101001,
+- (outs FPRegs:$dst), (ins FPRegs:$src),
+- "fsqrts $src, $dst",
+- [(set f32:$dst, (fsqrt f32:$src))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs2),
++ "fsqrts $rs2, $rd",
++ [(set f32:$rd, (fsqrt f32:$rs2))]>;
+ def FSQRTD : F3_3u<2, 0b110100, 0b000101010,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src),
+- "fsqrtd $src, $dst",
+- [(set f64:$dst, (fsqrt f64:$src))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2),
++ "fsqrtd $rs2, $rd",
++ [(set f64:$rd, (fsqrt f64:$rs2))]>;
+ def FSQRTQ : F3_3u<2, 0b110100, 0b000101011,
+- (outs QFPRegs:$dst), (ins QFPRegs:$src),
+- "fsqrtq $src, $dst",
+- [(set f128:$dst, (fsqrt f128:$src))]>,
++ (outs QFPRegs:$rd), (ins QFPRegs:$rs2),
++ "fsqrtq $rs2, $rd",
++ [(set f128:$rd, (fsqrt f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+
+@@ -692,73 +692,73 @@ def FSQRTQ : F3_3u<2, 0b110100, 0b000101011,
+
+ // Floating-point Add and Subtract Instructions, p. 146
+ def FADDS : F3_3<2, 0b110100, 0b001000001,
+- (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
+- "fadds $src1, $src2, $dst",
+- [(set f32:$dst, (fadd f32:$src1, f32:$src2))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2),
++ "fadds $rs1, $rs2, $rd",
++ [(set f32:$rd, (fadd f32:$rs1, f32:$rs2))]>;
+ def FADDD : F3_3<2, 0b110100, 0b001000010,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
+- "faddd $src1, $src2, $dst",
+- [(set f64:$dst, (fadd f64:$src1, f64:$src2))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2),
++ "faddd $rs1, $rs2, $rd",
++ [(set f64:$rd, (fadd f64:$rs1, f64:$rs2))]>;
+ def FADDQ : F3_3<2, 0b110100, 0b001000011,
+- (outs QFPRegs:$dst), (ins QFPRegs:$src1, QFPRegs:$src2),
+- "faddq $src1, $src2, $dst",
+- [(set f128:$dst, (fadd f128:$src1, f128:$src2))]>,
++ (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2),
++ "faddq $rs1, $rs2, $rd",
++ [(set f128:$rd, (fadd f128:$rs1, f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+ def FSUBS : F3_3<2, 0b110100, 0b001000101,
+- (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
+- "fsubs $src1, $src2, $dst",
+- [(set f32:$dst, (fsub f32:$src1, f32:$src2))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2),
++ "fsubs $rs1, $rs2, $rd",
++ [(set f32:$rd, (fsub f32:$rs1, f32:$rs2))]>;
+ def FSUBD : F3_3<2, 0b110100, 0b001000110,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
+- "fsubd $src1, $src2, $dst",
+- [(set f64:$dst, (fsub f64:$src1, f64:$src2))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2),
++ "fsubd $rs1, $rs2, $rd",
++ [(set f64:$rd, (fsub f64:$rs1, f64:$rs2))]>;
+ def FSUBQ : F3_3<2, 0b110100, 0b001000111,
+- (outs QFPRegs:$dst), (ins QFPRegs:$src1, QFPRegs:$src2),
+- "fsubq $src1, $src2, $dst",
+- [(set f128:$dst, (fsub f128:$src1, f128:$src2))]>,
++ (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2),
++ "fsubq $rs1, $rs2, $rd",
++ [(set f128:$rd, (fsub f128:$rs1, f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+
+ // Floating-point Multiply and Divide Instructions, p. 147
+ def FMULS : F3_3<2, 0b110100, 0b001001001,
+- (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
+- "fmuls $src1, $src2, $dst",
+- [(set f32:$dst, (fmul f32:$src1, f32:$src2))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2),
++ "fmuls $rs1, $rs2, $rd",
++ [(set f32:$rd, (fmul f32:$rs1, f32:$rs2))]>;
+ def FMULD : F3_3<2, 0b110100, 0b001001010,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
+- "fmuld $src1, $src2, $dst",
+- [(set f64:$dst, (fmul f64:$src1, f64:$src2))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2),
++ "fmuld $rs1, $rs2, $rd",
++ [(set f64:$rd, (fmul f64:$rs1, f64:$rs2))]>;
+ def FMULQ : F3_3<2, 0b110100, 0b001001011,
+- (outs QFPRegs:$dst), (ins QFPRegs:$src1, QFPRegs:$src2),
+- "fmulq $src1, $src2, $dst",
+- [(set f128:$dst, (fmul f128:$src1, f128:$src2))]>,
++ (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2),
++ "fmulq $rs1, $rs2, $rd",
++ [(set f128:$rd, (fmul f128:$rs1, f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+ def FSMULD : F3_3<2, 0b110100, 0b001101001,
+- (outs DFPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
+- "fsmuld $src1, $src2, $dst",
+- [(set f64:$dst, (fmul (fextend f32:$src1),
+- (fextend f32:$src2)))]>;
++ (outs DFPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2),
++ "fsmuld $rs1, $rs2, $rd",
++ [(set f64:$rd, (fmul (fextend f32:$rs1),
++ (fextend f32:$rs2)))]>;
+ def FDMULQ : F3_3<2, 0b110100, 0b001101110,
+- (outs QFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
+- "fdmulq $src1, $src2, $dst",
+- [(set f128:$dst, (fmul (fextend f64:$src1),
+- (fextend f64:$src2)))]>,
++ (outs QFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2),
++ "fdmulq $rs1, $rs2, $rd",
++ [(set f128:$rd, (fmul (fextend f64:$rs1),
++ (fextend f64:$rs2)))]>,
+ Requires<[HasHardQuad]>;
+
+ def FDIVS : F3_3<2, 0b110100, 0b001001101,
+- (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
+- "fdivs $src1, $src2, $dst",
+- [(set f32:$dst, (fdiv f32:$src1, f32:$src2))]>;
++ (outs FPRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2),
++ "fdivs $rs1, $rs2, $rd",
++ [(set f32:$rd, (fdiv f32:$rs1, f32:$rs2))]>;
+ def FDIVD : F3_3<2, 0b110100, 0b001001110,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
+- "fdivd $src1, $src2, $dst",
+- [(set f64:$dst, (fdiv f64:$src1, f64:$src2))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2),
++ "fdivd $rs1, $rs2, $rd",
++ [(set f64:$rd, (fdiv f64:$rs1, f64:$rs2))]>;
+ def FDIVQ : F3_3<2, 0b110100, 0b001001111,
+- (outs QFPRegs:$dst), (ins QFPRegs:$src1, QFPRegs:$src2),
+- "fdivq $src1, $src2, $dst",
+- [(set f128:$dst, (fdiv f128:$src1, f128:$src2))]>,
++ (outs QFPRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2),
++ "fdivq $rs1, $rs2, $rd",
++ [(set f128:$rd, (fdiv f128:$rs1, f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+ // Floating-point Compare Instructions, p. 148
+@@ -770,17 +770,17 @@ def FDIVQ : F3_3<2, 0b110100, 0b001001111,
+
+ let Defs = [FCC] in {
+ def FCMPS : F3_3c<2, 0b110101, 0b001010001,
+- (outs), (ins FPRegs:$src1, FPRegs:$src2),
+- "fcmps $src1, $src2",
+- [(SPcmpfcc f32:$src1, f32:$src2)]>;
++ (outs), (ins FPRegs:$rs1, FPRegs:$rs2),
++ "fcmps $rs1, $rs2",
++ [(SPcmpfcc f32:$rs1, f32:$rs2)]>;
+ def FCMPD : F3_3c<2, 0b110101, 0b001010010,
+- (outs), (ins DFPRegs:$src1, DFPRegs:$src2),
+- "fcmpd $src1, $src2",
+- [(SPcmpfcc f64:$src1, f64:$src2)]>;
++ (outs), (ins DFPRegs:$rs1, DFPRegs:$rs2),
++ "fcmpd $rs1, $rs2",
++ [(SPcmpfcc f64:$rs1, f64:$rs2)]>;
+ def FCMPQ : F3_3c<2, 0b110101, 0b001010011,
+- (outs), (ins QFPRegs:$src1, QFPRegs:$src2),
+- "fcmpq $src1, $src2",
+- [(SPcmpfcc f128:$src1, f128:$src2)]>,
++ (outs), (ins QFPRegs:$rs1, QFPRegs:$rs2),
++ "fcmpq $rs1, $rs2",
++ [(SPcmpfcc f128:$rs1, f128:$rs2)]>,
+ Requires<[HasHardQuad]>;
+ }
+
+@@ -892,29 +892,29 @@ let Predicates = [HasV9], Constraints = "$f = $rd"
+ // Floating-Point Move Instructions, p. 164 of the V9 manual.
+ let Predicates = [HasV9] in {
+ def FMOVD : F3_3u<2, 0b110100, 0b000000010,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src),
+- "fmovd $src, $dst", []>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2),
++ "fmovd $rs2, $rd", []>;
+ def FMOVQ : F3_3u<2, 0b110100, 0b000000011,
+- (outs QFPRegs:$dst), (ins QFPRegs:$src),
+- "fmovq $src, $dst", []>,
++ (outs QFPRegs:$rd), (ins QFPRegs:$rs2),
++ "fmovq $rs2, $rd", []>,
+ Requires<[HasHardQuad]>;
+ def FNEGD : F3_3u<2, 0b110100, 0b000000110,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src),
+- "fnegd $src, $dst",
+- [(set f64:$dst, (fneg f64:$src))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2),
++ "fnegd $rs2, $rd",
++ [(set f64:$rd, (fneg f64:$rs2))]>;
+ def FNEGQ : F3_3u<2, 0b110100, 0b000000111,
+- (outs QFPRegs:$dst), (ins QFPRegs:$src),
+- "fnegq $src, $dst",
+- [(set f128:$dst, (fneg f128:$src))]>,
++ (outs QFPRegs:$rd), (ins QFPRegs:$rs2),
++ "fnegq $rs2, $rd",
++ [(set f128:$rd, (fneg f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+ def FABSD : F3_3u<2, 0b110100, 0b000001010,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src),
+- "fabsd $src, $dst",
+- [(set f64:$dst, (fabs f64:$src))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2),
++ "fabsd $rs2, $rd",
++ [(set f64:$rd, (fabs f64:$rs2))]>;
+ def FABSQ : F3_3u<2, 0b110100, 0b000001011,
+- (outs QFPRegs:$dst), (ins QFPRegs:$src),
+- "fabsq $src, $dst",
+- [(set f128:$dst, (fabs f128:$src))]>,
++ (outs QFPRegs:$rd), (ins QFPRegs:$rs2),
++ "fabsq $rs2, $rd",
++ [(set f128:$rd, (fabs f128:$rs2))]>,
+ Requires<[HasHardQuad]>;
+ }
+
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -54,6 +54,8 @@ class SparcAsmParser : public MCTargetAsmParser {
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+ bool ParseDirective(AsmToken DirectiveID);
+
++ virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
++ unsigned Kind);
+
+ // Custom parse functions for Sparc specific operands.
+ OperandMatchResultTy
+@@ -67,8 +69,9 @@ class SparcAsmParser : public MCTargetAsmParser {
+ parseSparcAsmOperand(SparcOperand *&Operand);
+
+ // returns true if Tok is matched to a register and returns register in RegNo.
+- bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
+- bool isQFP);
++ bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
++ unsigned &RegKind);
++
+ bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
+
+ public:
+@@ -178,6 +181,16 @@ class SparcOperand : public MCParsedAsmOperand {
+ bool isMEMrr() const { return Kind == k_MemoryReg; }
+ bool isMEMri() const { return Kind == k_MemoryImm; }
+
++ bool isFloatReg() const {
++ return (Kind == k_Register && Reg.Kind == rk_FloatReg);
++ }
++
++ bool isFloatOrDoubleReg() const {
++ return (Kind == k_Register && (Reg.Kind == rk_FloatReg
++ || Reg.Kind == rk_DoubleReg));
++ }
++
++
+ StringRef getToken() const {
+ assert(Kind == k_Token && "Invalid access!");
+ return StringRef(Tok.Data, Tok.Length);
+@@ -280,11 +293,11 @@ class SparcOperand : public MCParsedAsmOperand {
+ }
+
+ static SparcOperand *CreateReg(unsigned RegNum,
+- SparcOperand::RegisterKind Kind,
++ unsigned Kind,
+ SMLoc S, SMLoc E) {
+ SparcOperand *Op = new SparcOperand(k_Register);
+ Op->Reg.RegNum = RegNum;
+- Op->Reg.Kind = Kind;
++ Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
+ Op->StartLoc = S;
+ Op->EndLoc = E;
+ return Op;
+@@ -298,6 +311,40 @@ class SparcOperand : public MCParsedAsmOperand {
+ return Op;
+ }
+
++ static SparcOperand *MorphToDoubleReg(SparcOperand *Op) {
++ unsigned Reg = Op->getReg();
++ assert(Op->Reg.Kind == rk_FloatReg);
++ unsigned regIdx = Reg - Sparc::F0;
++ if (regIdx % 2 || regIdx > 31)
++ return 0;
++ Op->Reg.RegNum = DoubleRegs[regIdx / 2];
++ Op->Reg.Kind = rk_DoubleReg;
++ return Op;
++ }
++
++ static SparcOperand *MorphToQuadReg(SparcOperand *Op) {
++ unsigned Reg = Op->getReg();
++ unsigned regIdx = 0;
++ switch (Op->Reg.Kind) {
++ default: assert(0 && "Unexpected register kind!");
++ case rk_FloatReg:
++ regIdx = Reg - Sparc::F0;
++ if (regIdx % 4 || regIdx > 31)
++ return 0;
++ Reg = QuadFPRegs[regIdx / 4];
++ break;
++ case rk_DoubleReg:
++ regIdx = Reg - Sparc::D0;
++ if (regIdx % 2 || regIdx > 31)
++ return 0;
++ Reg = QuadFPRegs[regIdx / 2];
++ break;
++ }
++ Op->Reg.RegNum = Reg;
++ Op->Reg.Kind = rk_QuadReg;
++ return Op;
++ }
++
+ static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
+ unsigned offsetReg = Op->getReg();
+ Op->Kind = k_MemoryReg;
+@@ -383,7 +430,8 @@ ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SM
+ if (getLexer().getKind() != AsmToken::Percent)
+ return false;
+ Parser.Lex();
+- if (matchRegisterName(Tok, RegNo, false, false)) {
++ unsigned regKind = SparcOperand::rk_None;
++ if (matchRegisterName(Tok, RegNo, regKind)) {
+ Parser.Lex();
+ return false;
+ }
+@@ -537,13 +585,14 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
+ case AsmToken::Percent:
+ Parser.Lex(); // Eat the '%'.
+ unsigned RegNo;
+- if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
++ unsigned RegKind;
++ if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
+ StringRef name = Parser.getTok().getString();
+ Parser.Lex(); // Eat the identifier token.
+ E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ switch (RegNo) {
+ default:
+- Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
++ Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
+ break;
+ case Sparc::Y:
+ Op = SparcOperand::CreateToken("%y", S);
+@@ -593,11 +642,11 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
+
+ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
+ unsigned &RegNo,
+- bool isDFP,
+- bool isQFP)
++ unsigned &RegKind)
+ {
+ int64_t intVal = 0;
+ RegNo = 0;
++ RegKind = SparcOperand::rk_None;
+ if (Tok.is(AsmToken::Identifier)) {
+ StringRef name = Tok.getString();
+
+@@ -604,21 +653,25 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ // %fp
+ if (name.equals("fp")) {
+ RegNo = Sparc::I6;
++ RegKind = SparcOperand::rk_IntReg;
+ return true;
+ }
+ // %sp
+ if (name.equals("sp")) {
+ RegNo = Sparc::O6;
++ RegKind = SparcOperand::rk_IntReg;
+ return true;
+ }
+
+ if (name.equals("y")) {
+ RegNo = Sparc::Y;
++ RegKind = SparcOperand::rk_Y;
+ return true;
+ }
+
+ if (name.equals("icc")) {
+ RegNo = Sparc::ICC;
++ RegKind = SparcOperand::rk_CCReg;
+ return true;
+ }
+
+@@ -625,6 +678,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ if (name.equals("xcc")) {
+ // FIXME:: check 64bit.
+ RegNo = Sparc::ICC;
++ RegKind = SparcOperand::rk_CCReg;
+ return true;
+ }
+
+@@ -634,6 +688,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ && intVal < 4) {
+ // FIXME: check 64bit and handle %fcc1 - %fcc3
+ RegNo = Sparc::FCC;
++ RegKind = SparcOperand::rk_CCReg;
+ return true;
+ }
+
+@@ -642,6 +697,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ && !name.substr(1).getAsInteger(10, intVal)
+ && intVal < 8) {
+ RegNo = IntRegs[intVal];
++ RegKind = SparcOperand::rk_IntReg;
+ return true;
+ }
+ // %o0 - %o7
+@@ -649,6 +705,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ && !name.substr(1).getAsInteger(10, intVal)
+ && intVal < 8) {
+ RegNo = IntRegs[8 + intVal];
++ RegKind = SparcOperand::rk_IntReg;
+ return true;
+ }
+ if (name.substr(0, 1).equals_lower("l")
+@@ -655,6 +712,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ && !name.substr(1).getAsInteger(10, intVal)
+ && intVal < 8) {
+ RegNo = IntRegs[16 + intVal];
++ RegKind = SparcOperand::rk_IntReg;
+ return true;
+ }
+ if (name.substr(0, 1).equals_lower("i")
+@@ -661,18 +719,14 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ && !name.substr(1).getAsInteger(10, intVal)
+ && intVal < 8) {
+ RegNo = IntRegs[24 + intVal];
++ RegKind = SparcOperand::rk_IntReg;
+ return true;
+ }
+ // %f0 - %f31
+ if (name.substr(0, 1).equals_lower("f")
+ && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
+- if (isDFP && (intVal%2 == 0)) {
+- RegNo = DoubleRegs[intVal/2];
+- } else if (isQFP && (intVal%4 == 0)) {
+- RegNo = QuadFPRegs[intVal/4];
+- } else {
+- RegNo = FloatRegs[intVal];
+- }
++ RegNo = FloatRegs[intVal];
++ RegKind = SparcOperand::rk_FloatReg;
+ return true;
+ }
+ // %f32 - %f62
+@@ -679,13 +733,9 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ if (name.substr(0, 1).equals_lower("f")
+ && !name.substr(1, 2).getAsInteger(10, intVal)
+ && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
+- if (isDFP) {
+- RegNo = DoubleRegs[16 + intVal/2];
+- } else if (isQFP && (intVal % 4 == 0)) {
+- RegNo = QuadFPRegs[8 + intVal/4];
+- } else {
+- return false;
+- }
++ // FIXME: Check V9
++ RegNo = DoubleRegs[16 + intVal/2];
++ RegKind = SparcOperand::rk_DoubleReg;
+ return true;
+ }
+
+@@ -693,6 +743,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ if (name.substr(0, 1).equals_lower("r")
+ && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
+ RegNo = IntRegs[intVal];
++ RegKind = SparcOperand::rk_IntReg;
+ return true;
+ }
+ }
+@@ -735,3 +786,26 @@ extern "C" void LLVMInitializeSparcAsmParser() {
+ #define GET_REGISTER_MATCHER
+ #define GET_MATCHER_IMPLEMENTATION
+ #include "SparcGenAsmMatcher.inc"
++
++
++
++unsigned SparcAsmParser::
++validateTargetOperandClass(MCParsedAsmOperand *GOp,
++ unsigned Kind)
++{
++ SparcOperand *Op = (SparcOperand*)GOp;
++ if (Op->isFloatOrDoubleReg()) {
++ switch (Kind) {
++ default: break;
++ case MCK_DFPRegs:
++ if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
++ return MCTargetAsmParser::Match_Success;
++ break;
++ case MCK_QFPRegs:
++ if (SparcOperand::MorphToQuadReg(Op))
++ return MCTargetAsmParser::Match_Success;
++ break;
++ }
++ }
++ return Match_InvalidOperand;
++}
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -358,31 +358,31 @@ def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFP
+ let Predicates = [Is64Bit] in {
+
+ def FXTOS : F3_3u<2, 0b110100, 0b010000100,
+- (outs FPRegs:$dst), (ins DFPRegs:$src),
+- "fxtos $src, $dst",
+- [(set FPRegs:$dst, (SPxtof DFPRegs:$src))]>;
++ (outs FPRegs:$rd), (ins DFPRegs:$rs2),
++ "fxtos $rs2, $rd",
++ [(set FPRegs:$rd, (SPxtof DFPRegs:$rs2))]>;
+ def FXTOD : F3_3u<2, 0b110100, 0b010001000,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src),
+- "fxtod $src, $dst",
+- [(set DFPRegs:$dst, (SPxtof DFPRegs:$src))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2),
++ "fxtod $rs2, $rd",
++ [(set DFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>;
+ def FXTOQ : F3_3u<2, 0b110100, 0b010001100,
+- (outs QFPRegs:$dst), (ins DFPRegs:$src),
+- "fxtoq $src, $dst",
+- [(set QFPRegs:$dst, (SPxtof DFPRegs:$src))]>,
++ (outs QFPRegs:$rd), (ins DFPRegs:$rs2),
++ "fxtoq $rs2, $rd",
++ [(set QFPRegs:$rd, (SPxtof DFPRegs:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+ def FSTOX : F3_3u<2, 0b110100, 0b010000001,
+- (outs DFPRegs:$dst), (ins FPRegs:$src),
+- "fstox $src, $dst",
+- [(set DFPRegs:$dst, (SPftox FPRegs:$src))]>;
++ (outs DFPRegs:$rd), (ins FPRegs:$rs2),
++ "fstox $rs2, $rd",
++ [(set DFPRegs:$rd, (SPftox FPRegs:$rs2))]>;
+ def FDTOX : F3_3u<2, 0b110100, 0b010000010,
+- (outs DFPRegs:$dst), (ins DFPRegs:$src),
+- "fdtox $src, $dst",
+- [(set DFPRegs:$dst, (SPftox DFPRegs:$src))]>;
++ (outs DFPRegs:$rd), (ins DFPRegs:$rs2),
++ "fdtox $rs2, $rd",
++ [(set DFPRegs:$rd, (SPftox DFPRegs:$rs2))]>;
+ def FQTOX : F3_3u<2, 0b110100, 0b010000011,
+- (outs DFPRegs:$dst), (ins QFPRegs:$src),
+- "fqtox $src, $dst",
+- [(set DFPRegs:$dst, (SPftox QFPRegs:$src))]>,
++ (outs DFPRegs:$rd), (ins QFPRegs:$rs2),
++ "fqtox $rs2, $rd",
++ [(set DFPRegs:$rd, (SPftox QFPRegs:$rs2))]>,
+ Requires<[HasHardQuad]>;
+
+ } // Predicates = [Is64Bit]
+Index: test/MC/Disassembler/Sparc/sparc-fp.txt
+===================================================================
+--- test/MC/Disassembler/Sparc/sparc-fp.txt
++++ test/MC/Disassembler/Sparc/sparc-fp.txt
+@@ -0,0 +1,142 @@
++# RUN: llvm-mc --disassemble %s -triple=sparc64-linux-gnu | FileCheck %s
++
++
++# CHECK: fitos %f0, %f4
++0x89 0xa0 0x18 0x80
++
++# CHECK: fitod %f0, %f4
++0x89 0xa0 0x19 0x00
++
++# CHECK: fitoq %f0, %f4
++0x89 0xa0 0x19 0x80
++
++# CHECK: fstoi %f0, %f4
++0x89 0xa0 0x1a 0x20
++
++# CHECK: fdtoi %f0, %f4
++0x89 0xa0 0x1a 0x40
++
++# CHECK: fqtoi %f0, %f4
++0x89 0xa0 0x1a 0x60
++
++# CHECK: fstod %f0, %f4
++0x89 0xa0 0x19 0x20
++# CHECK: fstoq %f0, %f4
++0x89 0xa0 0x19 0xa0
++
++# CHECK: fdtos %f0, %f4
++0x89 0xa0 0x18 0xc0
++
++# CHECK: fdtoq %f0, %f4
++0x89 0xa0 0x19 0xc0
++
++# CHECK: fqtos %f0, %f4
++0x89 0xa0 0x18 0xe0
++
++# CHECK: fqtod %f0, %f4
++0x89 0xa0 0x19 0x60
++
++# CHECK: fmovs %f0, %f4
++0x89 0xa0 0x00 0x20
++
++# CHECK: fmovd %f0, %f4
++0x89 0xa0 0x00 0x40
++
++# CHECK: fmovq %f0, %f4
++0x89 0xa0 0x00 0x60
++
++# CHECK: fnegs %f0, %f4
++0x89 0xa0 0x00 0xa0
++
++# CHECK: fnegd %f0, %f4
++0x89 0xa0 0x00 0xc0
++
++# CHECK: fnegq %f0, %f4
++0x89 0xa0 0x00 0xe0
++
++# CHECK: fabss %f0, %f4
++0x89 0xa0 0x01 0x20
++
++# CHECK: fabsd %f0, %f4
++0x89 0xa0 0x01 0x40
++
++# CHECK: fabsq %f0, %f4
++0x89 0xa0 0x01 0x60
++
++# CHECK: fsqrts %f0, %f4
++0x89 0xa0 0x05 0x20
++
++# CHECK: fsqrtd %f0, %f4
++0x89 0xa0 0x05 0x40
++
++# CHECK: fsqrtq %f0, %f4
++0x89 0xa0 0x05 0x60
++
++# CHECK: fadds %f0, %f4, %f8
++0x91 0xa0 0x08 0x24
++
++# CHECK: faddd %f0, %f4, %f8
++0x91 0xa0 0x08 0x44
++
++# CHECK: faddq %f0, %f4, %f8
++0x91 0xa0 0x08 0x64
++
++# CHECK: fsubs %f0, %f4, %f8
++0x91 0xa0 0x08 0xa4
++
++# CHECK: fsubd %f0, %f4, %f8
++0x91 0xa0 0x08 0xc4
++
++# CHECK: fsubq %f0, %f4, %f8
++0x91 0xa0 0x08 0xe4
++
++# CHECK: fmuls %f0, %f4, %f8
++0x91 0xa0 0x09 0x24
++
++# CHECK: fmuld %f0, %f4, %f8
++0x91 0xa0 0x09 0x44
++
++# CHECK: fmulq %f0, %f4, %f8
++0x91 0xa0 0x09 0x64
++
++# CHECK: fsmuld %f0, %f4, %f8
++0x91 0xa0 0x0d 0x24
++
++# CHECK: fdmulq %f0, %f4, %f8
++0x91 0xa0 0x0d 0xc4
++
++# CHECK: fdivs %f0, %f4, %f8
++0x91 0xa0 0x09 0xa4
++
++# CHECK: fdivd %f0, %f4, %f8
++0x91 0xa0 0x09 0xc4
++
++# CHECK: fdivq %f0, %f4, %f8
++0x91 0xa0 0x09 0xe4
++
++# CHECK: fcmps %f0, %f4
++0x81 0xa8 0x0a 0x24
++
++# CHECK: fcmpd %f0, %f4
++0x81 0xa8 0x0a 0x44
++
++# CHECK: fcmpq %f0, %f4
++0x81 0xa8 0x0a 0x64
++
++# CHECK: fxtos %f0, %f4
++0x89 0xa0 0x10 0x80
++
++# CHECK: fxtod %f0, %f4
++0x89 0xa0 0x11 0x00
++
++# CHECK: fxtoq %f0, %f4
++0x89 0xa0 0x11 0x80
++
++# CHECK: fstox %f0, %f4
++0x89 0xa0 0x10 0x20
++
++# CHECK: fdtox %f0, %f4
++0x89 0xa0 0x10 0x40
++
++# CHECK: fqtox %f0, %f4
++0x89 0xa0 0x10 0x60
+Index: test/MC/Sparc/sparc-fp-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-fp-instructions.s
++++ test/MC/Sparc/sparc-fp-instructions.s
+@@ -0,0 +1,113 @@
++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
++
++ ! CHECK: fitos %f0, %f4 ! encoding: [0x89,0xa0,0x18,0x80]
++ ! CHECK: fitod %f0, %f4 ! encoding: [0x89,0xa0,0x19,0x00]
++ ! CHECK: fitoq %f0, %f4 ! encoding: [0x89,0xa0,0x19,0x80]
++ fitos %f0, %f4
++ fitod %f0, %f4
++ fitoq %f0, %f4
++
++ ! CHECK: fstoi %f0, %f4 ! encoding: [0x89,0xa0,0x1a,0x20]
++ ! CHECK: fdtoi %f0, %f4 ! encoding: [0x89,0xa0,0x1a,0x40]
++ ! CHECK: fqtoi %f0, %f4 ! encoding: [0x89,0xa0,0x1a,0x60]
++ fstoi %f0, %f4
++ fdtoi %f0, %f4
++ fqtoi %f0, %f4
++
++ ! CHECK: fstod %f0, %f4 ! encoding: [0x89,0xa0,0x19,0x20]
++ ! CHECK: fstoq %f0, %f4 ! encoding: [0x89,0xa0,0x19,0xa0]
++ fstod %f0, %f4
++ fstoq %f0, %f4
++
++ ! CHECK: fdtos %f0, %f4 ! encoding: [0x89,0xa0,0x18,0xc0]
++ ! CHECK: fdtoq %f0, %f4 ! encoding: [0x89,0xa0,0x19,0xc0]
++ fdtos %f0, %f4
++ fdtoq %f0, %f4
++
++ ! CHECK: fqtos %f0, %f4 ! encoding: [0x89,0xa0,0x18,0xe0]
++ ! CHECK: fqtod %f0, %f4 ! encoding: [0x89,0xa0,0x19,0x60]
++ fqtos %f0, %f4
++ fqtod %f0, %f4
++
++ ! CHECK: fmovs %f0, %f4 ! encoding: [0x89,0xa0,0x00,0x20]
++ ! CHECK: fmovd %f0, %f4 ! encoding: [0x89,0xa0,0x00,0x40]
++ ! CHECK: fmovq %f0, %f4 ! encoding: [0x89,0xa0,0x00,0x60]
++ fmovs %f0, %f4
++ fmovd %f0, %f4
++ fmovq %f0, %f4
++
++ ! CHECK: fnegs %f0, %f4 ! encoding: [0x89,0xa0,0x00,0xa0]
++ ! CHECK: fnegd %f0, %f4 ! encoding: [0x89,0xa0,0x00,0xc0]
++ ! CHECK: fnegq %f0, %f4 ! encoding: [0x89,0xa0,0x00,0xe0]
++ fnegs %f0, %f4
++ fnegd %f0, %f4
++ fnegq %f0, %f4
++
++ ! CHECK: fabss %f0, %f4 ! encoding: [0x89,0xa0,0x01,0x20]
++ ! CHECK: fabsd %f0, %f4 ! encoding: [0x89,0xa0,0x01,0x40]
++ ! CHECK: fabsq %f0, %f4 ! encoding: [0x89,0xa0,0x01,0x60]
++ fabss %f0, %f4
++ fabsd %f0, %f4
++ fabsq %f0, %f4
++
++ ! CHECK: fsqrts %f0, %f4 ! encoding: [0x89,0xa0,0x05,0x20]
++ ! CHECK: fsqrtd %f0, %f4 ! encoding: [0x89,0xa0,0x05,0x40]
++ ! CHECK: fsqrtq %f0, %f4 ! encoding: [0x89,0xa0,0x05,0x60]
++ fsqrts %f0, %f4
++ fsqrtd %f0, %f4
++ fsqrtq %f0, %f4
++
++ ! CHECK: fadds %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0x24]
++ ! CHECK: faddd %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0x44]
++ ! CHECK: faddq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0x64]
++ fadds %f0, %f4, %f8
++ faddd %f0, %f4, %f8
++ faddq %f0, %f4, %f8
++
++ ! CHECK: fsubs %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xa4]
++ ! CHECK: fsubd %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xc4]
++ ! CHECK: fsubq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xe4]
++ fsubs %f0, %f4, %f8
++ fsubd %f0, %f4, %f8
++ fsubq %f0, %f4, %f8
++
++ ! CHECK: fmuls %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0x24]
++ ! CHECK: fmuld %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0x44]
++ ! CHECK: fmulq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0x64]
++ fmuls %f0, %f4, %f8
++ fmuld %f0, %f4, %f8
++ fmulq %f0, %f4, %f8
++
++ ! CHECK: fsmuld %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x0d,0x24]
++ ! CHECK: fdmulq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x0d,0xc4]
++ fsmuld %f0, %f4, %f8
++ fdmulq %f0, %f4, %f8
++
++ ! CHECK: fdivs %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0xa4]
++ ! CHECK: fdivd %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0xc4]
++ ! CHECK: fdivq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x09,0xe4]
++ fdivs %f0, %f4, %f8
++ fdivd %f0, %f4, %f8
++ fdivq %f0, %f4, %f8
++
++ ! CHECK: fcmps %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x24]
++ ! CHECK: fcmpd %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x44]
++ ! CHECK: fcmpq %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x64]
++ fcmps %f0, %f4
++ fcmpd %f0, %f4
++ fcmpq %f0, %f4
++
++ ! CHECK: fxtos %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x80]
++ ! CHECK: fxtod %f0, %f4 ! encoding: [0x89,0xa0,0x11,0x00]
++ ! CHECK: fxtoq %f0, %f4 ! encoding: [0x89,0xa0,0x11,0x80]
++ fxtos %f0, %f4
++ fxtod %f0, %f4
++ fxtoq %f0, %f4
++
++ ! CHECK: fstox %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x20]
++ ! CHECK: fdtox %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x40]
++ ! CHECK: fqtox %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x60]
++ fstox %f0, %f4
++ fdtox %f0, %f4
++ fqtox %f0, %f4
++
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199061-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199061-sparc.diff
new file mode 100644
index 0000000..4a8e5b8
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199061-sparc.diff
@@ -0,0 +1,126 @@
+Pull in r199061 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Handle bundled terminators in isBlockOnlyReachableByFallthrough.
+
+ Targets like SPARC and MIPS have delay slots and normally bundle the
+ delay slot instruction with the corresponding terminator.
+
+ Teach isBlockOnlyReachableByFallthrough to find any MBB operands on
+ bundled terminators so SPARC doesn't need to specialize this function.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/CodeGen/SPARC/missinglabel.ll
+===================================================================
+--- test/CodeGen/SPARC/missinglabel.ll
++++ test/CodeGen/SPARC/missinglabel.ll
+@@ -0,0 +1,23 @@
++; RUN: llc < %s -verify-machineinstrs | FileCheck %s
++target datalayout = "E-m:e-i64:64-n32:64-S128"
++target triple = "sparc64-unknown-linux-gnu"
++
++define void @f() align 2 {
++entry:
++; CHECK: %xcc, .LBB0_1
++ %cmp = icmp eq i64 undef, 0
++ br i1 %cmp, label %targetblock, label %cond.false
++
++cond.false:
++ unreachable
++
++; CHECK: .LBB0_1: ! %targetblock
++targetblock:
++ br i1 undef, label %cond.false.i83, label %exit.i85
++
++cond.false.i83:
++ unreachable
++
++exit.i85:
++ unreachable
++}
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -65,10 +65,6 @@ namespace {
+ bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
+-
+- virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
+- const;
+-
+ };
+ } // end of anonymous namespace
+
+@@ -390,37 +386,6 @@ bool SparcAsmPrinter::PrintAsmMemoryOperand(const
+ return false;
+ }
+
+-/// isBlockOnlyReachableByFallthough - Return true if the basic block has
+-/// exactly one predecessor and the control transfer mechanism between
+-/// the predecessor and this block is a fall-through.
+-///
+-/// This overrides AsmPrinter's implementation to handle delay slots.
+-bool SparcAsmPrinter::
+-isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
+- // If this is a landing pad, it isn't a fall through. If it has no preds,
+- // then nothing falls through to it.
+- if (MBB->isLandingPad() || MBB->pred_empty())
+- return false;
+-
+- // If there isn't exactly one predecessor, it can't be a fall through.
+- MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
+- ++PI2;
+- if (PI2 != MBB->pred_end())
+- return false;
+-
+- // The predecessor has to be immediately before this block.
+- const MachineBasicBlock *Pred = *PI;
+-
+- if (!Pred->isLayoutSuccessor(MBB))
+- return false;
+-
+- // Check if the last terminator is an unconditional branch.
+- MachineBasicBlock::const_iterator I = Pred->end();
+- while (I != Pred->begin() && !(--I)->isTerminator())
+- ; // Noop
+- return I == Pred->end() || !I->isBarrier();
+-}
+-
+ // Force static initialization.
+ extern "C" void LLVMInitializeSparcAsmPrinter() {
+ RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget);
+Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+===================================================================
+--- lib/CodeGen/AsmPrinter/AsmPrinter.cpp
++++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+@@ -23,6 +23,7 @@
+ #include "llvm/CodeGen/MachineConstantPool.h"
+ #include "llvm/CodeGen/MachineFrameInfo.h"
+ #include "llvm/CodeGen/MachineFunction.h"
++#include "llvm/CodeGen/MachineInstrBundle.h"
+ #include "llvm/CodeGen/MachineJumpTableInfo.h"
+ #include "llvm/CodeGen/MachineLoopInfo.h"
+ #include "llvm/CodeGen/MachineModuleInfo.h"
+@@ -2221,14 +2222,13 @@ isBlockOnlyReachableByFallthrough(const MachineBas
+ if (!MI.isBranch() || MI.isIndirectBranch())
+ return false;
+
+- // If we are the operands of one of the branches, this is not
+- // a fall through.
+- for (MachineInstr::mop_iterator OI = MI.operands_begin(),
+- OE = MI.operands_end(); OI != OE; ++OI) {
+- const MachineOperand& OP = *OI;
+- if (OP.isJTI())
++ // If we are the operands of one of the branches, this is not a fall
++ // through. Note that targets with delay slots will usually bundle
++ // terminators with the delay slot instruction.
++ for (ConstMIBundleOperands OP(&MI); OP.isValid(); ++OP) {
++ if (OP->isJTI())
+ return false;
+- if (OP.isMBB() && OP.getMBB() == MBB)
++ if (OP->isMBB() && OP->getMBB() == MBB)
+ return false;
+ }
+ }
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199186-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199186-sparc.diff
new file mode 100644
index 0000000..167aa6a
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199186-sparc.diff
@@ -0,0 +1,28 @@
+Pull in r199186 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Switch the NEON register class from QPR to DPair.
+
+ The already allocatable DPair superclass contains odd-even D register
+ pair in addition to the even-odd pairs in the QPR register class. There
+ is no reason to constrain the set of D register pairs that can be used
+ for NEON values. Any NEON instructions that require a Q register will
+ automatically constrain the register class to QPR.
+
+ The allocation order for DPair begins with the QPR registers, so
+ register allocation is unlikely to change much.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/ARM/ARMISelLowering.cpp
+===================================================================
+--- lib/Target/ARM/ARMISelLowering.cpp
++++ lib/Target/ARM/ARMISelLowering.cpp
+@@ -156,7 +156,7 @@ void ARMTargetLowering::addDRTypeForNEON(MVT VT) {
+ }
+
+ void ARMTargetLowering::addQRTypeForNEON(MVT VT) {
+- addRegisterClass(VT, &ARM::QPRRegClass);
++ addRegisterClass(VT, &ARM::DPairRegClass);
+ addTypeForNEON(VT, MVT::v2f64, MVT::v4i32);
+ }
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff
new file mode 100644
index 0000000..bfc1cfc
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199187-sparc.diff
@@ -0,0 +1,81 @@
+Pull in r199187 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Always let value types influence register classes.
+
+ When creating a virtual register for a def, the value type should be
+ used to pick the register class. If we only use the register class
+ constraint on the instruction, we might pick a too large register class.
+
+ Some registers can store values of different sizes. For example, the x86
+ xmm registers can hold f32, f64, and 128-bit vectors. The three
+ different value sizes are represented by register classes with identical
+ register sets: FR32, FR64, and VR128. These register classes have
+ different spill slot sizes, so it is important to use the right one.
+
+ The register class constraint on an instruction doesn't necessarily care
+ about the size of the value its defining. The value type determines
+ that.
+
+ This fixes a problem where InstrEmitter was picking 32-bit register
+ classes for 64-bit values on SPARC.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/CodeGen/SPARC/spillsize.ll
+===================================================================
+--- test/CodeGen/SPARC/spillsize.ll
++++ test/CodeGen/SPARC/spillsize.ll
+@@ -0,0 +1,25 @@
++; RUN: llc < %s -verify-machineinstrs | FileCheck %s
++target datalayout = "E-m:e-i64:64-n32:64-S128"
++target triple = "sparcv9"
++
++; CHECK-LABEL: spill4
++; This function spills two values: %p and the materialized large constant.
++; Both must use 8-byte spill and fill instructions.
++; CHECK: stx %{{..}}, [%fp+
++; CHECK: stx %{{..}}, [%fp+
++; CHECK: ldx [%fp+
++; CHECK: ldx [%fp+
++define void @spill4(i64* nocapture %p) {
++entry:
++ %val0 = load i64* %p
++ %cmp0 = icmp ult i64 %val0, 385672958347594845
++ %cm80 = zext i1 %cmp0 to i64
++ store i64 %cm80, i64* %p, align 8
++ tail call void asm sideeffect "", "~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{g2},~{g3},~{g4},~{g5},~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o7}"()
++ %arrayidx1 = getelementptr inbounds i64* %p, i64 1
++ %val = load i64* %arrayidx1
++ %cmp = icmp ult i64 %val, 385672958347594845
++ %cm8 = select i1 %cmp, i64 10, i64 20
++ store i64 %cm8, i64* %arrayidx1, align 8
++ ret void
++}
+Index: lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+===================================================================
+--- lib/CodeGen/SelectionDAG/InstrEmitter.cpp
++++ lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+@@ -220,10 +220,19 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *
+ unsigned VRBase = 0;
+ const TargetRegisterClass *RC =
+ TRI->getAllocatableClass(TII->getRegClass(II, i, TRI, *MF));
+- // If the register class is unknown for the given definition, then try to
+- // infer one from the value type.
+- if (!RC && i < NumResults)
+- RC = TLI->getRegClassFor(Node->getSimpleValueType(i));
++ // Always let the value type influence the used register class. The
++ // constraints on the instruction may be too lax to represent the value
++ // type correctly. For example, a 64-bit float (X86::FR64) can't live in
++ // the 32-bit float super-class (X86::FR32).
++ if (i < NumResults && TLI->isTypeLegal(Node->getSimpleValueType(i))) {
++ const TargetRegisterClass *VTRC =
++ TLI->getRegClassFor(Node->getSimpleValueType(i));
++ if (RC)
++ VTRC = TRI->getCommonSubClass(RC, VTRC);
++ if (VTRC)
++ RC = VTRC;
++ }
++
+ if (II.OpInfo[i].isOptionalDef()) {
+ // Optional def must be a physical register.
+ unsigned NumResults = CountResults(Node);
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff
new file mode 100644
index 0000000..489f457
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff
@@ -0,0 +1,200 @@
+Pull in r199775 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Do not add PC to _GLOBAL_OFFSET_TABLE_ address to access GOT in absolute code.
+ Fixes PR#18521
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -65,18 +65,24 @@ namespace {
+ bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
++
++ void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI);
++
+ };
+ } // end of anonymous namespace
+
+-static MCOperand createPCXCallOP(MCSymbol *Label,
+- MCContext &OutContext)
+-{
+- const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
++static MCOperand createSparcMCOperand(SparcMCExpr::VariantKind Kind,
++ MCSymbol *Sym, MCContext &OutContext) {
++ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Sym,
+ OutContext);
+- const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
+- MCSym, OutContext);
++ const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, OutContext);
+ return MCOperand::CreateExpr(expr);
++
+ }
++static MCOperand createPCXCallOP(MCSymbol *Label,
++ MCContext &OutContext) {
++ return createSparcMCOperand(SparcMCExpr::VK_Sparc_None, Label, OutContext);
++}
+
+ static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
+ MCSymbol *GOTLabel, MCSymbol *StartLabel,
+@@ -115,43 +121,101 @@ static void EmitSETHI(MCStreamer &OutStreamer,
+ OutStreamer.EmitInstruction(SETHIInst);
+ }
+
+-static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
+- MCOperand &Imm, MCOperand &RD)
++static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode,
++ MCOperand &RS1, MCOperand &Src2, MCOperand &RD)
+ {
+- MCInst ORInst;
+- ORInst.setOpcode(SP::ORri);
+- ORInst.addOperand(RD);
+- ORInst.addOperand(RS1);
+- ORInst.addOperand(Imm);
+- OutStreamer.EmitInstruction(ORInst);
++ MCInst Inst;
++ Inst.setOpcode(Opcode);
++ Inst.addOperand(RD);
++ Inst.addOperand(RS1);
++ Inst.addOperand(Src2);
++ OutStreamer.EmitInstruction(Inst);
+ }
+
++static void EmitOR(MCStreamer &OutStreamer,
++ MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
++ EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD);
++}
++
+ static void EmitADD(MCStreamer &OutStreamer,
+- MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
+-{
+- MCInst ADDInst;
+- ADDInst.setOpcode(SP::ADDrr);
+- ADDInst.addOperand(RD);
+- ADDInst.addOperand(RS1);
+- ADDInst.addOperand(RS2);
+- OutStreamer.EmitInstruction(ADDInst);
++ MCOperand &RS1, MCOperand &RS2, MCOperand &RD) {
++ EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD);
+ }
+
+-static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
+- MCStreamer &OutStreamer,
+- MCContext &OutContext)
++static void EmitSHL(MCStreamer &OutStreamer,
++ MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
++ EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD);
++}
++
++
++static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym,
++ SparcMCExpr::VariantKind HiKind,
++ SparcMCExpr::VariantKind LoKind,
++ MCOperand &RD,
++ MCContext &OutContext) {
++
++ MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext);
++ MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext);
++ EmitSETHI(OutStreamer, hi, RD);
++ EmitOR(OutStreamer, RD, lo, RD);
++}
++
++void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI)
+ {
+- const MachineOperand &MO = MI->getOperand(0);
+- MCSymbol *StartLabel = OutContext.CreateTempSymbol();
+- MCSymbol *EndLabel = OutContext.CreateTempSymbol();
+- MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
+ MCSymbol *GOTLabel =
+ OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
+
++ const MachineOperand &MO = MI->getOperand(0);
+ assert(MO.getReg() != SP::O7 &&
+ "%o7 is assigned as destination for getpcx!");
+
+ MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
++
++
++ if (TM.getRelocationModel() != Reloc::PIC_) {
++ // Just load the address of GOT to MCRegOP.
++ switch(TM.getCodeModel()) {
++ default:
++ llvm_unreachable("Unsupported absolute code model");
++ case CodeModel::Small:
++ EmitHiLo(OutStreamer, GOTLabel,
++ SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO,
++ MCRegOP, OutContext);
++ break;
++ case CodeModel::Medium: {
++ EmitHiLo(OutStreamer, GOTLabel,
++ SparcMCExpr::VK_Sparc_H44, SparcMCExpr::VK_Sparc_M44,
++ MCRegOP, OutContext);
++ MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(12,
++ OutContext));
++ EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
++ MCOperand lo = createSparcMCOperand(SparcMCExpr::VK_Sparc_L44,
++ GOTLabel, OutContext);
++ EmitOR(OutStreamer, MCRegOP, lo, MCRegOP);
++ break;
++ }
++ case CodeModel::Large: {
++ EmitHiLo(OutStreamer, GOTLabel,
++ SparcMCExpr::VK_Sparc_HH, SparcMCExpr::VK_Sparc_HM,
++ MCRegOP, OutContext);
++ MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(32,
++ OutContext));
++ EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
++ // Use register %o7 to load the lower 32 bits.
++ MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
++ EmitHiLo(OutStreamer, GOTLabel,
++ SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO,
++ RegO7, OutContext);
++ EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
++ }
++ }
++ return;
++ }
++
++ MCSymbol *StartLabel = OutContext.CreateTempSymbol();
++ MCSymbol *EndLabel = OutContext.CreateTempSymbol();
++ MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
++
+ MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
+
+ // <StartLabel>:
+@@ -187,7 +251,7 @@ void SparcAsmPrinter::EmitInstruction(const Machin
+ // FIXME: Debug Value.
+ return;
+ case SP::GETPCX:
+- LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
++ LowerGETPCXAndEmitMCInsts(MI);
+ return;
+ }
+ MachineBasicBlock::const_instr_iterator I = MI;
+Index: test/CodeGen/SPARC/tls.ll
+===================================================================
+--- test/CodeGen/SPARC/tls.ll
++++ test/CodeGen/SPARC/tls.ll
+@@ -38,8 +38,7 @@ entry:
+
+
+ ; v8abs-LABEL: test_tls_extern
+-; v8abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]]
+-; v8abs: add [[PC]], %o7, %[[GOTBASE:[goli][0-7]]]
++; v8abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]]
+ ; v8abs: sethi %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]]
+ ; v8abs: add [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]]
+ ; v8abs: ld [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ld(extern_symbol)
+@@ -47,8 +46,7 @@ entry:
+ ; v8abs: ld [%[[R4]]]
+
+ ; v9abs-LABEL: test_tls_extern
+-; v9abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]]
+-; v9abs: add [[PC]], %o7, %[[GOTBASE:[goli][0-7]]]
++; v9abs: or {{%[goli][0-7]}}, %l44(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]]
+ ; v9abs: sethi %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]]
+ ; v9abs: add [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]]
+ ; v9abs: ldx [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ldx(extern_symbol)
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff
new file mode 100644
index 0000000..0417410
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199781-sparc.diff
@@ -0,0 +1,142 @@
+Pull in r199781 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add support for inline assembly constraint 'I'.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/CodeGen/SPARC/inlineasm.ll
+===================================================================
+--- test/CodeGen/SPARC/inlineasm.ll
++++ test/CodeGen/SPARC/inlineasm.ll
+@@ -0,0 +1,35 @@
++; RUN: llc -march=sparc <%s | FileCheck %s
++
++; CHECK-LABEL: test_constraint_r
++; CHECK: add %o1, %o0, %o0
++define i32 @test_constraint_r(i32 %a, i32 %b) {
++entry:
++ %0 = tail call i32 asm sideeffect "add $2, $1, $0", "=r,r,r"(i32 %a, i32 %b)
++ ret i32 %0
++}
++
++; CHECK-LABEL: test_constraint_I
++; CHECK: add %o0, 1023, %o0
++define i32 @test_constraint_I(i32 %a) {
++entry:
++ %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 1023)
++ ret i32 %0
++}
++
++; CHECK-LABEL: test_constraint_I_neg
++; CHECK: add %o0, -4096, %o0
++define i32 @test_constraint_I_neg(i32 %a) {
++entry:
++ %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 -4096)
++ ret i32 %0
++}
++
++; CHECK-LABEL: test_constraint_I_largeimm
++; CHECK: sethi 9, [[R0:%[gilo][0-7]]]
++; CHECK: or [[R0]], 784, [[R1:%[gilo][0-7]]]
++; CHECK: add %o0, [[R1]], %o0
++define i32 @test_constraint_I_largeimm(i32 %a) {
++entry:
++ %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 10000)
++ ret i32 %0
++}
+Index: lib/Target/Sparc/SparcISelLowering.h
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.h
++++ lib/Target/Sparc/SparcISelLowering.h
+@@ -73,6 +73,13 @@ namespace llvm {
+ virtual const char *getTargetNodeName(unsigned Opcode) const;
+
+ ConstraintType getConstraintType(const std::string &Constraint) const;
++ ConstraintWeight
++ getSingleConstraintMatchWeight(AsmOperandInfo &info,
++ const char *constraint) const;
++ void LowerAsmOperandForConstraint(SDValue Op,
++ std::string &Constraint,
++ std::vector<SDValue> &Ops,
++ SelectionDAG &DAG) const;
+ std::pair<unsigned, const TargetRegisterClass*>
+ getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const;
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -2918,6 +2918,8 @@ SparcTargetLowering::getConstraintType(const std::
+ switch (Constraint[0]) {
+ default: break;
+ case 'r': return C_RegisterClass;
++ case 'I': // SIMM13
++ return C_Other;
+ }
+ }
+
+@@ -2924,6 +2926,64 @@ SparcTargetLowering::getConstraintType(const std::
+ return TargetLowering::getConstraintType(Constraint);
+ }
+
++TargetLowering::ConstraintWeight SparcTargetLowering::
++getSingleConstraintMatchWeight(AsmOperandInfo &info,
++ const char *constraint) const {
++ ConstraintWeight weight = CW_Invalid;
++ Value *CallOperandVal = info.CallOperandVal;
++ // If we don't have a value, we can't do a match,
++ // but allow it at the lowest weight.
++ if (CallOperandVal == NULL)
++ return CW_Default;
++
++ // Look at the constraint type.
++ switch (*constraint) {
++ default:
++ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
++ break;
++ case 'I': // SIMM13
++ if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) {
++ if (isInt<13>(C->getSExtValue()))
++ weight = CW_Constant;
++ }
++ break;
++ }
++ return weight;
++}
++
++/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
++/// vector. If it is invalid, don't add anything to Ops.
++void SparcTargetLowering::
++LowerAsmOperandForConstraint(SDValue Op,
++ std::string &Constraint,
++ std::vector<SDValue> &Ops,
++ SelectionDAG &DAG) const {
++ SDValue Result(0, 0);
++
++ // Only support length 1 constraints for now.
++ if (Constraint.length() > 1)
++ return;
++
++ char ConstraintLetter = Constraint[0];
++ switch (ConstraintLetter) {
++ default: break;
++ case 'I':
++ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
++ if (isInt<13>(C->getSExtValue())) {
++ Result = DAG.getTargetConstant(C->getSExtValue(), Op.getValueType());
++ break;
++ }
++ return;
++ }
++ }
++
++ if (Result.getNode()) {
++ Ops.push_back(Result);
++ return;
++ }
++ TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
++}
++
+ std::pair<unsigned, const TargetRegisterClass*>
+ SparcTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
+ MVT VT) const {
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199786-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199786-sparc.diff
new file mode 100644
index 0000000..844e4e4
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199786-sparc.diff
@@ -0,0 +1,55 @@
+Pull in r199786 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add support for inline assembly constraints which specify registers by their aliases.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -2992,6 +2992,26 @@ SparcTargetLowering::getRegForInlineAsmConstraint(
+ case 'r':
+ return std::make_pair(0U, &SP::IntRegsRegClass);
+ }
++ } else if (!Constraint.empty() && Constraint.size() <= 5
++ && Constraint[0] == '{' && *(Constraint.end()-1) == '}') {
++ // constraint = '{r<d>}'
++ // Remove the braces from around the name.
++ StringRef name(Constraint.data()+1, Constraint.size()-2);
++ // Handle register aliases:
++ // r0-r7 -> g0-g7
++ // r8-r15 -> o0-o7
++ // r16-r23 -> l0-l7
++ // r24-r31 -> i0-i7
++ uint64_t intVal = 0;
++ if (name.substr(0, 1).equals("r")
++ && !name.substr(1).getAsInteger(10, intVal) && intVal <= 31) {
++ const char regTypes[] = { 'g', 'o', 'l', 'i' };
++ char regType = regTypes[intVal/8];
++ char regIdx = '0' + (intVal % 8);
++ char tmp[] = { '{', regType, regIdx, '}', 0 };
++ std::string newConstraint = std::string(tmp);
++ return TargetLowering::getRegForInlineAsmConstraint(newConstraint, VT);
++ }
+ }
+
+ return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
+Index: test/CodeGen/SPARC/inlineasm.ll
+===================================================================
+--- test/CodeGen/SPARC/inlineasm.ll
++++ test/CodeGen/SPARC/inlineasm.ll
+@@ -33,3 +33,13 @@ entry:
+ %0 = tail call i32 asm sideeffect "add $1, $2, $0", "=r,r,rI"(i32 %a, i32 10000)
+ ret i32 %0
+ }
++
++; CHECK-LABEL: test_constraint_reg
++; CHECK: ldda [%o1] 43, %g2
++; CHECK: ldda [%o1] 43, %g3
++define void @test_constraint_reg(i32 %s, i32* %ptr) {
++entry:
++ %0 = tail call i64 asm sideeffect "ldda [$1] $2, $0", "={r2},r,n"(i32* %ptr, i32 43)
++ %1 = tail call i64 asm sideeffect "ldda [$1] $2, $0", "={g3},r,n"(i32* %ptr, i32 43)
++ ret void
++}
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199940-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199940-sparc.diff
new file mode 100644
index 0000000..e171799
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199940-sparc.diff
@@ -0,0 +1,21 @@
+Pull in r199940 from upstream llvm trunk (by Eric Christopher):
+
+ Fix out of bounds access to the double regs array. Given the
+ code this looks correct, but could use review. The previous
+ was definitely not correct.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -734,7 +734,7 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
+ && !name.substr(1, 2).getAsInteger(10, intVal)
+ && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
+ // FIXME: Check V9
+- RegNo = DoubleRegs[16 + intVal/2];
++ RegNo = DoubleRegs[intVal/2];
+ RegKind = SparcOperand::rk_DoubleReg;
+ return true;
+ }
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199974-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199974-sparc.diff
new file mode 100644
index 0000000..0951995
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199974-sparc.diff
@@ -0,0 +1,54 @@
+Pull in r199974 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Correct quad register list in the asm parser.
+ Add test cases to check parsing of v9 double registers and their aliased quad registers.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/MC/Disassembler/Sparc/sparc-fp.txt
+===================================================================
+--- test/MC/Disassembler/Sparc/sparc-fp.txt
++++ test/MC/Disassembler/Sparc/sparc-fp.txt
+@@ -81,6 +81,12 @@
+ # CHECK: faddq %f0, %f4, %f8
+ 0x91 0xa0 0x08 0x64
+
++# CHECK: faddd %f32, %f34, %f62
++0xbf 0xa0 0x48 0x43
++
++# CHECK: faddq %f32, %f36, %f60
++0xbb 0xa0 0x48 0x65
++
+ # CHECK: fsubs %f0, %f4, %f8
+ 0x91 0xa0 0x08 0xa4
+
+Index: test/MC/Sparc/sparc-fp-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-fp-instructions.s
++++ test/MC/Sparc/sparc-fp-instructions.s
+@@ -64,6 +64,12 @@
+ faddd %f0, %f4, %f8
+ faddq %f0, %f4, %f8
+
++ ! make sure we can handle V9 double registers and their aliased quad registers.
++ ! CHECK: faddd %f32, %f34, %f62 ! encoding: [0xbf,0xa0,0x48,0x43]
++ ! CHECK: faddq %f32, %f36, %f60 ! encoding: [0xbb,0xa0,0x48,0x65]
++ faddd %f32, %f34, %f62
++ faddq %f32, %f36, %f60
++
+ ! CHECK: fsubs %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xa4]
+ ! CHECK: fsubd %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xc4]
+ ! CHECK: fsubq %f0, %f4, %f8 ! encoding: [0x91,0xa0,0x08,0xe4]
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -117,7 +117,7 @@ class SparcAsmParser : public MCTargetAsmParser {
+ static unsigned QuadFPRegs[32] = {
+ Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
+ Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
+- Sparc::Q8, Sparc::Q7, Sparc::Q8, Sparc::Q9,
++ Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
+ Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
+
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199975-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199975-sparc.diff
new file mode 100644
index 0000000..b1dec41
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199975-sparc.diff
@@ -0,0 +1,344 @@
+Pull in r199975 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Implement atomicrmw operations in 32 and 64 bits for SPARCv9.
+
+ These all use the compare-and-swap CASA/CASXA instructions.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/CodeGen/SPARC/atomics.ll
+===================================================================
+--- test/CodeGen/SPARC/atomics.ll
++++ test/CodeGen/SPARC/atomics.ll
+@@ -1,4 +1,4 @@
+-; RUN: llc < %s -march=sparcv9 | FileCheck %s
++; RUN: llc < %s -march=sparcv9 -verify-machineinstrs | FileCheck %s
+
+ ; CHECK-LABEL: test_atomic_i32
+ ; CHECK: ld [%o0]
+@@ -61,3 +61,84 @@ entry:
+ %b = atomicrmw xchg i32* %ptr, i32 42 monotonic
+ ret i32 %b
+ }
++
++; CHECK-LABEL: test_load_add_32
++; CHECK: membar
++; CHECK: add
++; CHECK: cas [%o0]
++; CHECK: membar
++define zeroext i32 @test_load_add_32(i32* %p, i32 zeroext %v) {
++entry:
++ %0 = atomicrmw add i32* %p, i32 %v seq_cst
++ ret i32 %0
++}
++
++; CHECK-LABEL: test_load_sub_64
++; CHECK: membar
++; CHECK: sub
++; CHECK: casx [%o0]
++; CHECK: membar
++define zeroext i64 @test_load_sub_64(i64* %p, i64 zeroext %v) {
++entry:
++ %0 = atomicrmw sub i64* %p, i64 %v seq_cst
++ ret i64 %0
++}
++
++; CHECK-LABEL: test_load_xor_32
++; CHECK: membar
++; CHECK: xor
++; CHECK: cas [%o0]
++; CHECK: membar
++define zeroext i32 @test_load_xor_32(i32* %p, i32 zeroext %v) {
++entry:
++ %0 = atomicrmw xor i32* %p, i32 %v seq_cst
++ ret i32 %0
++}
++
++; CHECK-LABEL: test_load_and_32
++; CHECK: membar
++; CHECK: and
++; CHECK-NOT: xor
++; CHECK: cas [%o0]
++; CHECK: membar
++define zeroext i32 @test_load_and_32(i32* %p, i32 zeroext %v) {
++entry:
++ %0 = atomicrmw and i32* %p, i32 %v seq_cst
++ ret i32 %0
++}
++
++; CHECK-LABEL: test_load_nand_32
++; CHECK: membar
++; CHECK: and
++; CHECK: xor
++; CHECK: cas [%o0]
++; CHECK: membar
++define zeroext i32 @test_load_nand_32(i32* %p, i32 zeroext %v) {
++entry:
++ %0 = atomicrmw nand i32* %p, i32 %v seq_cst
++ ret i32 %0
++}
++
++; CHECK-LABEL: test_load_max_64
++; CHECK: membar
++; CHECK: cmp
++; CHECK: movg %xcc
++; CHECK: casx [%o0]
++; CHECK: membar
++define zeroext i64 @test_load_max_64(i64* %p, i64 zeroext %v) {
++entry:
++ %0 = atomicrmw max i64* %p, i64 %v seq_cst
++ ret i64 %0
++}
++
++; CHECK-LABEL: test_load_umin_32
++; CHECK: membar
++; CHECK: cmp
++; CHECK: movleu %icc
++; CHECK: cas [%o0]
++; CHECK: membar
++define zeroext i32 @test_load_umin_32(i32* %p, i32 zeroext %v) {
++entry:
++ %0 = atomicrmw umin i32* %p, i32 %v seq_cst
++ ret i32 %0
++}
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -438,6 +438,31 @@ def : Pat<(atomic_store ADDRri:$dst, i64:$val), (S
+
+ } // Predicates = [Is64Bit]
+
++let usesCustomInserter = 1, hasCtrlDep = 1, mayLoad = 1, mayStore = 1,
++ Defs = [ICC] in
++multiclass AtomicRMW<SDPatternOperator op32, SDPatternOperator op64> {
++
++ def _32 : Pseudo<(outs IntRegs:$rd),
++ (ins ptr_rc:$addr, IntRegs:$rs2), "",
++ [(set i32:$rd, (op32 iPTR:$addr, i32:$rs2))]>;
++
++ let Predicates = [Is64Bit] in
++ def _64 : Pseudo<(outs I64Regs:$rd),
++ (ins ptr_rc:$addr, I64Regs:$rs2), "",
++ [(set i64:$rd, (op64 iPTR:$addr, i64:$rs2))]>;
++}
++
++defm ATOMIC_LOAD_ADD : AtomicRMW<atomic_load_add_32, atomic_load_add_64>;
++defm ATOMIC_LOAD_SUB : AtomicRMW<atomic_load_sub_32, atomic_load_sub_64>;
++defm ATOMIC_LOAD_AND : AtomicRMW<atomic_load_and_32, atomic_load_and_64>;
++defm ATOMIC_LOAD_OR : AtomicRMW<atomic_load_or_32, atomic_load_or_64>;
++defm ATOMIC_LOAD_XOR : AtomicRMW<atomic_load_xor_32, atomic_load_xor_64>;
++defm ATOMIC_LOAD_NAND : AtomicRMW<atomic_load_nand_32, atomic_load_nand_64>;
++defm ATOMIC_LOAD_MIN : AtomicRMW<atomic_load_min_32, atomic_load_min_64>;
++defm ATOMIC_LOAD_MAX : AtomicRMW<atomic_load_max_32, atomic_load_max_64>;
++defm ATOMIC_LOAD_UMIN : AtomicRMW<atomic_load_umin_32, atomic_load_umin_64>;
++defm ATOMIC_LOAD_UMAX : AtomicRMW<atomic_load_umax_32, atomic_load_umax_64>;
++
+ // Global addresses, constant pool entries
+ let Predicates = [Is64Bit] in {
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -2831,11 +2831,6 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
+ MachineBasicBlock *
+ SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
+ MachineBasicBlock *BB) const {
+- const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
+- unsigned BROpcode;
+- unsigned CC;
+- DebugLoc dl = MI->getDebugLoc();
+- // Figure out the conditional branch opcode to use for this select_cc.
+ switch (MI->getOpcode()) {
+ default: llvm_unreachable("Unknown SELECT_CC!");
+ case SP::SELECT_CC_Int_ICC:
+@@ -2842,17 +2837,64 @@ SparcTargetLowering::EmitInstrWithCustomInserter(M
+ case SP::SELECT_CC_FP_ICC:
+ case SP::SELECT_CC_DFP_ICC:
+ case SP::SELECT_CC_QFP_ICC:
+- BROpcode = SP::BCOND;
+- break;
++ return expandSelectCC(MI, BB, SP::BCOND);
+ case SP::SELECT_CC_Int_FCC:
+ case SP::SELECT_CC_FP_FCC:
+ case SP::SELECT_CC_DFP_FCC:
+ case SP::SELECT_CC_QFP_FCC:
+- BROpcode = SP::FBCOND;
+- break;
++ return expandSelectCC(MI, BB, SP::FBCOND);
++
++ case SP::ATOMIC_LOAD_ADD_32:
++ return expandAtomicRMW(MI, BB, SP::ADDrr);
++ case SP::ATOMIC_LOAD_ADD_64:
++ return expandAtomicRMW(MI, BB, SP::ADDXrr);
++ case SP::ATOMIC_LOAD_SUB_32:
++ return expandAtomicRMW(MI, BB, SP::SUBrr);
++ case SP::ATOMIC_LOAD_SUB_64:
++ return expandAtomicRMW(MI, BB, SP::SUBXrr);
++ case SP::ATOMIC_LOAD_AND_32:
++ return expandAtomicRMW(MI, BB, SP::ANDrr);
++ case SP::ATOMIC_LOAD_AND_64:
++ return expandAtomicRMW(MI, BB, SP::ANDXrr);
++ case SP::ATOMIC_LOAD_OR_32:
++ return expandAtomicRMW(MI, BB, SP::ORrr);
++ case SP::ATOMIC_LOAD_OR_64:
++ return expandAtomicRMW(MI, BB, SP::ORXrr);
++ case SP::ATOMIC_LOAD_XOR_32:
++ return expandAtomicRMW(MI, BB, SP::XORrr);
++ case SP::ATOMIC_LOAD_XOR_64:
++ return expandAtomicRMW(MI, BB, SP::XORXrr);
++ case SP::ATOMIC_LOAD_NAND_32:
++ return expandAtomicRMW(MI, BB, SP::ANDrr);
++ case SP::ATOMIC_LOAD_NAND_64:
++ return expandAtomicRMW(MI, BB, SP::ANDXrr);
++
++ case SP::ATOMIC_LOAD_MAX_32:
++ return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_G);
++ case SP::ATOMIC_LOAD_MAX_64:
++ return expandAtomicRMW(MI, BB, SP::MOVXCCrr, SPCC::ICC_G);
++ case SP::ATOMIC_LOAD_MIN_32:
++ return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_LE);
++ case SP::ATOMIC_LOAD_MIN_64:
++ return expandAtomicRMW(MI, BB, SP::MOVXCCrr, SPCC::ICC_LE);
++ case SP::ATOMIC_LOAD_UMAX_32:
++ return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_GU);
++ case SP::ATOMIC_LOAD_UMAX_64:
++ return expandAtomicRMW(MI, BB, SP::MOVXCCrr, SPCC::ICC_GU);
++ case SP::ATOMIC_LOAD_UMIN_32:
++ return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_LEU);
++ case SP::ATOMIC_LOAD_UMIN_64:
++ return expandAtomicRMW(MI, BB, SP::MOVXCCrr, SPCC::ICC_LEU);
+ }
++}
+
+- CC = (SPCC::CondCodes)MI->getOperand(3).getImm();
++MachineBasicBlock*
++SparcTargetLowering::expandSelectCC(MachineInstr *MI,
++ MachineBasicBlock *BB,
++ unsigned BROpcode) const {
++ const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
++ DebugLoc dl = MI->getDebugLoc();
++ unsigned CC = (SPCC::CondCodes)MI->getOperand(3).getImm();
+
+ // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
+ // control-flow pattern. The incoming instruction knows the destination vreg
+@@ -2906,6 +2948,100 @@ SparcTargetLowering::EmitInstrWithCustomInserter(M
+ return BB;
+ }
+
++MachineBasicBlock*
++SparcTargetLowering::expandAtomicRMW(MachineInstr *MI,
++ MachineBasicBlock *MBB,
++ unsigned Opcode,
++ unsigned CondCode) const {
++ const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
++ MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
++ DebugLoc DL = MI->getDebugLoc();
++
++ // MI is an atomic read-modify-write instruction of the form:
++ //
++ // rd = atomicrmw<op> addr, rs2
++ //
++ // All three operands are registers.
++ unsigned DestReg = MI->getOperand(0).getReg();
++ unsigned AddrReg = MI->getOperand(1).getReg();
++ unsigned Rs2Reg = MI->getOperand(2).getReg();
++
++ // SelectionDAG has already inserted memory barriers before and after MI, so
++ // we simply have to implement the operatiuon in terms of compare-and-swap.
++ //
++ // %val0 = load %addr
++ // loop:
++ // %val = phi %val0, %dest
++ // %upd = op %val, %rs2
++ // %dest = cas %addr, %upd, %val
++ // cmp %val, %dest
++ // bne loop
++ // done:
++ //
++ bool is64Bit = SP::I64RegsRegClass.hasSubClassEq(MRI.getRegClass(DestReg));
++ const TargetRegisterClass *ValueRC =
++ is64Bit ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
++ unsigned Val0Reg = MRI.createVirtualRegister(ValueRC);
++
++ BuildMI(*MBB, MI, DL, TII.get(is64Bit ? SP::LDXri : SP::LDri), Val0Reg)
++ .addReg(AddrReg).addImm(0);
++
++ // Split the basic block MBB before MI and insert the loop block in the hole.
++ MachineFunction::iterator MFI = MBB;
++ const BasicBlock *LLVM_BB = MBB->getBasicBlock();
++ MachineFunction *MF = MBB->getParent();
++ MachineBasicBlock *LoopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
++ MachineBasicBlock *DoneMBB = MF->CreateMachineBasicBlock(LLVM_BB);
++ ++MFI;
++ MF->insert(MFI, LoopMBB);
++ MF->insert(MFI, DoneMBB);
++
++ // Move MI and following instructions to DoneMBB.
++ DoneMBB->splice(DoneMBB->begin(), MBB, MI, MBB->end());
++ DoneMBB->transferSuccessorsAndUpdatePHIs(MBB);
++
++ // Connect the CFG again.
++ MBB->addSuccessor(LoopMBB);
++ LoopMBB->addSuccessor(LoopMBB);
++ LoopMBB->addSuccessor(DoneMBB);
++
++ // Build the loop block.
++ unsigned ValReg = MRI.createVirtualRegister(ValueRC);
++ unsigned UpdReg = MRI.createVirtualRegister(ValueRC);
++
++ BuildMI(LoopMBB, DL, TII.get(SP::PHI), ValReg)
++ .addReg(Val0Reg).addMBB(MBB)
++ .addReg(DestReg).addMBB(LoopMBB);
++
++ if (CondCode) {
++ // This is one of the min/max operations. We need a CMPrr followed by a
++ // MOVXCC/MOVICC.
++ BuildMI(LoopMBB, DL, TII.get(SP::CMPrr)).addReg(ValReg).addReg(Rs2Reg);
++ BuildMI(LoopMBB, DL, TII.get(Opcode), UpdReg)
++ .addReg(ValReg).addReg(Rs2Reg).addImm(CondCode);
++ } else {
++ BuildMI(LoopMBB, DL, TII.get(Opcode), UpdReg)
++ .addReg(ValReg).addReg(Rs2Reg);
++ }
++
++ if (MI->getOpcode() == SP::ATOMIC_LOAD_NAND_32 ||
++ MI->getOpcode() == SP::ATOMIC_LOAD_NAND_64) {
++ unsigned TmpReg = UpdReg;
++ UpdReg = MRI.createVirtualRegister(ValueRC);
++ BuildMI(LoopMBB, DL, TII.get(SP::XORri), UpdReg).addReg(TmpReg).addImm(-1);
++ }
++
++ BuildMI(LoopMBB, DL, TII.get(is64Bit ? SP::CASXrr : SP::CASrr), DestReg)
++ .addReg(AddrReg).addReg(UpdReg).addReg(ValReg)
++ .setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
++ BuildMI(LoopMBB, DL, TII.get(SP::CMPrr)).addReg(ValReg).addReg(DestReg);
++ BuildMI(LoopMBB, DL, TII.get(is64Bit ? SP::BPXCC : SP::BCOND))
++ .addMBB(LoopMBB).addImm(SPCC::ICC_NE);
++
++ MI->eraseFromParent();
++ return DoneMBB;
++}
++
+ //===----------------------------------------------------------------------===//
+ // Sparc Inline Assembly Support
+ //===----------------------------------------------------------------------===//
+Index: lib/Target/Sparc/SparcISelLowering.h
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.h
++++ lib/Target/Sparc/SparcISelLowering.h
+@@ -165,6 +165,13 @@ namespace llvm {
+ virtual void ReplaceNodeResults(SDNode *N,
+ SmallVectorImpl<SDValue>& Results,
+ SelectionDAG &DAG) const;
++
++ MachineBasicBlock *expandSelectCC(MachineInstr *MI, MachineBasicBlock *BB,
++ unsigned BROpcode) const;
++ MachineBasicBlock *expandAtomicRMW(MachineInstr *MI,
++ MachineBasicBlock *BB,
++ unsigned Opcode,
++ unsigned CondCode = 0) const;
+ };
+ } // end namespace llvm
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r199977-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r199977-sparc.diff
new file mode 100644
index 0000000..166b5da
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r199977-sparc.diff
@@ -0,0 +1,377 @@
+Pull in r199977 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9] Add support for JIT in Sparc64.
+ With this change, all supported tests in test/ExecutionEngine pass in sparcv9.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcJITInfo.cpp
+===================================================================
+--- lib/Target/Sparc/SparcJITInfo.cpp
++++ lib/Target/Sparc/SparcJITInfo.cpp
+@@ -12,8 +12,9 @@
+ //===----------------------------------------------------------------------===//
+ #define DEBUG_TYPE "jit"
+ #include "SparcJITInfo.h"
++#include "Sparc.h"
+ #include "SparcRelocations.h"
+-
++#include "llvm/ADT/SmallVector.h"
+ #include "llvm/CodeGen/JITCodeEmitter.h"
+ #include "llvm/Support/Memory.h"
+
+@@ -35,18 +36,17 @@ extern "C" {
+ "SparcCompilationCallback:\n"
+ // Save current register window.
+ "\tsave %sp, -192, %sp\n"
+- // stubaddr+4 is in %g1.
++ // stubaddr is in %g1.
+ "\tcall SparcCompilationCallbackC\n"
+- "\t sub %g1, 4, %o0\n"
++ "\t mov %g1, %o0\n"
+ // restore original register window and
+ // copy %o0 to %g1
+- "\t restore %o0, 0, %g1\n"
++ "\trestore %o0, 0, %g1\n"
+ // call the new stub
+ "\tjmp %g1\n"
+ "\t nop\n"
+ "\t.size SparcCompilationCallback, .-SparcCompilationCallback"
+ );
+-
+ #else
+ void SparcCompilationCallback() {
+ llvm_unreachable(
+@@ -55,33 +55,120 @@ extern "C" {
+ #endif
+ }
+
+-#define HI(Val) (((unsigned)(Val)) >> 10)
+-#define LO(Val) (((unsigned)(Val)) & 0x3FF)
+
+ #define SETHI_INST(imm, rd) (0x01000000 | ((rd) << 25) | ((imm) & 0x3FFFFF))
+ #define JMP_INST(rs1, imm, rd) (0x80000000 | ((rd) << 25) | (0x38 << 19) \
+ | ((rs1) << 14) | (1 << 13) | ((imm) & 0x1FFF))
+ #define NOP_INST SETHI_INST(0, 0)
++#define OR_INST_I(rs1, imm, rd) (0x80000000 | ((rd) << 25) | (0x02 << 19) \
++ | ((rs1) << 14) | (1 << 13) | ((imm) & 0x1FFF))
++#define OR_INST_R(rs1, rs2, rd) (0x80000000 | ((rd) << 25) | (0x02 << 19) \
++ | ((rs1) << 14) | (0 << 13) | ((rs2) & 0x1F))
++#define RDPC_INST(rd) (0x80000000 | ((rd) << 25) | (0x28 << 19) \
++ | (5 << 14))
++#define LDX_INST(rs1, imm, rd) (0xC0000000 | ((rd) << 25) | (0x0B << 19) \
++ | ((rs1) << 14) | (1 << 13) | ((imm) & 0x1FFF))
++#define SLLX_INST(rs1, imm, rd) (0x80000000 | ((rd) << 25) | (0x25 << 19) \
++ | ((rs1) << 14) | (3 << 12) | ((imm) & 0x3F))
++#define SUB_INST(rs1, imm, rd) (0x80000000 | ((rd) << 25) | (0x04 << 19) \
++ | ((rs1) << 14) | (1 << 13) | ((imm) & 0x1FFF))
++#define XOR_INST(rs1, imm, rd) (0x80000000 | ((rd) << 25) | (0x03 << 19) \
++ | ((rs1) << 14) | (1 << 13) | ((imm) & 0x1FFF))
++#define BA_INST(tgt) (0x10800000 | ((tgt) & 0x3FFFFF))
+
++// Emit instructions to jump to Addr and store the starting address of
++// the instructions emitted in the scratch register.
++static void emitInstrForIndirectJump(intptr_t Addr,
++ unsigned scratch,
++ SmallVectorImpl<uint32_t> &Insts) {
++
++ if (isInt<13>(Addr)) {
++ // Emit: jmpl %g0+Addr, <scratch>
++ // nop
++ Insts.push_back(JMP_INST(0, LO10(Addr), scratch));
++ Insts.push_back(NOP_INST);
++ return;
++ }
++
++ if (isUInt<32>(Addr)) {
++ // Emit: sethi %hi(Addr), scratch
++ // jmpl scratch+%lo(Addr), scratch
++ // sub scratch, 4, scratch
++ Insts.push_back(SETHI_INST(HI22(Addr), scratch));
++ Insts.push_back(JMP_INST(scratch, LO10(Addr), scratch));
++ Insts.push_back(SUB_INST(scratch, 4, scratch));
++ return;
++ }
++
++ if (Addr < 0 && isInt<33>(Addr)) {
++ // Emit: sethi %hix(Addr), scratch)
++ // xor scratch, %lox(Addr), scratch
++ // jmpl scratch+0, scratch
++ // sub scratch, 8, scratch
++ Insts.push_back(SETHI_INST(HIX22(Addr), scratch));
++ Insts.push_back(XOR_INST(scratch, LOX10(Addr), scratch));
++ Insts.push_back(JMP_INST(scratch, 0, scratch));
++ Insts.push_back(SUB_INST(scratch, 8, scratch));
++ return;
++ }
++
++ // Emit: rd %pc, scratch
++ // ldx [scratch+16], scratch
++ // jmpl scratch+0, scratch
++ // sub scratch, 8, scratch
++ // <Addr: 8 byte>
++ Insts.push_back(RDPC_INST(scratch));
++ Insts.push_back(LDX_INST(scratch, 16, scratch));
++ Insts.push_back(JMP_INST(scratch, 0, scratch));
++ Insts.push_back(SUB_INST(scratch, 8, scratch));
++ Insts.push_back((uint32_t)(((int64_t)Addr) >> 32) & 0xffffffff);
++ Insts.push_back((uint32_t)(Addr & 0xffffffff));
++
++ // Instruction sequence without rdpc instruction
++ // 7 instruction and 2 scratch register
++ // Emit: sethi %hh(Addr), scratch
++ // or scratch, %hm(Addr), scratch
++ // sllx scratch, 32, scratch
++ // sethi %hi(Addr), scratch2
++ // or scratch, scratch2, scratch
++ // jmpl scratch+%lo(Addr), scratch
++ // sub scratch, 20, scratch
++ // Insts.push_back(SETHI_INST(HH22(Addr), scratch));
++ // Insts.push_back(OR_INST_I(scratch, HM10(Addr), scratch));
++ // Insts.push_back(SLLX_INST(scratch, 32, scratch));
++ // Insts.push_back(SETHI_INST(HI22(Addr), scratch2));
++ // Insts.push_back(OR_INST_R(scratch, scratch2, scratch));
++ // Insts.push_back(JMP_INST(scratch, LO10(Addr), scratch));
++ // Insts.push_back(SUB_INST(scratch, 20, scratch));
++}
++
+ extern "C" void *SparcCompilationCallbackC(intptr_t StubAddr) {
+ // Get the address of the compiled code for this function.
+ intptr_t NewVal = (intptr_t) JITCompilerFunction((void*) StubAddr);
+
+ // Rewrite the function stub so that we don't end up here every time we
+- // execute the call. We're replacing the first three instructions of the
+- // stub with code that jumps to the compiled function:
+- // sethi %hi(NewVal), %g1
+- // jmp %g1+%lo(NewVal)
+- // nop
++ // execute the call. We're replacing the stub instructions with code
++ // that jumps to the compiled function:
+
+- *(intptr_t *)(StubAddr) = SETHI_INST(HI(NewVal), 1);
+- *(intptr_t *)(StubAddr + 4) = JMP_INST(1, LO(NewVal), 0);
+- *(intptr_t *)(StubAddr + 8) = NOP_INST;
++ SmallVector<uint32_t, 8> Insts;
++ intptr_t diff = (NewVal - StubAddr) >> 2;
++ if (isInt<22>(diff)) {
++ // Use branch instruction to jump
++ Insts.push_back(BA_INST(diff));
++ Insts.push_back(NOP_INST);
++ } else {
++ // Otherwise, use indirect jump to the compiled function
++ emitInstrForIndirectJump(NewVal, 1, Insts);
++ }
+
+- sys::Memory::InvalidateInstructionCache((void*) StubAddr, 12);
++ for (unsigned i = 0, e = Insts.size(); i != e; ++i)
++ *(uint32_t *)(StubAddr + i*4) = Insts[i];
++
++ sys::Memory::InvalidateInstructionCache((void*) StubAddr, Insts.size() * 4);
+ return (void*)StubAddr;
+ }
+
++
+ void SparcJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
+ assert(0 && "FIXME: Implement SparcJITInfo::replaceMachineCodeForFunction");
+ }
+@@ -88,10 +175,10 @@ void SparcJITInfo::replaceMachineCodeForFunction(v
+
+
+ TargetJITInfo::StubLayout SparcJITInfo::getStubLayout() {
+- // The stub contains 3 4-byte instructions, aligned at 4 bytes. See
+- // emitFunctionStub for details.
+-
+- StubLayout Result = { 3*4, 4 };
++ // The stub contains maximum of 4 4-byte instructions and 8 bytes for address,
++ // aligned at 32 bytes.
++ // See emitFunctionStub and emitInstrForIndirectJump for details.
++ StubLayout Result = { 4*4 + 8, 32 };
+ return Result;
+ }
+
+@@ -98,32 +185,41 @@ TargetJITInfo::StubLayout SparcJITInfo::getStubLay
+ void *SparcJITInfo::emitFunctionStub(const Function *F, void *Fn,
+ JITCodeEmitter &JCE)
+ {
+- JCE.emitAlignment(4);
++ JCE.emitAlignment(32);
+ void *Addr = (void*) (JCE.getCurrentPCValue());
+- if (!sys::Memory::setRangeWritable(Addr, 12))
+- llvm_unreachable("ERROR: Unable to mark stub writable.");
+
++ intptr_t CurrentAddr = (intptr_t)Addr;
+ intptr_t EmittedAddr;
+- if (Fn != (void*)(intptr_t)SparcCompilationCallback)
++ SmallVector<uint32_t, 8> Insts;
++ if (Fn != (void*)(intptr_t)SparcCompilationCallback) {
+ EmittedAddr = (intptr_t)Fn;
+- else
++ intptr_t diff = (EmittedAddr - CurrentAddr) >> 2;
++ if (isInt<22>(diff)) {
++ Insts.push_back(BA_INST(diff));
++ Insts.push_back(NOP_INST);
++ }
++ } else {
+ EmittedAddr = (intptr_t)SparcCompilationCallback;
++ }
+
+- // sethi %hi(EmittedAddr), %g1
+- // jmp %g1+%lo(EmittedAddr), %g1
+- // nop
++ if (Insts.size() == 0)
++ emitInstrForIndirectJump(EmittedAddr, 1, Insts);
+
+- JCE.emitWordBE(SETHI_INST(HI(EmittedAddr), 1));
+- JCE.emitWordBE(JMP_INST(1, LO(EmittedAddr), 1));
+- JCE.emitWordBE(NOP_INST);
+
+- sys::Memory::InvalidateInstructionCache(Addr, 12);
+- if (!sys::Memory::setRangeExecutable(Addr, 12))
++ if (!sys::Memory::setRangeWritable(Addr, 4 * Insts.size()))
++ llvm_unreachable("ERROR: Unable to mark stub writable.");
++
++ for (unsigned i = 0, e = Insts.size(); i != e; ++i)
++ JCE.emitWordBE(Insts[i]);
++
++ sys::Memory::InvalidateInstructionCache(Addr, 4 * Insts.size());
++ if (!sys::Memory::setRangeExecutable(Addr, 4 * Insts.size()))
+ llvm_unreachable("ERROR: Unable to mark stub executable.");
+
+ return Addr;
+ }
+
++
+ TargetJITInfo::LazyResolverFn
+ SparcJITInfo::getLazyResolverFunction(JITCompilerFn F) {
+ JITCompilerFunction = F;
+@@ -159,6 +255,27 @@ void SparcJITInfo::relocate(void *Function, Machin
+ case SP::reloc_sparc_pc19:
+ ResultPtr = ((ResultPtr - (intptr_t)RelocPos) >> 2) & 0x7ffff;
+ break;
++
++ case SP::reloc_sparc_h44:
++ ResultPtr = (ResultPtr >> 22) & 0x3fffff;
++ break;
++
++ case SP::reloc_sparc_m44:
++ ResultPtr = (ResultPtr >> 12) & 0x3ff;
++ break;
++
++ case SP::reloc_sparc_l44:
++ ResultPtr = (ResultPtr & 0xfff);
++ break;
++
++ case SP::reloc_sparc_hh:
++ ResultPtr = (((int64_t)ResultPtr) >> 42) & 0x3fffff;
++ break;
++
++ case SP::reloc_sparc_hm:
++ ResultPtr = (((int64_t)ResultPtr) >> 32) & 0x3ff;
++ break;
++
+ }
+ *((unsigned*) RelocPos) |= (unsigned) ResultPtr;
+ }
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+@@ -68,9 +68,13 @@ static MCCodeGenInfo *createSparcMCCodeGenInfo(Str
+ CodeGenOpt::Level OL) {
+ MCCodeGenInfo *X = new MCCodeGenInfo();
+
+- // The default 32-bit code model is abs32/pic32.
+- if (CM == CodeModel::Default)
+- CM = RM == Reloc::PIC_ ? CodeModel::Medium : CodeModel::Small;
++ // The default 32-bit code model is abs32/pic32 and the default 32-bit
++ // code model for JIT is abs32.
++ switch (CM) {
++ default: break;
++ case CodeModel::Default:
++ case CodeModel::JITDefault: CM = CodeModel::Small; break;
++ }
+
+ X->InitMCCodeGenInfo(RM, CM, OL);
+ return X;
+@@ -81,9 +85,17 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(S
+ CodeGenOpt::Level OL) {
+ MCCodeGenInfo *X = new MCCodeGenInfo();
+
+- // The default 64-bit code model is abs44/pic32.
+- if (CM == CodeModel::Default)
+- CM = CodeModel::Medium;
++ // The default 64-bit code model is abs44/pic32 and the default 64-bit
++ // code model for JIT is abs64.
++ switch (CM) {
++ default: break;
++ case CodeModel::Default:
++ CM = RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;
++ break;
++ case CodeModel::JITDefault:
++ CM = CodeModel::Large;
++ break;
++ }
+
+ X->InitMCCodeGenInfo(RM, CM, OL);
+ return X;
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1810,7 +1810,6 @@ SDValue SparcTargetLowering::makeAddress(SDValue O
+ switch(getTargetMachine().getCodeModel()) {
+ default:
+ llvm_unreachable("Unsupported absolute code model");
+- case CodeModel::JITDefault:
+ case CodeModel::Small:
+ // abs32.
+ return makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
+Index: lib/Target/Sparc/SparcCodeEmitter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcCodeEmitter.cpp
++++ lib/Target/Sparc/SparcCodeEmitter.cpp
+@@ -207,11 +207,11 @@ unsigned SparcCodeEmitter::getRelocation(const Mac
+ case SPII::MO_NO_FLAG: break;
+ case SPII::MO_LO: return SP::reloc_sparc_lo;
+ case SPII::MO_HI: return SP::reloc_sparc_hi;
+- case SPII::MO_H44:
+- case SPII::MO_M44:
+- case SPII::MO_L44:
+- case SPII::MO_HH:
+- case SPII::MO_HM: assert(0 && "FIXME: Implement Medium/Large code model.");
++ case SPII::MO_H44: return SP::reloc_sparc_h44;
++ case SPII::MO_M44: return SP::reloc_sparc_m44;
++ case SPII::MO_L44: return SP::reloc_sparc_l44;
++ case SPII::MO_HH: return SP::reloc_sparc_hh;
++ case SPII::MO_HM: return SP::reloc_sparc_hm;
+ }
+
+ unsigned Opc = MI.getOpcode();
+Index: lib/Target/Sparc/SparcRelocations.h
+===================================================================
+--- lib/Target/Sparc/SparcRelocations.h
++++ lib/Target/Sparc/SparcRelocations.h
+@@ -33,7 +33,22 @@ namespace llvm {
+ reloc_sparc_pc22 = 4,
+
+ // reloc_sparc_pc22 - pc rel. 19 bits for branch with icc/xcc
+- reloc_sparc_pc19 = 5
++ reloc_sparc_pc19 = 5,
++
++ // reloc_sparc_h44 - 43-22 bits
++ reloc_sparc_h44 = 6,
++
++ // reloc_sparc_m44 - 21-12 bits
++ reloc_sparc_m44 = 7,
++
++ // reloc_sparc_l44 - lower 12 bits
++ reloc_sparc_l44 = 8,
++
++ // reloc_sparc_hh - 63-42 bits
++ reloc_sparc_hh = 9,
++
++ // reloc_sparc_hm - 41-32 bits
++ reloc_sparc_hm = 10
+ };
+ }
+ }
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200103-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200103-sparc.diff
new file mode 100644
index 0000000..a2fd7d2
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200103-sparc.diff
@@ -0,0 +1,49 @@
+Pull in r200103 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ Missing ELF relocations for Sparc.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: include/llvm/Support/ELF.h
+===================================================================
+--- include/llvm/Support/ELF.h
++++ include/llvm/Support/ELF.h
+@@ -1143,7 +1143,37 @@ enum {
+ R_SPARC_L44 = 52,
+ R_SPARC_REGISTER = 53,
+ R_SPARC_UA64 = 54,
+- R_SPARC_UA16 = 55
++ R_SPARC_UA16 = 55,
++ R_SPARC_UA16 = 55,
++ R_SPARC_TLS_GD_HI22 = 56,
++ R_SPARC_TLS_GD_LO10 = 57,
++ R_SPARC_TLS_GD_ADD = 58,
++ R_SPARC_TLS_GD_CALL = 59,
++ R_SPARC_TLS_LDM_HI22 = 60,
++ R_SPARC_TLS_LDM_LO10 = 61,
++ R_SPARC_TLS_LDM_ADD = 62,
++ R_SPARC_TLS_LDM_CALL = 63,
++ R_SPARC_TLS_LDO_HIX22 = 64,
++ R_SPARC_TLS_LDO_LOX10 = 65,
++ R_SPARC_TLS_LDO_ADD = 66,
++ R_SPARC_TLS_IE_HI22 = 67,
++ R_SPARC_TLS_IE_LO10 = 68,
++ R_SPARC_TLS_IE_LD = 69,
++ R_SPARC_TLS_IE_LDX = 70,
++ R_SPARC_TLS_IE_ADD = 71,
++ R_SPARC_TLS_LE_HIX22 = 72,
++ R_SPARC_TLS_LE_LOX10 = 73,
++ R_SPARC_TLS_DTPMOD32 = 74,
++ R_SPARC_TLS_DTPMOD64 = 75,
++ R_SPARC_TLS_DTPOFF32 = 76,
++ R_SPARC_TLS_DTPOFF64 = 77,
++ R_SPARC_TLS_TPOFF32 = 78,
++ R_SPARC_TLS_TPOFF64 = 79,
++ R_SPARC_GOTDATA_HIX22 = 80,
++ R_SPARC_GOTDATA_LOX22 = 81,
++ R_SPARC_GOTDATA_OP_HIX22 = 82,
++ R_SPARC_GOTDATA_OP_LOX22 = 83,
++ R_SPARC_GOTDATA_OP = 84
+ };
+
+ // Section header.
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200104-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200104-sparc.diff
new file mode 100644
index 0000000..c489ca1
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200104-sparc.diff
@@ -0,0 +1,18 @@
+Pull in r200104 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ removing duplicate enum value
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: include/llvm/Support/ELF.h
+===================================================================
+--- include/llvm/Support/ELF.h
++++ include/llvm/Support/ELF.h
+@@ -1144,7 +1144,6 @@ enum {
+ R_SPARC_REGISTER = 53,
+ R_SPARC_UA64 = 54,
+ R_SPARC_UA16 = 55,
+- R_SPARC_UA16 = 55,
+ R_SPARC_TLS_GD_HI22 = 56,
+ R_SPARC_TLS_GD_LO10 = 57,
+ R_SPARC_TLS_GD_ADD = 58,
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200112-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200112-sparc.diff
new file mode 100644
index 0000000..f499b59
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200112-sparc.diff
@@ -0,0 +1,169 @@
+Pull in r200112 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add support for sparc relocation types in ELF object file.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/MC/Sparc/sparc-relocations.s
+===================================================================
+--- test/MC/Sparc/sparc-relocations.s
++++ test/MC/Sparc/sparc-relocations.s
+@@ -1,5 +1,18 @@
+ ! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
++! RUN: llvm-mc %s -arch=sparcv9 -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-OBJ
+
++ ! CHECK-OBJ: Format: ELF64-sparc
++ ! CHECK-OBJ: Relocations [
++ ! CHECK-OBJ: 0x{{[0-9,A-F]+}} R_SPARC_WDISP30 foo
++ ! CHECK-OBJ: 0x{{[0-9,A-F]+}} R_SPARC_LO10 sym
++ ! CHECK-OBJ: 0x{{[0-9,A-F]+}} R_SPARC_HI22 sym
++ ! CHECK-OBJ: 0x{{[0-9,A-F]+}} R_SPARC_H44 sym
++ ! CHECK-OBJ: 0x{{[0-9,A-F]+}} R_SPARC_M44 sym
++ ! CHECK-OBJ: 0x{{[0-9,A-F]+}} R_SPARC_L44 sym
++ ! CHECK-OBJ: 0x{{[0-9,A-F]+}} R_SPARC_HH22 sym
++ ! CHECK-OBJ: 0x{{[0-9,A-F]+}} R_SPARC_HM10 sym
++ ! CHECK-ELF: ]
++
+ ! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
+ ! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
+ call foo
+Index: include/llvm/Object/ELFObjectFile.h
+===================================================================
+--- include/llvm/Object/ELFObjectFile.h
++++ include/llvm/Object/ELFObjectFile.h
+@@ -922,6 +922,9 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName()
+ return "ELF32-mips";
+ case ELF::EM_PPC:
+ return "ELF32-ppc";
++ case ELF::EM_SPARC:
++ case ELF::EM_SPARC32PLUS:
++ return "ELF32-sparc";
+ default:
+ return "ELF32-unknown";
+ }
+@@ -937,6 +940,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName()
+ return "ELF64-ppc64";
+ case ELF::EM_S390:
+ return "ELF64-s390";
++ case ELF::EM_SPARCV9:
++ return "ELF64-sparc";
+ default:
+ return "ELF64-unknown";
+ }
+@@ -967,6 +972,13 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
+ : Triple::ppc64;
+ case ELF::EM_S390:
+ return Triple::systemz;
++
++ case ELF::EM_SPARC:
++ case ELF::EM_SPARC32PLUS:
++ return Triple::sparc;
++ case ELF::EM_SPARCV9:
++ return Triple::sparcv9;
++
+ default:
+ return Triple::UnknownArch;
+ }
+Index: lib/Object/ELF.cpp
+===================================================================
+--- lib/Object/ELF.cpp
++++ lib/Object/ELF.cpp
+@@ -702,6 +702,98 @@ StringRef getELFRelocationTypeName(uint32_t Machin
+ break;
+ }
+ break;
++ case ELF::EM_SPARC:
++ case ELF::EM_SPARC32PLUS:
++ case ELF::EM_SPARCV9:
++ switch (Type) {
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_NONE);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_8);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_16);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_32);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_DISP8);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_DISP16);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_DISP32);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WDISP30);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WDISP22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HI22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_13);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_LO10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOT10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOT13);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOT22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WPLT30);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_COPY);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GLOB_DAT);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_JMP_SLOT);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_RELATIVE);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_UA32);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PLT32);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HIPLT22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_LOPLT10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PCPLT32);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PCPLT22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PCPLT10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_11);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_64);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_OLO10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HH22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HM10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_LM22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC_HH22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC_HM10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC_LM22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WDISP16);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WDISP19);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_7);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_5);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_6);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_DISP64);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PLT64);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HIX22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_LOX10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_H44);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_M44);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_L44);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_REGISTER);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_UA64);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_UA16);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_GD_HI22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_GD_LO10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_GD_ADD);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_GD_CALL);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDM_HI22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDM_LO10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDM_ADD);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDM_CALL);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDO_HIX22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDO_LOX10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDO_ADD);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_HI22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_LO10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_LD);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_LDX);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_ADD);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LE_HIX22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LE_LOX10);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_DTPMOD32);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_DTPMOD64);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_DTPOFF32);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_DTPOFF64);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_TPOFF32);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_TPOFF64);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_HIX22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_LOX22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_OP_HIX22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_OP_LOX22);
++ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_OP);
++ default:
++ break;
++ }
++ break;
+ default:
+ break;
+ }
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200130-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200130-sparc.diff
new file mode 100644
index 0000000..aad6ae9
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200130-sparc.diff
@@ -0,0 +1,45 @@
+Pull in r200130 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Fix swapped CASA operands.
+
+ Found by SingleSource/UnitTests/AtomicOps.c
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -2972,7 +2972,7 @@ SparcTargetLowering::expandAtomicRMW(MachineInstr
+ // loop:
+ // %val = phi %val0, %dest
+ // %upd = op %val, %rs2
+- // %dest = cas %addr, %upd, %val
++ // %dest = cas %addr, %val, %upd
+ // cmp %val, %dest
+ // bne loop
+ // done:
+@@ -3031,7 +3031,7 @@ SparcTargetLowering::expandAtomicRMW(MachineInstr
+ }
+
+ BuildMI(LoopMBB, DL, TII.get(is64Bit ? SP::CASXrr : SP::CASrr), DestReg)
+- .addReg(AddrReg).addReg(UpdReg).addReg(ValReg)
++ .addReg(AddrReg).addReg(ValReg).addReg(UpdReg)
+ .setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
+ BuildMI(LoopMBB, DL, TII.get(SP::CMPrr)).addReg(ValReg).addReg(DestReg);
+ BuildMI(LoopMBB, DL, TII.get(is64Bit ? SP::BPXCC : SP::BCOND))
+Index: test/CodeGen/SPARC/atomics.ll
+===================================================================
+--- test/CodeGen/SPARC/atomics.ll
++++ test/CodeGen/SPARC/atomics.ll
+@@ -64,8 +64,8 @@ entry:
+
+ ; CHECK-LABEL: test_load_add_32
+ ; CHECK: membar
+-; CHECK: add
+-; CHECK: cas [%o0]
++; CHECK: add [[V:%[gilo][0-7]]], %o1, [[U:%[gilo][0-7]]]
++; CHECK: cas [%o0], [[V]], [[U]]
+ ; CHECK: membar
+ define zeroext i32 @test_load_add_32(i32* %p, i32 zeroext %v) {
+ entry:
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200131-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200131-sparc.diff
new file mode 100644
index 0000000..6b0ab16
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200131-sparc.diff
@@ -0,0 +1,117 @@
+Pull in r200131 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Only generate the popc instruction for SPARC CPUs that implement it.
+
+ The popc instruction is defined in the SPARCv9 instruction set
+ architecture, but it was emulated on CPUs older than Niagara 2.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1461,7 +1461,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+ setOperationAction(ISD::BR_CC, MVT::i64, Custom);
+ setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
+
+- setOperationAction(ISD::CTPOP, MVT::i64, Legal);
++ if (Subtarget->usePopc())
++ setOperationAction(ISD::CTPOP, MVT::i64, Legal);
+ setOperationAction(ISD::CTTZ , MVT::i64, Expand);
+ setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand);
+ setOperationAction(ISD::CTLZ , MVT::i64, Expand);
+@@ -1567,7 +1568,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+
+ setStackPointerRegisterToSaveRestore(SP::O6);
+
+- if (Subtarget->isV9())
++ if (Subtarget->isV9() && Subtarget->usePopc())
+ setOperationAction(ISD::CTPOP, MVT::i32, Legal);
+
+ if (Subtarget->isV9() && Subtarget->hasHardQuad()) {
+Index: lib/Target/Sparc/Sparc.td
+===================================================================
+--- lib/Target/Sparc/Sparc.td
++++ lib/Target/Sparc/Sparc.td
+@@ -34,6 +34,9 @@ def FeatureHardQuad
+ : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true",
+ "Enable quad-word floating point instructions">;
+
++def UsePopc : SubtargetFeature<"popc", "UsePopc", "true",
++ "Use the popc (population count) instruction">;
++
+ //===----------------------------------------------------------------------===//
+ // Register File, Calling Conv, Instruction Descriptions
+ //===----------------------------------------------------------------------===//
+@@ -69,9 +72,9 @@ def : Proc<"v9", [FeatureV9]>;
+ def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated]>;
+ def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>;
+ def : Proc<"niagara", [FeatureV9, FeatureV8Deprecated]>;
+-def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated]>;
+-def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated]>;
+-def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated]>;
++def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated, UsePopc]>;
++def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated, UsePopc]>;
++def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated, UsePopc]>;
+
+ def SparcAsmWriter : AsmWriter {
+ string AsmWriterClassName = "InstPrinter";
+Index: lib/Target/Sparc/SparcSubtarget.h
+===================================================================
+--- lib/Target/Sparc/SparcSubtarget.h
++++ lib/Target/Sparc/SparcSubtarget.h
+@@ -30,6 +30,7 @@ class SparcSubtarget : public SparcGenSubtargetInf
+ bool IsVIS;
+ bool Is64Bit;
+ bool HasHardQuad;
++ bool UsePopc;
+
+ public:
+ SparcSubtarget(const std::string &TT, const std::string &CPU,
+@@ -39,6 +40,7 @@ class SparcSubtarget : public SparcGenSubtargetInf
+ bool isVIS() const { return IsVIS; }
+ bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; }
+ bool hasHardQuad() const { return HasHardQuad; }
++ bool usePopc() const { return UsePopc; }
+
+ /// ParseSubtargetFeatures - Parses features string setting specified
+ /// subtarget options. Definition of function is auto generated by tblgen.
+Index: lib/Target/Sparc/SparcSubtarget.cpp
+===================================================================
+--- lib/Target/Sparc/SparcSubtarget.cpp
++++ lib/Target/Sparc/SparcSubtarget.cpp
+@@ -31,7 +31,8 @@ SparcSubtarget::SparcSubtarget(const std::string &
+ V8DeprecatedInsts(false),
+ IsVIS(false),
+ Is64Bit(is64Bit),
+- HasHardQuad(false) {
++ HasHardQuad(false),
++ UsePopc(false) {
+
+ // Determine default and user specified characteristics
+ std::string CPUName = CPU;
+Index: test/CodeGen/SPARC/ctpop.ll
+===================================================================
+--- test/CodeGen/SPARC/ctpop.ll
++++ test/CodeGen/SPARC/ctpop.ll
+@@ -1,13 +1,13 @@
+ ; RUN: llc < %s -march=sparc -mattr=-v9 | FileCheck %s -check-prefix=V8
+-; RUN: llc < %s -march=sparc -mattr=+v9 | FileCheck %s -check-prefix=V9
+-; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V9
+-; RUN: llc < %s -march=sparc -mcpu=ultrasparc | FileCheck %s -check-prefix=V9
+-; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V9
+-; RUN: llc < %s -march=sparc -mcpu=niagara | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparc -mattr=+v9,+popc | FileCheck %s -check-prefix=V9
++; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V8
++; RUN: llc < %s -march=sparc -mcpu=ultrasparc | FileCheck %s -check-prefix=V8
++; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V8
++; RUN: llc < %s -march=sparc -mcpu=niagara | FileCheck %s -check-prefix=V8
+ ; RUN: llc < %s -march=sparc -mcpu=niagara2 | FileCheck %s -check-prefix=V9
+ ; RUN: llc < %s -march=sparc -mcpu=niagara3 | FileCheck %s -check-prefix=V9
+ ; RUN: llc < %s -march=sparc -mcpu=niagara4 | FileCheck %s -check-prefix=V9
+-; RUN: llc < %s -march=sparcv9 | FileCheck %s -check-prefix=SPARC64
++; RUN: llc < %s -march=sparcv9 -mattr=+popc | FileCheck %s -check-prefix=SPARC64
+
+ declare i32 @llvm.ctpop.i32(i32)
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200141-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200141-sparc.diff
new file mode 100644
index 0000000..d8016e8
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200141-sparc.diff
@@ -0,0 +1,67 @@
+Pull in r200141 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Clean up the Legal/Expand logic for SPARC popc.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcSubtarget.cpp
+===================================================================
+--- lib/Target/Sparc/SparcSubtarget.cpp
++++ lib/Target/Sparc/SparcSubtarget.cpp
+@@ -41,6 +41,10 @@ SparcSubtarget::SparcSubtarget(const std::string &
+
+ // Parse features string.
+ ParseSubtargetFeatures(CPUName, FS);
++
++ // Popc is a v9-only instruction.
++ if (!IsV9)
++ UsePopc = false;
+ }
+
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1461,8 +1461,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+ setOperationAction(ISD::BR_CC, MVT::i64, Custom);
+ setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
+
+- if (Subtarget->usePopc())
+- setOperationAction(ISD::CTPOP, MVT::i64, Legal);
++ setOperationAction(ISD::CTPOP, MVT::i64,
++ Subtarget->usePopc() ? Legal : Expand);
+ setOperationAction(ISD::CTTZ , MVT::i64, Expand);
+ setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand);
+ setOperationAction(ISD::CTLZ , MVT::i64, Expand);
+@@ -1518,7 +1518,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+ setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
+ setOperationAction(ISD::FREM , MVT::f32, Expand);
+ setOperationAction(ISD::FMA , MVT::f32, Expand);
+- setOperationAction(ISD::CTPOP, MVT::i32, Expand);
+ setOperationAction(ISD::CTTZ , MVT::i32, Expand);
+ setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
+ setOperationAction(ISD::CTLZ , MVT::i32, Expand);
+@@ -1568,8 +1567,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+
+ setStackPointerRegisterToSaveRestore(SP::O6);
+
+- if (Subtarget->isV9() && Subtarget->usePopc())
+- setOperationAction(ISD::CTPOP, MVT::i32, Legal);
++ setOperationAction(ISD::CTPOP, MVT::i32,
++ Subtarget->usePopc() ? Legal : Expand);
+
+ if (Subtarget->isV9() && Subtarget->hasHardQuad()) {
+ setOperationAction(ISD::LOAD, MVT::f128, Legal);
+Index: test/CodeGen/SPARC/64bit.ll
+===================================================================
+--- test/CodeGen/SPARC/64bit.ll
++++ test/CodeGen/SPARC/64bit.ll
+@@ -1,5 +1,5 @@
+-; RUN: llc < %s -march=sparcv9 -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck %s
+-; RUN: llc < %s -march=sparcv9 | FileCheck %s -check-prefix=OPT
++; RUN: llc < %s -march=sparcv9 -mattr=+popc -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck %s
++; RUN: llc < %s -march=sparcv9 -mattr=+popc | FileCheck %s -check-prefix=OPT
+
+ ; CHECK-LABEL: ret2:
+ ; CHECK: or %g0, %i1, %i0
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200282-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200282-sparc.diff
new file mode 100644
index 0000000..95f2868
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200282-sparc.diff
@@ -0,0 +1,183 @@
+Pull in r200282 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Fix the DWARF EH encodings for Sparc PIC code.
+
+ Also emit the stubs that were generated for references to typeinfo
+ symbols.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -23,7 +23,9 @@
+ #include "llvm/ADT/SmallString.h"
+ #include "llvm/CodeGen/AsmPrinter.h"
+ #include "llvm/CodeGen/MachineInstr.h"
++#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+ #include "llvm/CodeGen/MachineRegisterInfo.h"
++#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+ #include "llvm/MC/MCAsmInfo.h"
+ #include "llvm/MC/MCContext.h"
+ #include "llvm/MC/MCInst.h"
+@@ -54,6 +56,7 @@ namespace {
+
+ virtual void EmitFunctionBodyStart();
+ virtual void EmitInstruction(const MachineInstr *MI);
++ virtual void EmitEndOfAsmFile(Module &M);
+
+ static const char *getRegisterName(unsigned RegNo) {
+ return SparcInstPrinter::getRegisterName(RegNo);
+@@ -450,6 +453,23 @@ bool SparcAsmPrinter::PrintAsmMemoryOperand(const
+ return false;
+ }
+
++void SparcAsmPrinter::EmitEndOfAsmFile(Module &M) {
++ const TargetLoweringObjectFileELF &TLOFELF =
++ static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());
++ MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
++
++ // Generate stubs for global variables.
++ MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
++ if (!Stubs.empty()) {
++ OutStreamer.SwitchSection(TLOFELF.getDataSection());
++ unsigned PtrSize = TM.getDataLayout()->getPointerSize(0);
++ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
++ OutStreamer.EmitLabel(Stubs[i].first);
++ OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), PtrSize);
++ }
++ }
++}
++
+ // Force static initialization.
+ extern "C" void LLVMInitializeSparcAsmPrinter() {
+ RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget);
+Index: lib/MC/MCObjectFileInfo.cpp
+===================================================================
+--- lib/MC/MCObjectFileInfo.cpp
++++ lib/MC/MCObjectFileInfo.cpp
+@@ -310,6 +310,33 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Tri
+ FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
+ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_udata8;
++ } else if (T.getArch() == Triple::sparc) {
++ if (RelocM == Reloc::PIC_) {
++ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
++ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
++ dwarf::DW_EH_PE_sdata4;
++ FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
++ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
++ dwarf::DW_EH_PE_sdata4;
++ } else {
++ LSDAEncoding = dwarf::DW_EH_PE_absptr;
++ PersonalityEncoding = dwarf::DW_EH_PE_absptr;
++ FDEEncoding = dwarf::DW_EH_PE_udata4;
++ TTypeEncoding = dwarf::DW_EH_PE_absptr;
++ }
++ } else if (T.getArch() == Triple::sparcv9) {
++ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
++ if (RelocM == Reloc::PIC_) {
++ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
++ dwarf::DW_EH_PE_sdata4;
++ FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
++ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
++ dwarf::DW_EH_PE_sdata4;
++ } else {
++ PersonalityEncoding = dwarf::DW_EH_PE_absptr;
++ FDEEncoding = dwarf::DW_EH_PE_udata4;
++ TTypeEncoding = dwarf::DW_EH_PE_absptr;
++ }
+ } else if (T.getArch() == Triple::systemz) {
+ // All currently-defined code models guarantee that 4-byte PC-relative
+ // values will be in range.
+Index: test/CodeGen/SPARC/exception.ll
+===================================================================
+--- test/CodeGen/SPARC/exception.ll
++++ test/CodeGen/SPARC/exception.ll
+@@ -1,4 +1,7 @@
+-; RUN: llc < %s -march=sparc | FileCheck %s
++; RUN: llc < %s -march=sparc -relocation-model=static | FileCheck -check-prefix=V8ABS %s
++; RUN: llc < %s -march=sparc -relocation-model=pic | FileCheck -check-prefix=V8PIC %s
++; RUN: llc < %s -march=sparcv9 -relocation-model=static | FileCheck -check-prefix=V9ABS %s
++; RUN: llc < %s -march=sparcv9 -relocation-model=pic | FileCheck -check-prefix=V9PIC %s
+
+
+ %struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo }
+@@ -9,23 +12,64 @@
+ @.cst = linker_private unnamed_addr constant [12 x i8] c"catched int\00", align 64
+ @.cst1 = linker_private unnamed_addr constant [14 x i8] c"catched float\00", align 64
+
+-; CHECK-LABEL: main:
+-; CHECK: .cfi_startproc
+-; CHECK: .cfi_def_cfa_register {{30|%fp}}
+-; CHECK: .cfi_window_save
+-; CHECK: .cfi_register 15, 31
++; V8ABS-LABEL: main:
++; V8ABS: .cfi_startproc
++; V8ABS: .cfi_personality 0, __gxx_personality_v0
++; V8ABS: .cfi_lsda 0,
++; V8ABS: .cfi_def_cfa_register {{30|%fp}}
++; V8ABS: .cfi_window_save
++; V8ABS: .cfi_register 15, 31
+
+-; CHECK: call __cxa_throw
+-; CHECK: call __cxa_throw
++; V8ABS: call __cxa_throw
++; V8ABS: call __cxa_throw
+
+-; CHECK: call __cxa_begin_catch
+-; CHECK: call __cxa_end_catch
++; V8ABS: call __cxa_begin_catch
++; V8ABS: call __cxa_end_catch
+
+-; CHECK: call __cxa_begin_catch
+-; CHECK: call __cxa_end_catch
++; V8ABS: call __cxa_begin_catch
++; V8ABS: call __cxa_end_catch
+
+-; CHECK: .cfi_endproc
++; V8ABS: .cfi_endproc
+
++; V8PIC-LABEL: main:
++; V8PIC: .cfi_startproc
++; V8PIC: .cfi_personality 155, DW.ref.__gxx_personality_v0
++; V8PIC: .cfi_lsda 27,
++; V8PIC: .cfi_def_cfa_register {{30|%fp}}
++; V8PIC: .cfi_window_save
++; V8PIC: .cfi_register 15, 31
++; V8PIC: .section .gcc_except_table
++; V8PIC-NOT: .section
++; V8PIC: .word .L_ZTIi.DW.stub-
++; V8PIC: .data
++; V8PIC: .L_ZTIi.DW.stub:
++; V8PIC-NEXT: .word _ZTIi
++
++; V9ABS-LABEL: main:
++; V9ABS: .cfi_startproc
++; V9ABS: .cfi_personality 0, __gxx_personality_v0
++; V9ABS: .cfi_lsda 27,
++; V9ABS: .cfi_def_cfa_register {{30|%fp}}
++; V9ABS: .cfi_window_save
++; V9ABS: .cfi_register 15, 31
++; V9ABS: .section .gcc_except_table
++; V9ABS-NOT: .section
++; V9ABS: .xword _ZTIi
++
++; V9PIC-LABEL: main:
++; V9PIC: .cfi_startproc
++; V9PIC: .cfi_personality 155, DW.ref.__gxx_personality_v0
++; V9PIC: .cfi_lsda 27,
++; V9PIC: .cfi_def_cfa_register {{30|%fp}}
++; V9PIC: .cfi_window_save
++; V9PIC: .cfi_register 15, 31
++; V9PIC: .section .gcc_except_table
++; V9PIC-NOT: .section
++; V9PIC: .word .L_ZTIi.DW.stub-
++; V9PIC: .data
++; V9PIC: .L_ZTIi.DW.stub:
++; V9PIC-NEXT: .xword _ZTIi
++
+ define i32 @main(i32 %argc, i8** nocapture readnone %argv) unnamed_addr #0 {
+ entry:
+ %0 = icmp eq i32 %argc, 2
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200368-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200368-sparc.diff
new file mode 100644
index 0000000..f596b5f
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200368-sparc.diff
@@ -0,0 +1,88 @@
+Pull r200368 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [SparcV9] Use correct register class (I64RegClass) to hold the address of _GLOBAL_OFFSET_TABLE_ in sparcv9.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcInstrInfo.cpp
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.cpp
++++ lib/Target/Sparc/SparcInstrInfo.cpp
+@@ -431,9 +431,10 @@ unsigned SparcInstrInfo::getGlobalBaseReg(MachineF
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ MachineRegisterInfo &RegInfo = MF->getRegInfo();
+
+- GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
++ const TargetRegisterClass *PtrRC =
++ Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
++ GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);
+
+-
+ DebugLoc dl;
+
+ BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -180,7 +180,7 @@ def tlscall : SDNode<"SPISD::TLS_CALL", SDT_
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
+ SDNPVariadic]>;
+
+-def getPCX : Operand<i32> {
++def getPCX : Operand<iPTR> {
+ let PrintMethod = "printGetPCX";
+ }
+
+Index: test/CodeGen/SPARC/2009-08-28-PIC.ll
+===================================================================
+--- test/CodeGen/SPARC/2009-08-28-PIC.ll
++++ test/CodeGen/SPARC/2009-08-28-PIC.ll
+@@ -1,9 +1,45 @@
+-; RUN: llc -march=sparc --relocation-model=pic < %s | grep _GLOBAL_OFFSET_TABLE_
++; RUN: llc -march=sparc --relocation-model=pic < %s | FileCheck %s --check-prefix=V8
++; RUN: llc -march=sparcv9 --relocation-model=pic < %s | FileCheck %s --check-prefix=V9
++; RUN: llc -march=sparc --relocation-model=pic < %s -O0 | FileCheck %s --check-prefix=V8UNOPT
++; RUN: llc -march=sparcv9 --relocation-model=pic < %s -O0 | FileCheck %s --check-prefix=V9UNOPT
+
++
++; V8-LABEL: func
++; V8: _GLOBAL_OFFSET_TABLE_
++
++; V9-LABEL: func
++; V9: _GLOBAL_OFFSET_TABLE_
++
+ @foo = global i32 0 ; <i32*> [#uses=1]
+
+-define i32 @func() nounwind readonly {
++define i32 @func(i32 %a) nounwind readonly {
+ entry:
+ %0 = load i32* @foo, align 4 ; <i32> [#uses=1]
+ ret i32 %0
+ }
++
++; V8UNOPT-LABEL: test_spill
++; V8UNOPT: sethi %hi(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[R:%[goli][0-7]]]
++; V8UNOPT: or [[R]], %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[R]]
++; V8UNOPT: add [[R]], %o7, [[R]]
++; V8UNOPT: st [[R]], [%fp+{{.+}}]
++
++; V9UNOPT-LABEL: test_spill
++; V9UNOPT: sethi %hi(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[R:%[goli][0-7]]]
++; V9UNOPT: or [[R]], %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[R]]
++; V9UNOPT: add [[R]], %o7, [[R]]
++; V9UNOPT: stx [[R]], [%fp+{{.+}}]
++
++define i32 @test_spill(i32 %a, i32 %b) {
++entry:
++ %cmp = icmp eq i32 %b, 0
++ br i1 %cmp, label %if.then, label %if.end
++
++if.then:
++ %ret = load i32* @foo, align 4
++ ret i32 %ret
++
++if.end:
++ %add = add nsw i32 %b, %a
++ ret i32 %add
++}
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200373-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200373-sparc.diff
new file mode 100644
index 0000000..f9bed35
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200373-sparc.diff
@@ -0,0 +1,296 @@
+Pull in r200373 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Use %r_disp32 for pc_rel entries in gcc_except_table and eh_frame.
+
+ Otherwise, assembler (gas) fails to assemble them with error message "operation
+ combines symbols in different segments". This is because MC computes
+ pc_rel entries with subtract expression between labels from different sections.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcTargetObjectFile.h
+===================================================================
+--- lib/Target/Sparc/SparcTargetObjectFile.h
++++ lib/Target/Sparc/SparcTargetObjectFile.h
+@@ -0,0 +1,34 @@
++//===-- SparcTargetObjectFile.h - Sparc Object Info -------------*- C++ -*-===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++
++#ifndef LLVM_TARGET_SPARC_TARGETOBJECTFILE_H
++#define LLVM_TARGET_SPARC_TARGETOBJECTFILE_H
++
++#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
++
++namespace llvm {
++
++class MCContext;
++class TargetMachine;
++
++class SparcELFTargetObjectFile : public TargetLoweringObjectFileELF {
++public:
++ SparcELFTargetObjectFile() :
++ TargetLoweringObjectFileELF()
++ {}
++
++ const MCExpr *
++ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
++ MachineModuleInfo *MMI, unsigned Encoding,
++ MCStreamer &Streamer) const;
++};
++
++} // end namespace llvm
++
++#endif
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -16,6 +16,7 @@
+ #include "SparcMachineFunctionInfo.h"
+ #include "SparcRegisterInfo.h"
+ #include "SparcTargetMachine.h"
++#include "SparcTargetObjectFile.h"
+ #include "MCTargetDesc/SparcBaseInfo.h"
+ #include "llvm/CodeGen/CallingConvLower.h"
+ #include "llvm/CodeGen/MachineFrameInfo.h"
+@@ -1361,7 +1362,7 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondC
+ }
+
+ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
+- : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
++ : TargetLowering(TM, new SparcELFTargetObjectFile()) {
+ Subtarget = &TM.getSubtarget<SparcSubtarget>();
+
+ // Set up the register classes.
+Index: lib/Target/Sparc/SparcTargetObjectFile.cpp
+===================================================================
+--- lib/Target/Sparc/SparcTargetObjectFile.cpp
++++ lib/Target/Sparc/SparcTargetObjectFile.cpp
+@@ -0,0 +1,48 @@
++//===------- SparcTargetObjectFile.cpp - Sparc Object Info Impl -----------===//
++//
++// The LLVM Compiler Infrastructure
++//
++// This file is distributed under the University of Illinois Open Source
++// License. See LICENSE.TXT for details.
++//
++//===----------------------------------------------------------------------===//
++
++#include "SparcTargetObjectFile.h"
++#include "MCTargetDesc/SparcMCExpr.h"
++#include "llvm/CodeGen/MachineModuleInfoImpls.h"
++#include "llvm/Support/Dwarf.h"
++#include "llvm/Target/Mangler.h"
++
++using namespace llvm;
++
++
++const MCExpr *SparcELFTargetObjectFile::
++getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
++ MachineModuleInfo *MMI, unsigned Encoding,
++ MCStreamer &Streamer) const {
++
++ if (Encoding & dwarf::DW_EH_PE_pcrel) {
++ MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
++
++ //MCSymbol *SSym = getSymbolWithGlobalValueBase(*Mang, GV, ".DW.stub");
++ SmallString<60> NameStr;
++ Mang->getNameWithPrefix(NameStr, GV, true);
++ NameStr.append(".DW.stub");
++ MCSymbol *SSym = getContext().GetOrCreateSymbol(NameStr.str());
++
++ // Add information about the stub reference to ELFMMI so that the stub
++ // gets emitted by the asmprinter.
++ MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
++ if (StubSym.getPointer() == 0) {
++ MCSymbol *Sym = getSymbol(*Mang, GV);
++ StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
++ }
++
++ MCContext &Ctx = getContext();
++ return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32,
++ MCSymbolRefExpr::Create(SSym, Ctx), Ctx);
++ }
++
++ return TargetLoweringObjectFileELF::
++ getTTypeGlobalReference(GV, Mang, MMI, Encoding, Streamer);
++}
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
+@@ -12,7 +12,9 @@
+ //===----------------------------------------------------------------------===//
+
+ #include "SparcMCAsmInfo.h"
++#include "SparcMCExpr.h"
+ #include "llvm/ADT/Triple.h"
++#include "llvm/MC/MCStreamer.h"
+
+ using namespace llvm;
+
+@@ -44,4 +46,15 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT)
+ PrivateGlobalPrefix = ".L";
+ }
+
++const MCExpr*
++SparcELFMCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym,
++ unsigned Encoding,
++ MCStreamer &Streamer) const {
++ if (Encoding & dwarf::DW_EH_PE_pcrel) {
++ MCContext &Ctx = Streamer.getContext();
++ return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32,
++ MCSymbolRefExpr::Create(Sym, Ctx), Ctx);
++ }
+
++ return MCAsmInfo::getExprForPersonalitySymbol(Sym, Encoding, Streamer);
++}
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+@@ -41,6 +41,7 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
+ case VK_Sparc_L44: OS << "%l44("; break;
+ case VK_Sparc_HH: OS << "%hh("; break;
+ case VK_Sparc_HM: OS << "%hm("; break;
++ case VK_Sparc_R_DISP32: OS << "%r_disp32("; break;
+ case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break;
+ case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break;
+ case VK_Sparc_TLS_GD_ADD: OS << "%tgd_add("; break;
+@@ -77,6 +78,7 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
+ .Case("l44", VK_Sparc_L44)
+ .Case("hh", VK_Sparc_HH)
+ .Case("hm", VK_Sparc_HM)
++ .Case("r_disp32", VK_Sparc_R_DISP32)
+ .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
+ .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
+ .Case("tgd_add", VK_Sparc_TLS_GD_ADD)
+@@ -101,6 +103,8 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
+ bool
+ SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
+ const MCAsmLayout *Layout) const {
++ if (!Layout)
++ return false;
+ return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
+ }
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
+@@ -17,13 +17,16 @@
+ #include "llvm/MC/MCAsmInfoELF.h"
+
+ namespace llvm {
+- class StringRef;
++class StringRef;
+
+- class SparcELFMCAsmInfo : public MCAsmInfoELF {
+- virtual void anchor();
+- public:
+- explicit SparcELFMCAsmInfo(StringRef TT);
+- };
++class SparcELFMCAsmInfo : public MCAsmInfoELF {
++ virtual void anchor();
++public:
++ explicit SparcELFMCAsmInfo(StringRef TT);
++ virtual const MCExpr* getExprForPersonalitySymbol(const MCSymbol *Sym,
++ unsigned Encoding,
++ MCStreamer &Streamer) const;
++};
+
+ } // namespace llvm
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+@@ -31,6 +31,7 @@ class SparcMCExpr : public MCTargetExpr {
+ VK_Sparc_L44,
+ VK_Sparc_HH,
+ VK_Sparc_HM,
++ VK_Sparc_R_DISP32,
+ VK_Sparc_TLS_GD_HI22,
+ VK_Sparc_TLS_GD_LO10,
+ VK_Sparc_TLS_GD_ADD,
+Index: lib/Target/Sparc/CMakeLists.txt
+===================================================================
+--- lib/Target/Sparc/CMakeLists.txt
++++ lib/Target/Sparc/CMakeLists.txt
+@@ -27,6 +27,7 @@ add_llvm_target(SparcCodeGen
+ SparcJITInfo.cpp
+ SparcCodeEmitter.cpp
+ SparcMCInstLower.cpp
++ SparcTargetObjectFile.cpp
+ )
+
+ add_dependencies(LLVMSparcCodeGen SparcCommonTableGen intrinsics_gen)
+Index: test/CodeGen/SPARC/exception.ll
+===================================================================
+--- test/CodeGen/SPARC/exception.ll
++++ test/CodeGen/SPARC/exception.ll
+@@ -1,7 +1,9 @@
+ ; RUN: llc < %s -march=sparc -relocation-model=static | FileCheck -check-prefix=V8ABS %s
+ ; RUN: llc < %s -march=sparc -relocation-model=pic | FileCheck -check-prefix=V8PIC %s
++; RUN: llc < %s -march=sparc -relocation-model=pic -disable-cfi | FileCheck -check-prefix=V8PIC_NOCFI %s
+ ; RUN: llc < %s -march=sparcv9 -relocation-model=static | FileCheck -check-prefix=V9ABS %s
+ ; RUN: llc < %s -march=sparcv9 -relocation-model=pic | FileCheck -check-prefix=V9PIC %s
++; RUN: llc < %s -march=sparcv9 -relocation-model=pic -disable-cfi | FileCheck -check-prefix=V9PIC_NOCFI %s
+
+
+ %struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo }
+@@ -40,11 +42,23 @@
+ ; V8PIC: .cfi_register 15, 31
+ ; V8PIC: .section .gcc_except_table
+ ; V8PIC-NOT: .section
+-; V8PIC: .word .L_ZTIi.DW.stub-
++; V8PIC: .word %r_disp32(.L_ZTIi.DW.stub)
+ ; V8PIC: .data
+ ; V8PIC: .L_ZTIi.DW.stub:
+ ; V8PIC-NEXT: .word _ZTIi
+
++; V8PIC_NOCFI-LABEL: main:
++; V8PIC_NOCFI: .section .gcc_except_table
++; V8PIC_NOCFI-NOT: .section
++; V8PIC_NOCFI: .word %r_disp32(.L_ZTIi.DW.stub)
++; V8PIC_NOCFI: .data
++; V8PIC_NOCFI: .L_ZTIi.DW.stub:
++; V8PIC_NOCFI-NEXT: .word _ZTIi
++; V8PIC_NOCFI: .section .eh_frame
++; V8PIC_NOCFI-NOT: .section
++; V8PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0)
++
++
+ ; V9ABS-LABEL: main:
+ ; V9ABS: .cfi_startproc
+ ; V9ABS: .cfi_personality 0, __gxx_personality_v0
+@@ -65,11 +79,22 @@
+ ; V9PIC: .cfi_register 15, 31
+ ; V9PIC: .section .gcc_except_table
+ ; V9PIC-NOT: .section
+-; V9PIC: .word .L_ZTIi.DW.stub-
++; V9PIC: .word %r_disp32(.L_ZTIi.DW.stub)
+ ; V9PIC: .data
+ ; V9PIC: .L_ZTIi.DW.stub:
+ ; V9PIC-NEXT: .xword _ZTIi
+
++; V9PIC_NOCFI-LABEL: main:
++; V9PIC_NOCFI: .section .gcc_except_table
++; V9PIC_NOCFI-NOT: .section
++; V9PIC_NOCFI: .word %r_disp32(.L_ZTIi.DW.stub)
++; V9PIC_NOCFI: .data
++; V9PIC_NOCFI: .L_ZTIi.DW.stub:
++; V9PIC_NOCFI-NEXT: .xword _ZTIi
++; V9PIC_NOCFI: .section .eh_frame
++; V9PIC_NOCFI-NOT: .section
++; V9PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0)
++
+ define i32 @main(i32 %argc, i8** nocapture readnone %argv) unnamed_addr #0 {
+ entry:
+ %0 = icmp eq i32 %argc, 2
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200376-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200376-sparc.diff
new file mode 100644
index 0000000..0053365
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200376-sparc.diff
@@ -0,0 +1,76 @@
+Pull in r200376 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Use %r_disp32 for pc_rel entries in FDE as well.
+
+ This makes MCAsmInfo::getExprForFDESymbol() a virtual function and overrides it in SparcMCAsmInfo.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
+@@ -26,6 +26,10 @@ class SparcELFMCAsmInfo : public MCAsmInfoELF {
+ virtual const MCExpr* getExprForPersonalitySymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
++ virtual const MCExpr* getExprForFDESymbol(const MCSymbol *Sym,
++ unsigned Encoding,
++ MCStreamer &Streamer) const;
++
+ };
+
+ } // namespace llvm
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
+@@ -58,3 +58,15 @@ SparcELFMCAsmInfo::getExprForPersonalitySymbol(con
+
+ return MCAsmInfo::getExprForPersonalitySymbol(Sym, Encoding, Streamer);
+ }
++
++const MCExpr*
++SparcELFMCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
++ unsigned Encoding,
++ MCStreamer &Streamer) const {
++ if (Encoding & dwarf::DW_EH_PE_pcrel) {
++ MCContext &Ctx = Streamer.getContext();
++ return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32,
++ MCSymbolRefExpr::Create(Sym, Ctx), Ctx);
++ }
++ return MCAsmInfo::getExprForFDESymbol(Sym, Encoding, Streamer);
++}
+Index: test/CodeGen/SPARC/exception.ll
+===================================================================
+--- test/CodeGen/SPARC/exception.ll
++++ test/CodeGen/SPARC/exception.ll
+@@ -57,6 +57,7 @@
+ ; V8PIC_NOCFI: .section .eh_frame
+ ; V8PIC_NOCFI-NOT: .section
+ ; V8PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0)
++; V8PIC_NOCFI: .word %r_disp32(.Ltmp{{.+}}) ! FDE initial location
+
+
+ ; V9ABS-LABEL: main:
+@@ -94,6 +95,7 @@
+ ; V9PIC_NOCFI: .section .eh_frame
+ ; V9PIC_NOCFI-NOT: .section
+ ; V9PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0)
++; V9PIC_NOCFI: .word %r_disp32(.Ltmp{{.+}}) ! FDE initial location
+
+ define i32 @main(i32 %argc, i8** nocapture readnone %argv) unnamed_addr #0 {
+ entry:
+Index: include/llvm/MC/MCAsmInfo.h
+===================================================================
+--- include/llvm/MC/MCAsmInfo.h
++++ include/llvm/MC/MCAsmInfo.h
+@@ -371,7 +371,7 @@ namespace llvm {
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+- const MCExpr *
++ virtual const MCExpr *
+ getExprForFDESymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200509-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200509-sparc.diff
new file mode 100644
index 0000000..9ada6aa
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200509-sparc.diff
@@ -0,0 +1,73 @@
+Pull in r200509 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Save and restore float registers that may be used for parameter passing.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcJITInfo.cpp
+===================================================================
+--- lib/Target/Sparc/SparcJITInfo.cpp
++++ lib/Target/Sparc/SparcJITInfo.cpp
+@@ -28,6 +28,13 @@ extern "C" void SparcCompilationCallback();
+
+ extern "C" {
+ #if defined (__sparc__)
++
++#if defined(__arch64__)
++#define FRAME_PTR(X) #X "+2047"
++#else
++#define FRAME_PTR(X) #X
++#endif
++
+ asm(
+ ".text\n"
+ "\t.align 4\n"
+@@ -34,11 +41,46 @@ extern "C" {
+ "\t.global SparcCompilationCallback\n"
+ "\t.type SparcCompilationCallback, #function\n"
+ "SparcCompilationCallback:\n"
+- // Save current register window.
+- "\tsave %sp, -192, %sp\n"
++ // Save current register window and create stack.
++ // 128 (save area) + 6*8 (for arguments) + 16*8 (for float regfile) = 304
++ "\tsave %sp, -304, %sp\n"
++ // save float regfile to the stack.
++ "\tstd %f0, [" FRAME_PTR(%fp) "-0]\n"
++ "\tstd %f2, [" FRAME_PTR(%fp) "-8]\n"
++ "\tstd %f4, [" FRAME_PTR(%fp) "-16]\n"
++ "\tstd %f6, [" FRAME_PTR(%fp) "-24]\n"
++ "\tstd %f8, [" FRAME_PTR(%fp) "-32]\n"
++ "\tstd %f10, [" FRAME_PTR(%fp) "-40]\n"
++ "\tstd %f12, [" FRAME_PTR(%fp) "-48]\n"
++ "\tstd %f14, [" FRAME_PTR(%fp) "-56]\n"
++ "\tstd %f16, [" FRAME_PTR(%fp) "-64]\n"
++ "\tstd %f18, [" FRAME_PTR(%fp) "-72]\n"
++ "\tstd %f20, [" FRAME_PTR(%fp) "-80]\n"
++ "\tstd %f22, [" FRAME_PTR(%fp) "-88]\n"
++ "\tstd %f24, [" FRAME_PTR(%fp) "-96]\n"
++ "\tstd %f26, [" FRAME_PTR(%fp) "-104]\n"
++ "\tstd %f28, [" FRAME_PTR(%fp) "-112]\n"
++ "\tstd %f30, [" FRAME_PTR(%fp) "-120]\n"
+ // stubaddr is in %g1.
+ "\tcall SparcCompilationCallbackC\n"
+ "\t mov %g1, %o0\n"
++ // restore float regfile from the stack.
++ "\tldd [" FRAME_PTR(%fp) "-0], %f0\n"
++ "\tldd [" FRAME_PTR(%fp) "-8], %f2\n"
++ "\tldd [" FRAME_PTR(%fp) "-16], %f4\n"
++ "\tldd [" FRAME_PTR(%fp) "-24], %f6\n"
++ "\tldd [" FRAME_PTR(%fp) "-32], %f8\n"
++ "\tldd [" FRAME_PTR(%fp) "-40], %f10\n"
++ "\tldd [" FRAME_PTR(%fp) "-48], %f12\n"
++ "\tldd [" FRAME_PTR(%fp) "-56], %f14\n"
++ "\tldd [" FRAME_PTR(%fp) "-64], %f16\n"
++ "\tldd [" FRAME_PTR(%fp) "-72], %f18\n"
++ "\tldd [" FRAME_PTR(%fp) "-80], %f20\n"
++ "\tldd [" FRAME_PTR(%fp) "-88], %f22\n"
++ "\tldd [" FRAME_PTR(%fp) "-96], %f24\n"
++ "\tldd [" FRAME_PTR(%fp) "-104], %f26\n"
++ "\tldd [" FRAME_PTR(%fp) "-112], %f28\n"
++ "\tldd [" FRAME_PTR(%fp) "-120], %f30\n"
+ // restore original register window and
+ // copy %o0 to %g1
+ "\trestore %o0, 0, %g1\n"
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200617-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200617-sparc.diff
new file mode 100644
index 0000000..831cd98
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200617-sparc.diff
@@ -0,0 +1,97 @@
+Pull in r200617 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Set %o7 as the return address register instead of %i7 in MCRegisterInfo. Also, add CFI instructions to initialize the frame correctly.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+@@ -33,6 +33,25 @@
+
+ using namespace llvm;
+
++
++static MCAsmInfo *createSparcMCAsmInfo(const MCRegisterInfo &MRI,
++ StringRef TT) {
++ MCAsmInfo *MAI = new SparcELFMCAsmInfo(TT);
++ unsigned Reg = MRI.getDwarfRegNum(SP::O6, true);
++ MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0);
++ MAI->addInitialFrameState(Inst);
++ return MAI;
++}
++
++static MCAsmInfo *createSparcV9MCAsmInfo(const MCRegisterInfo &MRI,
++ StringRef TT) {
++ MCAsmInfo *MAI = new SparcELFMCAsmInfo(TT);
++ unsigned Reg = MRI.getDwarfRegNum(SP::O6, true);
++ MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 2047);
++ MAI->addInitialFrameState(Inst);
++ return MAI;
++}
++
+ static MCInstrInfo *createSparcMCInstrInfo() {
+ MCInstrInfo *X = new MCInstrInfo();
+ InitSparcMCInstrInfo(X);
+@@ -41,7 +60,7 @@ static MCInstrInfo *createSparcMCInstrInfo() {
+
+ static MCRegisterInfo *createSparcMCRegisterInfo(StringRef TT) {
+ MCRegisterInfo *X = new MCRegisterInfo();
+- InitSparcMCRegisterInfo(X, SP::I7);
++ InitSparcMCRegisterInfo(X, SP::O7);
+ return X;
+ }
+
+@@ -132,8 +151,8 @@ static MCInstPrinter *createSparcMCInstPrinter(con
+
+ extern "C" void LLVMInitializeSparcTargetMC() {
+ // Register the MC asm info.
+- RegisterMCAsmInfo<SparcELFMCAsmInfo> X(TheSparcTarget);
+- RegisterMCAsmInfo<SparcELFMCAsmInfo> Y(TheSparcV9Target);
++ RegisterMCAsmInfoFn X(TheSparcTarget, createSparcMCAsmInfo);
++ RegisterMCAsmInfoFn Y(TheSparcV9Target, createSparcV9MCAsmInfo);
+
+ // Register the MC codegen info.
+ TargetRegistry::RegisterMCCodeGenInfo(TheSparcTarget,
+Index: lib/Target/Sparc/SparcRegisterInfo.cpp
+===================================================================
+--- lib/Target/Sparc/SparcRegisterInfo.cpp
++++ lib/Target/Sparc/SparcRegisterInfo.cpp
+@@ -35,7 +35,7 @@ ReserveAppRegisters("sparc-reserve-app-registers",
+ cl::desc("Reserve application registers (%g2-%g4)"));
+
+ SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st)
+- : SparcGenRegisterInfo(SP::I7), Subtarget(st) {
++ : SparcGenRegisterInfo(SP::O7), Subtarget(st) {
+ }
+
+ const uint16_t* SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
+Index: test/CodeGen/SPARC/exception.ll
+===================================================================
+--- test/CodeGen/SPARC/exception.ll
++++ test/CodeGen/SPARC/exception.ll
+@@ -56,7 +56,11 @@
+ ; V8PIC_NOCFI-NEXT: .word _ZTIi
+ ; V8PIC_NOCFI: .section .eh_frame
+ ; V8PIC_NOCFI-NOT: .section
++; V8PIC_NOCFI: .byte 15 ! CIE Return Address Column
+ ; V8PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0)
++; V8PIC_NOCFI: .byte 12 ! DW_CFA_def_cfa
++; V8PIC_NOCFI: .byte 14 ! Reg 14
++; V8PIC_NOCFI-NEXT: .byte 0 ! Offset 0
+ ; V8PIC_NOCFI: .word %r_disp32(.Ltmp{{.+}}) ! FDE initial location
+
+
+@@ -94,7 +98,11 @@
+ ; V9PIC_NOCFI-NEXT: .xword _ZTIi
+ ; V9PIC_NOCFI: .section .eh_frame
+ ; V9PIC_NOCFI-NOT: .section
++; V9PIC_NOCFI: .byte 15 ! CIE Return Address Column
+ ; V9PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0)
++; V9PIC_NOCFI: .byte 12 ! DW_CFA_def_cfa
++; V9PIC_NOCFI-NEXT: .byte 14 ! Reg 14
++; V9PIC_NOCFI: .ascii "\377\017" ! Offset 2047
+ ; V9PIC_NOCFI: .word %r_disp32(.Ltmp{{.+}}) ! FDE initial location
+
+ define i32 @main(i32 %argc, i8** nocapture readnone %argv) unnamed_addr #0 {
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200960-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200960-sparc.diff
new file mode 100644
index 0000000..c430f88
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200960-sparc.diff
@@ -0,0 +1,512 @@
+Pull in r200960 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Use SparcMCExpr::VariantKind itself as MachineOperand's target flags.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -13,11 +13,11 @@
+ //===----------------------------------------------------------------------===//
+
+ #include "SparcISelLowering.h"
++#include "MCTargetDesc/SparcMCExpr.h"
+ #include "SparcMachineFunctionInfo.h"
+ #include "SparcRegisterInfo.h"
+ #include "SparcTargetMachine.h"
+ #include "SparcTargetObjectFile.h"
+-#include "MCTargetDesc/SparcBaseInfo.h"
+ #include "llvm/CodeGen/CallingConvLower.h"
+ #include "llvm/CodeGen/MachineFrameInfo.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+@@ -1796,7 +1796,8 @@ SDValue SparcTargetLowering::makeAddress(SDValue O
+ // Handle PIC mode first.
+ if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ // This is the pic32 code model, the GOT is known to be smaller than 4GB.
+- SDValue HiLo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
++ SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI,
++ SparcMCExpr::VK_Sparc_LO, DAG);
+ SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
+ SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo);
+ // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
+@@ -1813,20 +1814,24 @@ SDValue SparcTargetLowering::makeAddress(SDValue O
+ llvm_unreachable("Unsupported absolute code model");
+ case CodeModel::Small:
+ // abs32.
+- return makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
++ return makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI,
++ SparcMCExpr::VK_Sparc_LO, DAG);
+ case CodeModel::Medium: {
+ // abs44.
+- SDValue H44 = makeHiLoPair(Op, SPII::MO_H44, SPII::MO_M44, DAG);
++ SDValue H44 = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_H44,
++ SparcMCExpr::VK_Sparc_M44, DAG);
+ H44 = DAG.getNode(ISD::SHL, DL, VT, H44, DAG.getConstant(12, MVT::i32));
+- SDValue L44 = withTargetFlags(Op, SPII::MO_L44, DAG);
++ SDValue L44 = withTargetFlags(Op, SparcMCExpr::VK_Sparc_L44, DAG);
+ L44 = DAG.getNode(SPISD::Lo, DL, VT, L44);
+ return DAG.getNode(ISD::ADD, DL, VT, H44, L44);
+ }
+ case CodeModel::Large: {
+ // abs64.
+- SDValue Hi = makeHiLoPair(Op, SPII::MO_HH, SPII::MO_HM, DAG);
++ SDValue Hi = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HH,
++ SparcMCExpr::VK_Sparc_HM, DAG);
+ Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, DAG.getConstant(32, MVT::i32));
+- SDValue Lo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG);
++ SDValue Lo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI,
++ SparcMCExpr::VK_Sparc_LO, DAG);
+ return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
+ }
+ }
+@@ -1858,14 +1863,18 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress
+ TLSModel::Model model = getTargetMachine().getTLSModel(GV);
+
+ if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) {
+- unsigned HiTF = ((model == TLSModel::GeneralDynamic)? SPII::MO_TLS_GD_HI22
+- : SPII::MO_TLS_LDM_HI22);
+- unsigned LoTF = ((model == TLSModel::GeneralDynamic)? SPII::MO_TLS_GD_LO10
+- : SPII::MO_TLS_LDM_LO10);
+- unsigned addTF = ((model == TLSModel::GeneralDynamic)? SPII::MO_TLS_GD_ADD
+- : SPII::MO_TLS_LDM_ADD);
+- unsigned callTF = ((model == TLSModel::GeneralDynamic)? SPII::MO_TLS_GD_CALL
+- : SPII::MO_TLS_LDM_CALL);
++ unsigned HiTF = ((model == TLSModel::GeneralDynamic)
++ ? SparcMCExpr::VK_Sparc_TLS_GD_HI22
++ : SparcMCExpr::VK_Sparc_TLS_LDM_HI22);
++ unsigned LoTF = ((model == TLSModel::GeneralDynamic)
++ ? SparcMCExpr::VK_Sparc_TLS_GD_LO10
++ : SparcMCExpr::VK_Sparc_TLS_LDM_LO10);
++ unsigned addTF = ((model == TLSModel::GeneralDynamic)
++ ? SparcMCExpr::VK_Sparc_TLS_GD_ADD
++ : SparcMCExpr::VK_Sparc_TLS_LDM_ADD);
++ unsigned callTF = ((model == TLSModel::GeneralDynamic)
++ ? SparcMCExpr::VK_Sparc_TLS_GD_CALL
++ : SparcMCExpr::VK_Sparc_TLS_LDM_CALL);
+
+ SDValue HiLo = makeHiLoPair(Op, HiTF, LoTF, DAG);
+ SDValue Base = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, PtrVT);
+@@ -1903,17 +1912,17 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress
+ return Ret;
+
+ SDValue Hi = DAG.getNode(SPISD::Hi, DL, PtrVT,
+- withTargetFlags(Op, SPII::MO_TLS_LDO_HIX22, DAG));
++ withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_HIX22, DAG));
+ SDValue Lo = DAG.getNode(SPISD::Lo, DL, PtrVT,
+- withTargetFlags(Op, SPII::MO_TLS_LDO_LOX10, DAG));
++ withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_LOX10, DAG));
+ HiLo = DAG.getNode(ISD::XOR, DL, PtrVT, Hi, Lo);
+ return DAG.getNode(SPISD::TLS_ADD, DL, PtrVT, Ret, HiLo,
+- withTargetFlags(Op, SPII::MO_TLS_LDO_ADD, DAG));
++ withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LDO_ADD, DAG));
+ }
+
+ if (model == TLSModel::InitialExec) {
+- unsigned ldTF = ((PtrVT == MVT::i64)? SPII::MO_TLS_IE_LDX
+- : SPII::MO_TLS_IE_LD);
++ unsigned ldTF = ((PtrVT == MVT::i64)? SparcMCExpr::VK_Sparc_TLS_IE_LDX
++ : SparcMCExpr::VK_Sparc_TLS_IE_LD);
+
+ SDValue Base = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, PtrVT);
+
+@@ -1923,7 +1932,8 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress
+ MFI->setHasCalls(true);
+
+ SDValue TGA = makeHiLoPair(Op,
+- SPII::MO_TLS_IE_HI22, SPII::MO_TLS_IE_LO10, DAG);
++ SparcMCExpr::VK_Sparc_TLS_IE_HI22,
++ SparcMCExpr::VK_Sparc_TLS_IE_LO10, DAG);
+ SDValue Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Base, TGA);
+ SDValue Offset = DAG.getNode(SPISD::TLS_LD,
+ DL, PtrVT, Ptr,
+@@ -1930,14 +1940,15 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress
+ withTargetFlags(Op, ldTF, DAG));
+ return DAG.getNode(SPISD::TLS_ADD, DL, PtrVT,
+ DAG.getRegister(SP::G7, PtrVT), Offset,
+- withTargetFlags(Op, SPII::MO_TLS_IE_ADD, DAG));
++ withTargetFlags(Op,
++ SparcMCExpr::VK_Sparc_TLS_IE_ADD, DAG));
+ }
+
+ assert(model == TLSModel::LocalExec);
+ SDValue Hi = DAG.getNode(SPISD::Hi, DL, PtrVT,
+- withTargetFlags(Op, SPII::MO_TLS_LE_HIX22, DAG));
++ withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LE_HIX22, DAG));
+ SDValue Lo = DAG.getNode(SPISD::Lo, DL, PtrVT,
+- withTargetFlags(Op, SPII::MO_TLS_LE_LOX10, DAG));
++ withTargetFlags(Op, SparcMCExpr::VK_Sparc_TLS_LE_LOX10, DAG));
+ SDValue Offset = DAG.getNode(ISD::XOR, DL, PtrVT, Hi, Lo);
+
+ return DAG.getNode(ISD::ADD, DL, PtrVT,
+Index: lib/Target/Sparc/SparcCodeEmitter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcCodeEmitter.cpp
++++ lib/Target/Sparc/SparcCodeEmitter.cpp
+@@ -14,7 +14,7 @@
+
+ #define DEBUG_TYPE "jit"
+ #include "Sparc.h"
+-#include "MCTargetDesc/SparcBaseInfo.h"
++#include "MCTargetDesc/SparcMCExpr.h"
+ #include "SparcRelocations.h"
+ #include "SparcTargetMachine.h"
+ #include "llvm/ADT/Statistic.h"
+@@ -204,14 +204,14 @@ unsigned SparcCodeEmitter::getRelocation(const Mac
+ unsigned TF = MO.getTargetFlags();
+ switch (TF) {
+ default:
+- case SPII::MO_NO_FLAG: break;
+- case SPII::MO_LO: return SP::reloc_sparc_lo;
+- case SPII::MO_HI: return SP::reloc_sparc_hi;
+- case SPII::MO_H44: return SP::reloc_sparc_h44;
+- case SPII::MO_M44: return SP::reloc_sparc_m44;
+- case SPII::MO_L44: return SP::reloc_sparc_l44;
+- case SPII::MO_HH: return SP::reloc_sparc_hh;
+- case SPII::MO_HM: return SP::reloc_sparc_hm;
++ case SparcMCExpr::VK_Sparc_None: break;
++ case SparcMCExpr::VK_Sparc_LO: return SP::reloc_sparc_lo;
++ case SparcMCExpr::VK_Sparc_HI: return SP::reloc_sparc_hi;
++ case SparcMCExpr::VK_Sparc_H44: return SP::reloc_sparc_h44;
++ case SparcMCExpr::VK_Sparc_M44: return SP::reloc_sparc_m44;
++ case SparcMCExpr::VK_Sparc_L44: return SP::reloc_sparc_l44;
++ case SparcMCExpr::VK_Sparc_HH: return SP::reloc_sparc_hh;
++ case SparcMCExpr::VK_Sparc_HM: return SP::reloc_sparc_hm;
+ }
+
+ unsigned Opc = MI.getOpcode();
+Index: lib/Target/Sparc/SparcMCInstLower.cpp
+===================================================================
+--- lib/Target/Sparc/SparcMCInstLower.cpp
++++ lib/Target/Sparc/SparcMCInstLower.cpp
+@@ -13,7 +13,6 @@
+ //===----------------------------------------------------------------------===//
+
+ #include "Sparc.h"
+-#include "MCTargetDesc/SparcBaseInfo.h"
+ #include "MCTargetDesc/SparcMCExpr.h"
+ #include "llvm/CodeGen/AsmPrinter.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+@@ -33,41 +32,10 @@ static MCOperand LowerSymbolOperand(const MachineI
+ const MachineOperand &MO,
+ AsmPrinter &AP) {
+
+- SparcMCExpr::VariantKind Kind;
++ SparcMCExpr::VariantKind Kind =
++ (SparcMCExpr::VariantKind)MO.getTargetFlags();
+ const MCSymbol *Symbol = 0;
+
+- unsigned TF = MO.getTargetFlags();
+-
+- switch(TF) {
+- default: llvm_unreachable("Unknown target flags on operand");
+- case SPII::MO_NO_FLAG: Kind = SparcMCExpr::VK_Sparc_None; break;
+- case SPII::MO_LO: Kind = SparcMCExpr::VK_Sparc_LO; break;
+- case SPII::MO_HI: Kind = SparcMCExpr::VK_Sparc_HI; break;
+- case SPII::MO_H44: Kind = SparcMCExpr::VK_Sparc_H44; break;
+- case SPII::MO_M44: Kind = SparcMCExpr::VK_Sparc_M44; break;
+- case SPII::MO_L44: Kind = SparcMCExpr::VK_Sparc_L44; break;
+- case SPII::MO_HH: Kind = SparcMCExpr::VK_Sparc_HH; break;
+- case SPII::MO_HM: Kind = SparcMCExpr::VK_Sparc_HM; break;
+- case SPII::MO_TLS_GD_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_GD_HI22; break;
+- case SPII::MO_TLS_GD_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_GD_LO10; break;
+- case SPII::MO_TLS_GD_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_GD_ADD; break;
+- case SPII::MO_TLS_GD_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_GD_CALL; break;
+- case SPII::MO_TLS_LDM_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_HI22; break;
+- case SPII::MO_TLS_LDM_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_LO10; break;
+- case SPII::MO_TLS_LDM_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_ADD; break;
+- case SPII::MO_TLS_LDM_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_CALL; break;
+- case SPII::MO_TLS_LDO_HIX22:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_HIX22; break;
+- case SPII::MO_TLS_LDO_LOX10:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_LOX10; break;
+- case SPII::MO_TLS_LDO_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDO_ADD; break;
+- case SPII::MO_TLS_IE_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_IE_HI22; break;
+- case SPII::MO_TLS_IE_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LO10; break;
+- case SPII::MO_TLS_IE_LD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LD; break;
+- case SPII::MO_TLS_IE_LDX: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LDX; break;
+- case SPII::MO_TLS_IE_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_ADD; break;
+- case SPII::MO_TLS_LE_HIX22: Kind = SparcMCExpr::VK_Sparc_TLS_LE_HIX22; break;
+- case SPII::MO_TLS_LE_LOX10: Kind = SparcMCExpr::VK_Sparc_TLS_LE_LOX10; break;
+- }
+-
+ switch(MO.getType()) {
+ default: llvm_unreachable("Unknown type in LowerSymbolOperand");
+ case MachineOperand::MO_MachineBasicBlock:
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -18,7 +18,6 @@
+ #include "SparcTargetMachine.h"
+ #include "SparcTargetStreamer.h"
+ #include "InstPrinter/SparcInstPrinter.h"
+-#include "MCTargetDesc/SparcBaseInfo.h"
+ #include "MCTargetDesc/SparcMCExpr.h"
+ #include "llvm/ADT/SmallString.h"
+ #include "llvm/CodeGen/AsmPrinter.h"
+@@ -287,83 +286,60 @@ void SparcAsmPrinter::EmitFunctionBodyStart() {
+ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
+ const MachineOperand &MO = MI->getOperand (opNum);
+- unsigned TF = MO.getTargetFlags();
++ SparcMCExpr::VariantKind TF = (SparcMCExpr::VariantKind) MO.getTargetFlags();
++
+ #ifndef NDEBUG
+ // Verify the target flags.
+ if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) {
+ if (MI->getOpcode() == SP::CALL)
+- assert(TF == SPII::MO_NO_FLAG &&
++ assert(TF == SparcMCExpr::VK_Sparc_None &&
+ "Cannot handle target flags on call address");
+ else if (MI->getOpcode() == SP::SETHIi || MI->getOpcode() == SP::SETHIXi)
+- assert((TF == SPII::MO_HI || TF == SPII::MO_H44 || TF == SPII::MO_HH
+- || TF == SPII::MO_TLS_GD_HI22
+- || TF == SPII::MO_TLS_LDM_HI22
+- || TF == SPII::MO_TLS_LDO_HIX22
+- || TF == SPII::MO_TLS_IE_HI22
+- || TF == SPII::MO_TLS_LE_HIX22) &&
++ assert((TF == SparcMCExpr::VK_Sparc_HI
++ || TF == SparcMCExpr::VK_Sparc_H44
++ || TF == SparcMCExpr::VK_Sparc_HH
++ || TF == SparcMCExpr::VK_Sparc_TLS_GD_HI22
++ || TF == SparcMCExpr::VK_Sparc_TLS_LDM_HI22
++ || TF == SparcMCExpr::VK_Sparc_TLS_LDO_HIX22
++ || TF == SparcMCExpr::VK_Sparc_TLS_IE_HI22
++ || TF == SparcMCExpr::VK_Sparc_TLS_LE_HIX22) &&
+ "Invalid target flags for address operand on sethi");
+ else if (MI->getOpcode() == SP::TLS_CALL)
+- assert((TF == SPII::MO_NO_FLAG
+- || TF == SPII::MO_TLS_GD_CALL
+- || TF == SPII::MO_TLS_LDM_CALL) &&
++ assert((TF == SparcMCExpr::VK_Sparc_None
++ || TF == SparcMCExpr::VK_Sparc_TLS_GD_CALL
++ || TF == SparcMCExpr::VK_Sparc_TLS_LDM_CALL) &&
+ "Cannot handle target flags on tls call address");
+ else if (MI->getOpcode() == SP::TLS_ADDrr)
+- assert((TF == SPII::MO_TLS_GD_ADD || TF == SPII::MO_TLS_LDM_ADD
+- || TF == SPII::MO_TLS_LDO_ADD || TF == SPII::MO_TLS_IE_ADD) &&
++ assert((TF == SparcMCExpr::VK_Sparc_TLS_GD_ADD
++ || TF == SparcMCExpr::VK_Sparc_TLS_LDM_ADD
++ || TF == SparcMCExpr::VK_Sparc_TLS_LDO_ADD
++ || TF == SparcMCExpr::VK_Sparc_TLS_IE_ADD) &&
+ "Cannot handle target flags on add for TLS");
+ else if (MI->getOpcode() == SP::TLS_LDrr)
+- assert(TF == SPII::MO_TLS_IE_LD &&
++ assert(TF == SparcMCExpr::VK_Sparc_TLS_IE_LD &&
+ "Cannot handle target flags on ld for TLS");
+ else if (MI->getOpcode() == SP::TLS_LDXrr)
+- assert(TF == SPII::MO_TLS_IE_LDX &&
++ assert(TF == SparcMCExpr::VK_Sparc_TLS_IE_LDX &&
+ "Cannot handle target flags on ldx for TLS");
+ else if (MI->getOpcode() == SP::XORri || MI->getOpcode() == SP::XORXri)
+- assert((TF == SPII::MO_TLS_LDO_LOX10 || TF == SPII::MO_TLS_LE_LOX10) &&
++ assert((TF == SparcMCExpr::VK_Sparc_TLS_LDO_LOX10
++ || TF == SparcMCExpr::VK_Sparc_TLS_LE_LOX10) &&
+ "Cannot handle target flags on xor for TLS");
+ else
+- assert((TF == SPII::MO_LO || TF == SPII::MO_M44 || TF == SPII::MO_L44
+- || TF == SPII::MO_HM
+- || TF == SPII::MO_TLS_GD_LO10
+- || TF == SPII::MO_TLS_LDM_LO10
+- || TF == SPII::MO_TLS_IE_LO10 ) &&
++ assert((TF == SparcMCExpr::VK_Sparc_LO
++ || TF == SparcMCExpr::VK_Sparc_M44
++ || TF == SparcMCExpr::VK_Sparc_L44
++ || TF == SparcMCExpr::VK_Sparc_HM
++ || TF == SparcMCExpr::VK_Sparc_TLS_GD_LO10
++ || TF == SparcMCExpr::VK_Sparc_TLS_LDM_LO10
++ || TF == SparcMCExpr::VK_Sparc_TLS_IE_LO10 ) &&
+ "Invalid target flags for small address operand");
+ }
+ #endif
+
+- bool CloseParen = true;
+- switch (TF) {
+- default:
+- llvm_unreachable("Unknown target flags on operand");
+- case SPII::MO_NO_FLAG:
+- CloseParen = false;
+- break;
+- case SPII::MO_LO: O << "%lo("; break;
+- case SPII::MO_HI: O << "%hi("; break;
+- case SPII::MO_H44: O << "%h44("; break;
+- case SPII::MO_M44: O << "%m44("; break;
+- case SPII::MO_L44: O << "%l44("; break;
+- case SPII::MO_HH: O << "%hh("; break;
+- case SPII::MO_HM: O << "%hm("; break;
+- case SPII::MO_TLS_GD_HI22: O << "%tgd_hi22("; break;
+- case SPII::MO_TLS_GD_LO10: O << "%tgd_lo10("; break;
+- case SPII::MO_TLS_GD_ADD: O << "%tgd_add("; break;
+- case SPII::MO_TLS_GD_CALL: O << "%tgd_call("; break;
+- case SPII::MO_TLS_LDM_HI22: O << "%tldm_hi22("; break;
+- case SPII::MO_TLS_LDM_LO10: O << "%tldm_lo10("; break;
+- case SPII::MO_TLS_LDM_ADD: O << "%tldm_add("; break;
+- case SPII::MO_TLS_LDM_CALL: O << "%tldm_call("; break;
+- case SPII::MO_TLS_LDO_HIX22: O << "%tldo_hix22("; break;
+- case SPII::MO_TLS_LDO_LOX10: O << "%tldo_lox10("; break;
+- case SPII::MO_TLS_LDO_ADD: O << "%tldo_add("; break;
+- case SPII::MO_TLS_IE_HI22: O << "%tie_hi22("; break;
+- case SPII::MO_TLS_IE_LO10: O << "%tie_lo10("; break;
+- case SPII::MO_TLS_IE_LD: O << "%tie_ld("; break;
+- case SPII::MO_TLS_IE_LDX: O << "%tie_ldx("; break;
+- case SPII::MO_TLS_IE_ADD: O << "%tie_add("; break;
+- case SPII::MO_TLS_LE_HIX22: O << "%tle_hix22("; break;
+- case SPII::MO_TLS_LE_LOX10: O << "%tle_lox10("; break;
+- }
+
++ bool CloseParen = SparcMCExpr::printVariantKind(O, TF);
++
+ switch (MO.getType()) {
+ case MachineOperand::MO_Register:
+ O << "%" << StringRef(getRegisterName(MO.getReg())).lower();
+Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+@@ -15,7 +15,6 @@
+ #include "SparcInstPrinter.h"
+
+ #include "Sparc.h"
+-#include "MCTargetDesc/SparcBaseInfo.h"
+ #include "llvm/MC/MCExpr.h"
+ #include "llvm/MC/MCInst.h"
+ #include "llvm/MC/MCSymbol.h"
+Index: lib/Target/Sparc/MCTargetDesc/SparcBaseInfo.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcBaseInfo.h
++++ lib/Target/Sparc/MCTargetDesc/SparcBaseInfo.h
+@@ -1,82 +0,0 @@
+-//===-- SparcBaseInfo.h - Top level definitions for Sparc ---- --*- C++ -*-===//
+-//
+-// The LLVM Compiler Infrastructure
+-//
+-// This file is distributed under the University of Illinois Open Source
+-// License. See LICENSE.TXT for details.
+-//
+-//===----------------------------------------------------------------------===//
+-//
+-// This file contains small standalone helper functions and enum definitions
+-// for the Sparc target useful for the compiler back-end and the MC libraries.
+-// As such, it deliberately does not include references to LLVM core code gen
+-// types, passes, etc..
+-//
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef SPARCBASEINFO_H
+-#define SPARCBASEINFO_H
+-
+-namespace llvm {
+-
+-/// SPII - This namespace holds target specific flags for instruction info.
+-namespace SPII {
+-
+-/// Target Operand Flags. Sparc specific TargetFlags for MachineOperands and
+-/// SDNodes.
+-enum TOF {
+- MO_NO_FLAG,
+-
+- // Extract the low 10 bits of an address.
+- // Assembler: %lo(addr)
+- MO_LO,
+-
+- // Extract bits 31-10 of an address. Only for sethi.
+- // Assembler: %hi(addr) or %lm(addr)
+- MO_HI,
+-
+- // Extract bits 43-22 of an adress. Only for sethi.
+- // Assembler: %h44(addr)
+- MO_H44,
+-
+- // Extract bits 21-12 of an address.
+- // Assembler: %m44(addr)
+- MO_M44,
+-
+- // Extract bits 11-0 of an address.
+- // Assembler: %l44(addr)
+- MO_L44,
+-
+- // Extract bits 63-42 of an address. Only for sethi.
+- // Assembler: %hh(addr)
+- MO_HH,
+-
+- // Extract bits 41-32 of an address.
+- // Assembler: %hm(addr)
+- MO_HM,
+-
+- // TargetFlags for Thread Local Storage.
+- MO_TLS_GD_HI22,
+- MO_TLS_GD_LO10,
+- MO_TLS_GD_ADD,
+- MO_TLS_GD_CALL,
+- MO_TLS_LDM_HI22,
+- MO_TLS_LDM_LO10,
+- MO_TLS_LDM_ADD,
+- MO_TLS_LDM_CALL,
+- MO_TLS_LDO_HIX22,
+- MO_TLS_LDO_LOX10,
+- MO_TLS_LDO_ADD,
+- MO_TLS_IE_HI22,
+- MO_TLS_IE_LO10,
+- MO_TLS_IE_LD,
+- MO_TLS_IE_LDX,
+- MO_TLS_IE_ADD,
+- MO_TLS_LE_HIX22,
+- MO_TLS_LE_LOX10
+-};
+-
+-} // end namespace SPII
+-} // end namespace llvm
+-
+-#endif
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+@@ -29,8 +29,21 @@ SparcMCExpr::Create(VariantKind Kind, const MCExpr
+ }
+
+
++
+ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
+ {
++
++ bool closeParen = printVariantKind(OS, Kind);
++
++ const MCExpr *Expr = getSubExpr();
++ Expr->print(OS);
++
++ if (closeParen)
++ OS << ')';
++}
++
++bool SparcMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind)
++{
+ bool closeParen = true;
+ switch (Kind) {
+ case VK_Sparc_None: closeParen = false; break;
+@@ -61,11 +74,7 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
+ case VK_Sparc_TLS_LE_HIX22: OS << "%tle_hix22("; break;
+ case VK_Sparc_TLS_LE_LOX10: OS << "%tle_lox10("; break;
+ }
+-
+- const MCExpr *Expr = getSubExpr();
+- Expr->print(OS);
+- if (closeParen)
+- OS << ')';
++ return closeParen;
+ }
+
+ SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+@@ -93,7 +93,7 @@ class SparcMCExpr : public MCTargetExpr {
+ static bool classof(const SparcMCExpr *) { return true; }
+
+ static VariantKind parseVariantKind(StringRef name);
+-
++ static bool printVariantKind(raw_ostream &OS, VariantKind Kind);
+ };
+
+ } // end namespace llvm.
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200961-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200961-sparc.diff
new file mode 100644
index 0000000..a08d173
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200961-sparc.diff
@@ -0,0 +1,443 @@
+Pull in r200961 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Emit correct relocations for PIC code when integrated assembler is used.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/CodeGen/SPARC/obj-relocs.ll
+===================================================================
+--- test/CodeGen/SPARC/obj-relocs.ll
++++ test/CodeGen/SPARC/obj-relocs.ll
+@@ -0,0 +1,33 @@
++; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=static | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-ABS
++; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=pic | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-PIC
++
++;CHECK-ABS: Relocations [
++;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_H44 AGlobalVar 0x0
++;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_M44 AGlobalVar 0x0
++;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_L44 AGlobalVar 0x0
++;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_WDISP30 bar 0x0
++;CHECK-ABS:]
++
++; CHECK-PIC: Relocations [
++; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
++; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
++; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
++; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
++; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
++; CHECK-PIC: ]
++
++
++@AGlobalVar = global i64 0, align 8
++
++; CHECK-ASM: sethi %h44(AGlobalVar), [[R:%[goli][0-7]]]
++; CHECK-ASM: add [[R]], %m44(AGlobalVar), [[R]]
++define i64 @foo(i64 %a) {
++entry:
++ %0 = load i64* @AGlobalVar, align 4
++ %1 = add i64 %a, %0
++ %2 = call i64 @bar(i64 %1)
++ ret i64 %2
++}
++
++
++declare i64 @bar(i64)
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -895,10 +895,12 @@ SparcTargetLowering::LowerCall_32(TargetLowering::
+ // If the callee is a GlobalAddress node (quite common, every direct call is)
+ // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
+ // Likewise ExternalSymbol -> TargetExternalSymbol.
++ unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_)
++ ? SparcMCExpr::VK_Sparc_WPLT30 : 0);
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
+- Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
++ Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32, 0, TF);
+ else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
+- Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
++ Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32, TF);
+
+ // Returns a chain & a flag for retval copy to use
+ SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
+@@ -1209,10 +1211,13 @@ SparcTargetLowering::LowerCall_64(TargetLowering::
+ // Likewise ExternalSymbol -> TargetExternalSymbol.
+ SDValue Callee = CLI.Callee;
+ bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CS);
++ unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_)
++ ? SparcMCExpr::VK_Sparc_WPLT30 : 0);
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
+- Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy());
++ Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0,
++ TF);
+ else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
+- Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy());
++ Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy(), TF);
+
+ // Build the operands for the call instruction itself.
+ SmallVector<SDValue, 8> Ops;
+@@ -1796,8 +1801,8 @@ SDValue SparcTargetLowering::makeAddress(SDValue O
+ // Handle PIC mode first.
+ if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ // This is the pic32 code model, the GOT is known to be smaller than 4GB.
+- SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI,
+- SparcMCExpr::VK_Sparc_LO, DAG);
++ SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22,
++ SparcMCExpr::VK_Sparc_GOT10, DAG);
+ SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
+ SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo);
+ // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
+Index: lib/Target/Sparc/SparcAsmPrinter.cpp
+===================================================================
+--- lib/Target/Sparc/SparcAsmPrinter.cpp
++++ lib/Target/Sparc/SparcAsmPrinter.cpp
+@@ -232,12 +232,12 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(co
+ MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
+ EmitCall(OutStreamer, Callee);
+ OutStreamer.EmitLabel(SethiLabel);
+- MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI,
++ MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22,
+ GOTLabel, StartLabel, SethiLabel,
+ OutContext);
+ EmitSETHI(OutStreamer, hiImm, MCRegOP);
+ OutStreamer.EmitLabel(EndLabel);
+- MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO,
++ MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC10,
+ GOTLabel, StartLabel, EndLabel,
+ OutContext);
+ EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP);
+Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+@@ -26,6 +26,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui
+ case FK_Data_4:
+ case FK_Data_8:
+ return Value;
++ case Sparc::fixup_sparc_wplt30:
+ case Sparc::fixup_sparc_call30:
+ return (Value >> 2) & 0x3fffffff;
+ case Sparc::fixup_sparc_br22:
+@@ -32,8 +33,12 @@ static unsigned adjustFixupValue(unsigned Kind, ui
+ return (Value >> 2) & 0x3fffff;
+ case Sparc::fixup_sparc_br19:
+ return (Value >> 2) & 0x7ffff;
++ case Sparc::fixup_sparc_pc22:
++ case Sparc::fixup_sparc_got22:
+ case Sparc::fixup_sparc_hi22:
+ return (Value >> 10) & 0x3fffff;
++ case Sparc::fixup_sparc_pc10:
++ case Sparc::fixup_sparc_got10:
+ case Sparc::fixup_sparc_lo10:
+ return Value & 0x3ff;
+ case Sparc::fixup_sparc_h44:
+@@ -72,6 +77,11 @@ namespace {
+ { "fixup_sparc_l44", 20, 12, 0 },
+ { "fixup_sparc_hh", 10, 22, 0 },
+ { "fixup_sparc_hm", 22, 10, 0 },
++ { "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_got22", 10, 22, 0 },
++ { "fixup_sparc_got10", 22, 10, 0 },
++ { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }
+ };
+
+ if (Kind < FirstTargetFixupKind)
+@@ -82,6 +92,20 @@ namespace {
+ return Infos[Kind - FirstTargetFixupKind];
+ }
+
++ void processFixupValue(const MCAssembler &Asm,
++ const MCAsmLayout &Layout,
++ const MCFixup &Fixup,
++ const MCFragment *DF,
++ MCValue & Target,
++ uint64_t &Value,
++ bool &IsResolved) {
++ switch ((Sparc::Fixups)Fixup.getKind()) {
++ default: break;
++ case Sparc::fixup_sparc_wplt30: IsResolved = false; break;
++ }
++ }
++
++
+ bool mayNeedRelaxation(const MCInst &Inst) const {
+ // FIXME.
+ return false;
+Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
++++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+@@ -48,6 +48,21 @@ namespace llvm {
+ /// fixup_sparc_hm - 10-bit fixup corresponding to %hm(foo)
+ fixup_sparc_hm,
+
++ /// fixup_sparc_pc22 - 22-bit fixup corresponding to %pc22(foo)
++ fixup_sparc_pc22,
++
++ /// fixup_sparc_pc10 - 10-bit fixup corresponding to %pc10(foo)
++ fixup_sparc_pc10,
++
++ /// fixup_sparc_got22 - 22-bit fixup corresponding to %got22(foo)
++ fixup_sparc_got22,
++
++ /// fixup_sparc_got10 - 10-bit fixup corresponding to %got10(foo)
++ fixup_sparc_got10,
++
++ /// fixup_sparc_wplt30
++ fixup_sparc_wplt30,
++
+ // Marker
+ LastTargetFixupKind,
+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+@@ -7,8 +7,9 @@
+ //
+ //===----------------------------------------------------------------------===//
+
++#include "MCTargetDesc/SparcFixupKinds.h"
++#include "MCTargetDesc/SparcMCExpr.h"
+ #include "MCTargetDesc/SparcMCTargetDesc.h"
+-#include "MCTargetDesc/SparcFixupKinds.h"
+ #include "llvm/ADT/STLExtras.h"
+ #include "llvm/MC/MCELFObjectWriter.h"
+ #include "llvm/MC/MCExpr.h"
+@@ -31,6 +32,11 @@ namespace {
+ bool IsPCRel, bool IsRelocWithSymbol,
+ int64_t Addend) const;
+
++ virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
++ const MCValue &Target,
++ const MCFragment &F,
++ const MCFixup &Fixup,
++ bool IsPCRel) const;
+ };
+ }
+
+@@ -40,6 +46,12 @@ unsigned SparcELFObjectWriter::GetRelocType(const
+ bool IsPCRel,
+ bool IsRelocWithSymbol,
+ int64_t Addend) const {
++
++ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) {
++ if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32)
++ return ELF::R_SPARC_DISP32;
++ }
++
+ if (IsPCRel) {
+ switch((unsigned)Fixup.getKind()) {
+ default:
+@@ -51,6 +63,9 @@ unsigned SparcELFObjectWriter::GetRelocType(const
+ case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30;
+ case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22;
+ case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19;
++ case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22;
++ case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10;
++ case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30;
+ }
+ }
+
+@@ -74,10 +89,30 @@ unsigned SparcELFObjectWriter::GetRelocType(const
+ case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44;
+ case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22;
+ case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10;
++ case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22;
++ case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10;
+ }
++
+ return ELF::R_SPARC_NONE;
+ }
+
++const MCSymbol *SparcELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
++ const MCValue &Target,
++ const MCFragment &F,
++ const MCFixup &Fixup,
++ bool IsPCRel) const {
++
++ if (!Target.getSymA())
++ return NULL;
++ switch((unsigned)Fixup.getKind()) {
++ default: break;
++ case Sparc::fixup_sparc_got22:
++ case Sparc::fixup_sparc_got10:
++ return &Target.getSymA()->getSymbol().AliasedSymbol();
++ }
++ return NULL;
++}
++
+ MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS,
+ bool Is64Bit,
+ uint8_t OSABI) {
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+@@ -17,6 +17,7 @@
+ #include "llvm/MC/MCContext.h"
+ #include "llvm/MC/MCAssembler.h"
+ #include "llvm/MC/MCELF.h"
++#include "llvm/MC/MCSymbol.h"
+ #include "llvm/Object/ELF.h"
+
+
+@@ -54,6 +55,13 @@ bool SparcMCExpr::printVariantKind(raw_ostream &OS
+ case VK_Sparc_L44: OS << "%l44("; break;
+ case VK_Sparc_HH: OS << "%hh("; break;
+ case VK_Sparc_HM: OS << "%hm("; break;
++ // FIXME: use %pc22/%pc10, if system assembler supports them.
++ case VK_Sparc_PC22: OS << "%hi("; break;
++ case VK_Sparc_PC10: OS << "%lo("; break;
++ // FIXME: use %got22/%got10, if system assembler supports them.
++ case VK_Sparc_GOT22: OS << "%hi("; break;
++ case VK_Sparc_GOT10: OS << "%lo("; break;
++ case VK_Sparc_WPLT30: closeParen = false; break;
+ case VK_Sparc_R_DISP32: OS << "%r_disp32("; break;
+ case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break;
+ case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break;
+@@ -87,6 +95,10 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
+ .Case("l44", VK_Sparc_L44)
+ .Case("hh", VK_Sparc_HH)
+ .Case("hm", VK_Sparc_HM)
++ .Case("pc22", VK_Sparc_PC22)
++ .Case("pc10", VK_Sparc_PC10)
++ .Case("got22", VK_Sparc_GOT22)
++ .Case("got10", VK_Sparc_GOT10)
+ .Case("r_disp32", VK_Sparc_R_DISP32)
+ .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
+ .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
+@@ -109,9 +121,26 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
+ .Default(VK_Sparc_None);
+ }
+
++Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) {
++ switch (Kind) {
++ default: assert(0 && "Unhandled SparcMCExpr::VariantKind");
++ case VK_Sparc_LO: return Sparc::fixup_sparc_lo10;
++ case VK_Sparc_HI: return Sparc::fixup_sparc_hi22;
++ case VK_Sparc_H44: return Sparc::fixup_sparc_h44;
++ case VK_Sparc_M44: return Sparc::fixup_sparc_m44;
++ case VK_Sparc_L44: return Sparc::fixup_sparc_l44;
++ case VK_Sparc_HH: return Sparc::fixup_sparc_hh;
++ case VK_Sparc_HM: return Sparc::fixup_sparc_hm;
++ case VK_Sparc_PC22: return Sparc::fixup_sparc_pc22;
++ case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10;
++ case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22;
++ case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10;
++ }
++}
++
+ bool
+ SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
+- const MCAsmLayout *Layout) const {
++ const MCAsmLayout *Layout) const {
+ if (!Layout)
+ return false;
+ return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+@@ -15,6 +15,7 @@
+ #ifndef LLVM_SPARCMCEXPR_H
+ #define LLVM_SPARCMCEXPR_H
+
++#include "SparcFixupKinds.h"
+ #include "llvm/MC/MCExpr.h"
+
+ namespace llvm {
+@@ -31,6 +32,11 @@ class SparcMCExpr : public MCTargetExpr {
+ VK_Sparc_L44,
+ VK_Sparc_HH,
+ VK_Sparc_HM,
++ VK_Sparc_PC22,
++ VK_Sparc_PC10,
++ VK_Sparc_GOT22,
++ VK_Sparc_GOT10,
++ VK_Sparc_WPLT30,
+ VK_Sparc_R_DISP32,
+ VK_Sparc_TLS_GD_HI22,
+ VK_Sparc_TLS_GD_LO10,
+@@ -75,6 +81,9 @@ class SparcMCExpr : public MCTargetExpr {
+ /// getSubExpr - Get the child of this expression.
+ const MCExpr *getSubExpr() const { return Expr; }
+
++ /// getFixupKind - Get the fixup kind of this expression.
++ Sparc::Fixups getFixupKind() const { return getFixupKind(Kind); }
++
+ /// @}
+ void PrintImpl(raw_ostream &OS) const;
+ bool EvaluateAsRelocatableImpl(MCValue &Res,
+@@ -94,6 +103,7 @@ class SparcMCExpr : public MCTargetExpr {
+
+ static VariantKind parseVariantKind(StringRef name);
+ static bool printVariantKind(raw_ostream &OS, VariantKind Kind);
++ static Sparc::Fixups getFixupKind(VariantKind Kind);
+ };
+
+ } // end namespace llvm.
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+@@ -94,37 +94,8 @@ getMachineOpValue(const MCInst &MI, const MCOperan
+ assert(MO.isExpr());
+ const MCExpr *Expr = MO.getExpr();
+ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
+- switch(SExpr->getKind()) {
+- default: assert(0 && "Unhandled sparc expression!"); break;
+- case SparcMCExpr::VK_Sparc_LO:
+- Fixups.push_back(MCFixup::Create(0, Expr,
+- (MCFixupKind)Sparc::fixup_sparc_lo10));
+- break;
+- case SparcMCExpr::VK_Sparc_HI:
+- Fixups.push_back(MCFixup::Create(0, Expr,
+- (MCFixupKind)Sparc::fixup_sparc_hi22));
+- break;
+- case SparcMCExpr::VK_Sparc_H44:
+- Fixups.push_back(MCFixup::Create(0, Expr,
+- (MCFixupKind)Sparc::fixup_sparc_h44));
+- break;
+- case SparcMCExpr::VK_Sparc_M44:
+- Fixups.push_back(MCFixup::Create(0, Expr,
+- (MCFixupKind)Sparc::fixup_sparc_m44));
+- break;
+- case SparcMCExpr::VK_Sparc_L44:
+- Fixups.push_back(MCFixup::Create(0, Expr,
+- (MCFixupKind)Sparc::fixup_sparc_l44));
+- break;
+- case SparcMCExpr::VK_Sparc_HH:
+- Fixups.push_back(MCFixup::Create(0, Expr,
+- (MCFixupKind)Sparc::fixup_sparc_hh));
+- break;
+- case SparcMCExpr::VK_Sparc_HM:
+- Fixups.push_back(MCFixup::Create(0, Expr,
+- (MCFixupKind)Sparc::fixup_sparc_hm));
+- break;
+- }
++ MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
++ Fixups.push_back(MCFixup::Create(0, Expr, Kind));
+ return 0;
+ }
+
+@@ -143,8 +114,15 @@ getCallTargetOpValue(const MCInst &MI, unsigned Op
+ if (MO.isReg() || MO.isImm())
+ return getMachineOpValue(MI, MO, Fixups);
+
+- Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
+- (MCFixupKind)Sparc::fixup_sparc_call30));
++ MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30;
++
++ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) {
++ if (SExpr->getKind() == SparcMCExpr::VK_Sparc_WPLT30)
++ fixupKind = (MCFixupKind)Sparc::fixup_sparc_wplt30;
++ }
++
++ Fixups.push_back(MCFixup::Create(0, MO.getExpr(), fixupKind));
++
+ return 0;
+ }
+
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff
new file mode 100644
index 0000000..2e668a3
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200962-sparc.diff
@@ -0,0 +1,378 @@
+Pull in r200962 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Emit relocations for Thread Local Storage (TLS) when integrated assembler is used.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+@@ -26,31 +26,65 @@ static unsigned adjustFixupValue(unsigned Kind, ui
+ case FK_Data_4:
+ case FK_Data_8:
+ return Value;
++
+ case Sparc::fixup_sparc_wplt30:
+ case Sparc::fixup_sparc_call30:
+ return (Value >> 2) & 0x3fffffff;
++
+ case Sparc::fixup_sparc_br22:
+ return (Value >> 2) & 0x3fffff;
++
+ case Sparc::fixup_sparc_br19:
+ return (Value >> 2) & 0x7ffff;
++
+ case Sparc::fixup_sparc_pc22:
+ case Sparc::fixup_sparc_got22:
++ case Sparc::fixup_sparc_tls_gd_hi22:
++ case Sparc::fixup_sparc_tls_ldm_hi22:
++ case Sparc::fixup_sparc_tls_ie_hi22:
+ case Sparc::fixup_sparc_hi22:
+ return (Value >> 10) & 0x3fffff;
++
+ case Sparc::fixup_sparc_pc10:
+ case Sparc::fixup_sparc_got10:
++ case Sparc::fixup_sparc_tls_gd_lo10:
++ case Sparc::fixup_sparc_tls_ldm_lo10:
++ case Sparc::fixup_sparc_tls_ie_lo10:
+ case Sparc::fixup_sparc_lo10:
+ return Value & 0x3ff;
++
++ case Sparc::fixup_sparc_tls_ldo_hix22:
++ case Sparc::fixup_sparc_tls_le_hix22:
++ return (~Value >> 10) & 0x3fffff;
++
++ case Sparc::fixup_sparc_tls_ldo_lox10:
++ case Sparc::fixup_sparc_tls_le_lox10:
++ return (~(~Value & 0x3ff)) & 0x1fff;
++
+ case Sparc::fixup_sparc_h44:
+ return (Value >> 22) & 0x3fffff;
++
+ case Sparc::fixup_sparc_m44:
+ return (Value >> 12) & 0x3ff;
++
+ case Sparc::fixup_sparc_l44:
+ return Value & 0xfff;
++
+ case Sparc::fixup_sparc_hh:
+ return (Value >> 42) & 0x3fffff;
++
+ case Sparc::fixup_sparc_hm:
+ return (Value >> 32) & 0x3ff;
++
++ case Sparc::fixup_sparc_tls_gd_add:
++ case Sparc::fixup_sparc_tls_gd_call:
++ case Sparc::fixup_sparc_tls_ldm_add:
++ case Sparc::fixup_sparc_tls_ldm_call:
++ case Sparc::fixup_sparc_tls_ldo_add:
++ case Sparc::fixup_sparc_tls_ie_ld:
++ case Sparc::fixup_sparc_tls_ie_ldx:
++ case Sparc::fixup_sparc_tls_ie_add:
++ return 0;
+ }
+ }
+
+@@ -81,7 +115,25 @@ namespace {
+ { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_got22", 10, 22, 0 },
+ { "fixup_sparc_got10", 22, 10, 0 },
+- { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }
++ { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
++ { "fixup_sparc_tls_gd_hi22", 10, 22, 0 },
++ { "fixup_sparc_tls_gd_lo10", 22, 10, 0 },
++ { "fixup_sparc_tls_gd_add", 0, 0, 0 },
++ { "fixup_sparc_tls_gd_call", 0, 0, 0 },
++ { "fixup_sparc_tls_ldm_hi22", 10, 22, 0 },
++ { "fixup_sparc_tls_ldm_lo10", 22, 10, 0 },
++ { "fixup_sparc_tls_ldm_add", 0, 0, 0 },
++ { "fixup_sparc_tls_ldm_call", 0, 0, 0 },
++ { "fixup_sparc_tls_ldo_hix22", 10, 22, 0 },
++ { "fixup_sparc_tls_ldo_lox10", 22, 10, 0 },
++ { "fixup_sparc_tls_ldo_add", 0, 0, 0 },
++ { "fixup_sparc_tls_ie_hi22", 10, 22, 0 },
++ { "fixup_sparc_tls_ie_lo10", 22, 10, 0 },
++ { "fixup_sparc_tls_ie_ld", 0, 0, 0 },
++ { "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
++ { "fixup_sparc_tls_ie_add", 0, 0, 0 },
++ { "fixup_sparc_tls_le_hix22", 0, 0, 0 },
++ { "fixup_sparc_tls_le_lox10", 0, 0, 0 }
+ };
+
+ if (Kind < FirstTargetFixupKind)
+@@ -101,11 +153,28 @@ namespace {
+ bool &IsResolved) {
+ switch ((Sparc::Fixups)Fixup.getKind()) {
+ default: break;
+- case Sparc::fixup_sparc_wplt30: IsResolved = false; break;
++ case Sparc::fixup_sparc_wplt30:
++ case Sparc::fixup_sparc_tls_gd_hi22:
++ case Sparc::fixup_sparc_tls_gd_lo10:
++ case Sparc::fixup_sparc_tls_gd_add:
++ case Sparc::fixup_sparc_tls_gd_call:
++ case Sparc::fixup_sparc_tls_ldm_hi22:
++ case Sparc::fixup_sparc_tls_ldm_lo10:
++ case Sparc::fixup_sparc_tls_ldm_add:
++ case Sparc::fixup_sparc_tls_ldm_call:
++ case Sparc::fixup_sparc_tls_ldo_hix22:
++ case Sparc::fixup_sparc_tls_ldo_lox10:
++ case Sparc::fixup_sparc_tls_ldo_add:
++ case Sparc::fixup_sparc_tls_ie_hi22:
++ case Sparc::fixup_sparc_tls_ie_lo10:
++ case Sparc::fixup_sparc_tls_ie_ld:
++ case Sparc::fixup_sparc_tls_ie_ldx:
++ case Sparc::fixup_sparc_tls_ie_add:
++ case Sparc::fixup_sparc_tls_le_hix22:
++ case Sparc::fixup_sparc_tls_le_lox10: IsResolved = false; break;
+ }
+ }
+
+-
+ bool mayNeedRelaxation(const MCInst &Inst) const {
+ // FIXME.
+ return false;
+Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
++++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+@@ -63,6 +63,26 @@ namespace llvm {
+ /// fixup_sparc_wplt30
+ fixup_sparc_wplt30,
+
++ /// fixups for Thread Local Storage
++ fixup_sparc_tls_gd_hi22,
++ fixup_sparc_tls_gd_lo10,
++ fixup_sparc_tls_gd_add,
++ fixup_sparc_tls_gd_call,
++ fixup_sparc_tls_ldm_hi22,
++ fixup_sparc_tls_ldm_lo10,
++ fixup_sparc_tls_ldm_add,
++ fixup_sparc_tls_ldm_call,
++ fixup_sparc_tls_ldo_hix22,
++ fixup_sparc_tls_ldo_lox10,
++ fixup_sparc_tls_ldo_add,
++ fixup_sparc_tls_ie_hi22,
++ fixup_sparc_tls_ie_lo10,
++ fixup_sparc_tls_ie_ld,
++ fixup_sparc_tls_ie_ldx,
++ fixup_sparc_tls_ie_add,
++ fixup_sparc_tls_le_hix22,
++ fixup_sparc_tls_le_lox10,
++
+ // Marker
+ LastTargetFixupKind,
+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+@@ -91,6 +91,24 @@ unsigned SparcELFObjectWriter::GetRelocType(const
+ case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10;
+ case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22;
+ case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10;
++ case Sparc::fixup_sparc_tls_gd_hi22: return ELF::R_SPARC_TLS_GD_HI22;
++ case Sparc::fixup_sparc_tls_gd_lo10: return ELF::R_SPARC_TLS_GD_LO10;
++ case Sparc::fixup_sparc_tls_gd_add: return ELF::R_SPARC_TLS_GD_ADD;
++ case Sparc::fixup_sparc_tls_gd_call: return ELF::R_SPARC_TLS_GD_CALL;
++ case Sparc::fixup_sparc_tls_ldm_hi22: return ELF::R_SPARC_TLS_LDM_HI22;
++ case Sparc::fixup_sparc_tls_ldm_lo10: return ELF::R_SPARC_TLS_LDM_LO10;
++ case Sparc::fixup_sparc_tls_ldm_add: return ELF::R_SPARC_TLS_LDM_ADD;
++ case Sparc::fixup_sparc_tls_ldm_call: return ELF::R_SPARC_TLS_LDM_CALL;
++ case Sparc::fixup_sparc_tls_ldo_hix22: return ELF::R_SPARC_TLS_LDO_HIX22;
++ case Sparc::fixup_sparc_tls_ldo_lox10: return ELF::R_SPARC_TLS_LDO_LOX10;
++ case Sparc::fixup_sparc_tls_ldo_add: return ELF::R_SPARC_TLS_LDO_ADD;
++ case Sparc::fixup_sparc_tls_ie_hi22: return ELF::R_SPARC_TLS_IE_HI22;
++ case Sparc::fixup_sparc_tls_ie_lo10: return ELF::R_SPARC_TLS_IE_LO10;
++ case Sparc::fixup_sparc_tls_ie_ld: return ELF::R_SPARC_TLS_IE_LD;
++ case Sparc::fixup_sparc_tls_ie_ldx: return ELF::R_SPARC_TLS_IE_LDX;
++ case Sparc::fixup_sparc_tls_ie_add: return ELF::R_SPARC_TLS_IE_ADD;
++ case Sparc::fixup_sparc_tls_le_hix22: return ELF::R_SPARC_TLS_LE_HIX22;
++ case Sparc::fixup_sparc_tls_le_lox10: return ELF::R_SPARC_TLS_LE_LOX10;
+ }
+
+ return ELF::R_SPARC_NONE;
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+@@ -135,6 +135,25 @@ Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExp
+ case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10;
+ case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22;
+ case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10;
++ case VK_Sparc_WPLT30: return Sparc::fixup_sparc_wplt30;
++ case VK_Sparc_TLS_GD_HI22: return Sparc::fixup_sparc_tls_gd_hi22;
++ case VK_Sparc_TLS_GD_LO10: return Sparc::fixup_sparc_tls_gd_lo10;
++ case VK_Sparc_TLS_GD_ADD: return Sparc::fixup_sparc_tls_gd_add;
++ case VK_Sparc_TLS_GD_CALL: return Sparc::fixup_sparc_tls_gd_call;
++ case VK_Sparc_TLS_LDM_HI22: return Sparc::fixup_sparc_tls_ldm_hi22;
++ case VK_Sparc_TLS_LDM_LO10: return Sparc::fixup_sparc_tls_ldm_lo10;
++ case VK_Sparc_TLS_LDM_ADD: return Sparc::fixup_sparc_tls_ldm_add;
++ case VK_Sparc_TLS_LDM_CALL: return Sparc::fixup_sparc_tls_ldm_call;
++ case VK_Sparc_TLS_LDO_HIX22: return Sparc::fixup_sparc_tls_ldo_hix22;
++ case VK_Sparc_TLS_LDO_LOX10: return Sparc::fixup_sparc_tls_ldo_lox10;
++ case VK_Sparc_TLS_LDO_ADD: return Sparc::fixup_sparc_tls_ldo_add;
++ case VK_Sparc_TLS_IE_HI22: return Sparc::fixup_sparc_tls_ie_hi22;
++ case VK_Sparc_TLS_IE_LO10: return Sparc::fixup_sparc_tls_ie_lo10;
++ case VK_Sparc_TLS_IE_LD: return Sparc::fixup_sparc_tls_ie_ld;
++ case VK_Sparc_TLS_IE_LDX: return Sparc::fixup_sparc_tls_ie_ldx;
++ case VK_Sparc_TLS_IE_ADD: return Sparc::fixup_sparc_tls_ie_add;
++ case VK_Sparc_TLS_LE_HIX22: return Sparc::fixup_sparc_tls_le_hix22;
++ case VK_Sparc_TLS_LE_LOX10: return Sparc::fixup_sparc_tls_le_lox10;
+ }
+ }
+
+@@ -147,7 +166,33 @@ SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Re
+ }
+
+ static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
+- assert(0 && "Implement fixELFSymbolsInTLSFixupsImpl!");
++ switch (Expr->getKind()) {
++ case MCExpr::Target:
++ llvm_unreachable("Can't handle nested target expr!");
++ break;
++
++ case MCExpr::Constant:
++ break;
++
++ case MCExpr::Binary: {
++ const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
++ fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
++ fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
++ break;
++ }
++
++ case MCExpr::SymbolRef: {
++ const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
++ MCSymbolData &SD = Asm.getOrCreateSymbolData(SymRef.getSymbol());
++ MCELF::SetType(SD, ELF::STT_TLS);
++ break;
++ }
++
++ case MCExpr::Unary:
++ fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
++ break;
++ }
++
+ }
+
+ void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
+Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+===================================================================
+--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
++++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+@@ -20,6 +20,7 @@
+ #include "llvm/MC/MCExpr.h"
+ #include "llvm/MC/MCInst.h"
+ #include "llvm/MC/MCRegisterInfo.h"
++#include "llvm/MC/MCSymbol.h"
+ #include "llvm/ADT/Statistic.h"
+ #include "llvm/Support/raw_ostream.h"
+
+@@ -76,6 +77,21 @@ EncodeInstruction(const MCInst &MI, raw_ostream &O
+ OS << (char)(Bits >> 24);
+ Bits <<= 8;
+ }
++ unsigned tlsOpNo = 0;
++ switch (MI.getOpcode()) {
++ default: break;
++ case SP::TLS_CALL: tlsOpNo = 1; break;
++ case SP::TLS_ADDrr:
++ case SP::TLS_ADDXrr:
++ case SP::TLS_LDrr:
++ case SP::TLS_LDXrr: tlsOpNo = 3; break;
++ }
++ if (tlsOpNo != 0) {
++ const MCOperand &MO = MI.getOperand(tlsOpNo);
++ uint64_t op = getMachineOpValue(MI, MO, Fixups);
++ assert(op == 0 && "Unexpected operand value!");
++ (void)op; // suppress warning.
++ }
+
+ ++MCNumEmitted; // Keep track of the # of mi's emitted.
+ }
+@@ -114,6 +130,21 @@ getCallTargetOpValue(const MCInst &MI, unsigned Op
+ if (MO.isReg() || MO.isImm())
+ return getMachineOpValue(MI, MO, Fixups);
+
++ if (MI.getOpcode() == SP::TLS_CALL) {
++ // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in
++ // EncodeInstruction.
++#ifndef NDEBUG
++ // Verify that the callee is actually __tls_get_addr.
++ const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr());
++ assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef &&
++ "Unexpected expression in TLS_CALL");
++ const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr());
++ assert(SymExpr->getSymbol().getName() == "__tls_get_addr" &&
++ "Unexpected function for TLS_CALL");
++#endif
++ return 0;
++ }
++
+ MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30;
+
+ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) {
+Index: test/CodeGen/SPARC/tls.ll
+===================================================================
+--- test/CodeGen/SPARC/tls.ll
++++ test/CodeGen/SPARC/tls.ll
+@@ -3,6 +3,10 @@
+ ; RUN: llc <%s -march=sparc -relocation-model=pic | FileCheck %s --check-prefix=pic
+ ; RUN: llc <%s -march=sparcv9 -relocation-model=pic | FileCheck %s --check-prefix=pic
+
++; RUN: llc <%s -march=sparc -relocation-model=static -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=v8abs-obj
++; RUN: llc <%s -march=sparcv9 -relocation-model=static -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=v9abs-obj
++; RUN: llc <%s -march=sparc -relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=pic-obj
++; RUN: llc <%s -march=sparcv9 -relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=pic-obj
+
+ @local_symbol = internal thread_local global i32 0
+ @extern_symbol = external thread_local global i32
+@@ -69,3 +73,47 @@ entry:
+ store i32 %1, i32* @extern_symbol, align 4
+ ret i32 %1
+ }
++
++
++; v8abs-obj: Relocations [
++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_HIX22 local_symbol 0x0
++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_LOX10 local_symbol 0x0
++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_HI22 _GLOBAL_OFFSET_TABLE_ 0x0
++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_LO10 _GLOBAL_OFFSET_TABLE_ 0x0
++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_HI22 extern_symbol 0x0
++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LO10 extern_symbol 0x0
++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LD extern_symbol 0x0
++; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_ADD extern_symbol 0x0
++; v8abs-obj: ]
++
++; v9abs-obj: Relocations [
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_HIX22 local_symbol 0x0
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_LOX10 local_symbol 0x0
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_H44 _GLOBAL_OFFSET_TABLE_ 0x0
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_M44 _GLOBAL_OFFSET_TABLE_ 0x0
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_L44 _GLOBAL_OFFSET_TABLE_ 0x0
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_HI22 extern_symbol 0x0
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LO10 extern_symbol 0x0
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LDX extern_symbol 0x0
++; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_ADD extern_symbol 0x0
++; v9abs-obj: ]
++
++; pic-obj: Relocations [
++; pic-obj: Section (2) .rela.text {
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_HIX22 local_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_LOX10 local_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_HI22 local_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_LO10 local_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_ADD local_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_CALL local_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_ADD local_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_HI22 extern_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_LO10 extern_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_ADD extern_symbol 0x0
++; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_CALL extern_symbol 0x0
++; pic-obj: ]
++
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200963-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200963-sparc.diff
new file mode 100644
index 0000000..f8a817e
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200963-sparc.diff
@@ -0,0 +1,131 @@
+Pull in r200963 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Emit correct encoding for atomic instructions. Also, add support for parsing CAS instructions to test the CAS encoding.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: test/MC/Sparc/sparc-atomic-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-atomic-instructions.s
++++ test/MC/Sparc/sparc-atomic-instructions.s
+@@ -0,0 +1,19 @@
++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
++
++ ! CHECK: membar 15 ! encoding: [0x81,0x43,0xe0,0x0f]
++ membar 15
++
++ ! CHECK: stbar ! encoding: [0x81,0x43,0xc0,0x00]
++ stbar
++
++ ! CHECK: swap [%i0+%l6], %o2 ! encoding: [0xd4,0x7e,0x00,0x16]
++ swap [%i0+%l6], %o2
++
++ ! CHECK: swap [%i0+32], %o2 ! encoding: [0xd4,0x7e,0x20,0x20]
++ swap [%i0+32], %o2
++
++ ! CHECK: cas [%i0], %l6, %o2 ! encoding: [0xd5,0xe6,0x10,0x16]
++ cas [%i0], %l6, %o2
++
++ ! CHECK: casx [%i0], %l6, %o2 ! encoding: [0xd5,0xf6,0x10,0x16]
++ casx [%i0], %l6, %o2
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -935,19 +935,19 @@ let Predicates = [HasV9], hasSideEffects = 1, rd =
+ def MEMBARi : F3_2<2, 0b101000, (outs), (ins i32imm:$simm13),
+ "membar $simm13", []>;
+
+-let Constraints = "$val = $rd" in {
++let Constraints = "$val = $dst" in {
+ def SWAPrr : F3_1<3, 0b001111,
+- (outs IntRegs:$rd), (ins IntRegs:$val, MEMrr:$addr),
+- "swap [$addr], $rd",
+- [(set i32:$rd, (atomic_swap_32 ADDRrr:$addr, i32:$val))]>;
++ (outs IntRegs:$dst), (ins MEMrr:$addr, IntRegs:$val),
++ "swap [$addr], $dst",
++ [(set i32:$dst, (atomic_swap_32 ADDRrr:$addr, i32:$val))]>;
+ def SWAPri : F3_2<3, 0b001111,
+- (outs IntRegs:$rd), (ins IntRegs:$val, MEMri:$addr),
+- "swap [$addr], $rd",
+- [(set i32:$rd, (atomic_swap_32 ADDRri:$addr, i32:$val))]>;
++ (outs IntRegs:$dst), (ins MEMri:$addr, IntRegs:$val),
++ "swap [$addr], $dst",
++ [(set i32:$dst, (atomic_swap_32 ADDRri:$addr, i32:$val))]>;
+ }
+
+ let Predicates = [HasV9], Constraints = "$swap = $rd" in
+- def CASrr: F3_1<3, 0b111100,
++ def CASrr: F3_1_asi<3, 0b111100, 0b10000000,
+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
+ IntRegs:$swap),
+ "cas [$rs1], $rs2, $rd",
+Index: lib/Target/Sparc/SparcInstrFormats.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrFormats.td
++++ lib/Target/Sparc/SparcInstrFormats.td
+@@ -100,9 +100,8 @@ class F3<dag outs, dag ins, string asmstr, list<da
+
+ // Specific F3 classes: SparcV8 manual, page 44
+ //
+-class F3_1<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
++class F3_1_asi<bits<2> opVal, bits<6> op3val, bits<8> asi, dag outs, dag ins,
+ string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
+- bits<8> asi = 0; // asi not currently used
+ bits<5> rs2;
+
+ let op = opVal;
+@@ -113,6 +112,10 @@ class F3<dag outs, dag ins, string asmstr, list<da
+ let Inst{4-0} = rs2;
+ }
+
++class F3_1<bits<2> opVal, bits<6> op3val, dag outs, dag ins, string asmstr,
++ list<dag> pattern> : F3_1_asi<opVal, op3val, 0, outs, ins,
++ asmstr, pattern>;
++
+ class F3_2<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
+ string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
+ bits<13> simm13;
+Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+===================================================================
+--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+@@ -546,7 +546,24 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*>
+ Parser.getTok().getLoc()));
+ Parser.Lex(); // Eat the [
+
+- ResTy = parseMEMOperand(Operands);
++ if (Mnemonic == "cas" || Mnemonic == "casx") {
++ SMLoc S = Parser.getTok().getLoc();
++ if (getLexer().getKind() != AsmToken::Percent)
++ return MatchOperand_NoMatch;
++ Parser.Lex(); // eat %
++
++ unsigned RegNo, RegKind;
++ if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
++ return MatchOperand_NoMatch;
++
++ Parser.Lex(); // Eat the identifier token.
++ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
++ Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
++ ResTy = MatchOperand_Success;
++ } else {
++ ResTy = parseMEMOperand(Operands);
++ }
++
+ if (ResTy != MatchOperand_Success)
+ return ResTy;
+
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -415,7 +415,7 @@ def SETHIXi : F2_1<0b100,
+
+ // ATOMICS.
+ let Predicates = [Is64Bit], Constraints = "$swap = $rd" in {
+- def CASXrr: F3_1<3, 0b111110,
++ def CASXrr: F3_1_asi<3, 0b111110, 0b10000000,
+ (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
+ I64Regs:$swap),
+ "casx [$rs1], $rs2, $rd",
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r200965-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r200965-sparc.diff
new file mode 100644
index 0000000..2b0d41e
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r200965-sparc.diff
@@ -0,0 +1,33 @@
+Pull in r200965 from upstream llvm trunk (by Venkatraman Govindaraju):
+
+ [Sparc] Add support for parsing synthetic instruction 'mov'.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262261
+
+Index: lib/Target/Sparc/SparcInstrAliases.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrAliases.td
++++ lib/Target/Sparc/SparcInstrAliases.td
+@@ -134,3 +134,9 @@ def : InstAlias<"retl", (RETL 8)>;
+
+ // ret -> RET 8
+ def : InstAlias<"ret", (RET 8)>;
++
++// mov reg, rd -> or %g0, reg, rd
++def : InstAlias<"mov $rs2, $rd", (ORrr IntRegs:$rd, G0, IntRegs:$rs2)>;
++
++// mov simm13, rd -> or %g0, simm13, rd
++def : InstAlias<"mov $simm13, $rd", (ORri IntRegs:$rd, G0, i32imm:$simm13)>;
+Index: test/MC/Sparc/sparc-alu-instructions.s
+===================================================================
+--- test/MC/Sparc/sparc-alu-instructions.s
++++ test/MC/Sparc/sparc-alu-instructions.s
+@@ -70,3 +70,8 @@
+ ! CHECK: subxcc %g1, %g2, %g3 ! encoding: [0x86,0xe0,0x40,0x02]
+ subxcc %g1, %g2, %g3
+
++ ! CHECK: or %g0, %g1, %g3 ! encoding: [0x86,0x10,0x00,0x01]
++ mov %g1, %g3
++
++ ! CHECK: or %g0, 255, %g3 ! encoding: [0x86,0x10,0x20,0xff]
++ mov 0xff, %g3
diff --git a/contrib/llvm/patches/patch-r262262-clang-r198311-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r198311-sparc.diff
new file mode 100644
index 0000000..751b976
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r198311-sparc.diff
@@ -0,0 +1,31 @@
+Pull in r198311 from upstream clang trunk (by Roman Divacky):
+
+ In the FreeBSD assembler driver, inform the sparc assembler that we're producing
+ PIC code.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -5785,6 +5785,19 @@ void freebsd::Assemble::ConstructJob(Compilation &
+ default:
+ CmdArgs.push_back("-matpcs");
+ }
++ } else if (getToolChain().getArch() == llvm::Triple::sparc ||
++ getToolChain().getArch() == llvm::Triple::sparcv9) {
++ Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
++ options::OPT_fpic, options::OPT_fno_pic,
++ options::OPT_fPIE, options::OPT_fno_PIE,
++ options::OPT_fpie, options::OPT_fno_pie);
++ if (LastPICArg &&
++ (LastPICArg->getOption().matches(options::OPT_fPIC) ||
++ LastPICArg->getOption().matches(options::OPT_fpic) ||
++ LastPICArg->getOption().matches(options::OPT_fPIE) ||
++ LastPICArg->getOption().matches(options::OPT_fpie))) {
++ CmdArgs.push_back("-KPIC");
++ }
+ }
+
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
diff --git a/contrib/llvm/patches/patch-r262262-clang-r198312-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r198312-sparc.diff
new file mode 100644
index 0000000..8903d38
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r198312-sparc.diff
@@ -0,0 +1,19 @@
+Pull in r198312 from upstream clang trunk (by Roman Divacky):
+
+ Remove a tab that snuck in.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -5786,7 +5786,7 @@ void freebsd::Assemble::ConstructJob(Compilation &
+ CmdArgs.push_back("-matpcs");
+ }
+ } else if (getToolChain().getArch() == llvm::Triple::sparc ||
+- getToolChain().getArch() == llvm::Triple::sparcv9) {
++ getToolChain().getArch() == llvm::Triple::sparcv9) {
+ Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+ options::OPT_fpic, options::OPT_fno_pic,
+ options::OPT_fPIE, options::OPT_fno_PIE,
diff --git a/contrib/llvm/patches/patch-r262262-clang-r198911-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r198911-sparc.diff
new file mode 100644
index 0000000..d50b53f
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r198911-sparc.diff
@@ -0,0 +1,46 @@
+Pull in r198911 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ Pass -32/-64 to the assembler when building for sparc/sparc64.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/test/Driver/linux-as.c
+===================================================================
+--- tools/clang/test/Driver/linux-as.c
++++ tools/clang/test/Driver/linux-as.c
+@@ -60,6 +60,20 @@
+ // RUN: | FileCheck -check-prefix=CHECK-PPC-NO-MCPU %s
+ // CHECK-PPC-NO-MCPU-NOT: as{{.*}} "-mcpu=invalid-cpu"
+ //
++// RUN: %clang -target sparc64-linux -mcpu=invalid-cpu -### \
++// RUN: -no-integrated-as -c %s 2>&1 \
++// RUN: | FileCheck -check-prefix=CHECK-SPARCV9 %s
++// CHECK-SPARCV9: as
++// CHECK-SPARCV9: -64
++// CHECK-SPARCV9: -o
++//
++// RUN: %clang -target sparc-linux -mcpu=invalid-cpu -### \
++// RUN: -no-integrated-as -c %s 2>&1 \
++// RUN: | FileCheck -check-prefix=CHECK-SPARCV8 %s
++// CHECK-SPARCV8: as
++// CHECK-SPARCV8: -32
++// CHECK-SPARCV8: -o
++//
+ // RUN: %clang -target s390x-linux -### -no-integrated-as -c %s 2>&1 \
+ // RUN: | FileCheck -check-prefix=CHECK-Z-DEFAULT-ARCH %s
+ // CHECK-Z-DEFAULT-ARCH: as{{.*}} "-march=z10"
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -6226,6 +6226,10 @@ void gnutools::Assemble::ConstructJob(Compilation
+ CmdArgs.push_back("-a64");
+ CmdArgs.push_back("-mppc64le");
+ CmdArgs.push_back("-many");
++ } else if (getToolChain().getArch() == llvm::Triple::sparc) {
++ CmdArgs.push_back("-32");
++ } else if (getToolChain().getArch() == llvm::Triple::sparcv9) {
++ CmdArgs.push_back("-64");
+ } else if (getToolChain().getArch() == llvm::Triple::arm) {
+ StringRef MArch = getToolChain().getArchName();
+ if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
diff --git a/contrib/llvm/patches/patch-r262262-clang-r198912-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r198912-sparc.diff
new file mode 100644
index 0000000..9e3ce43
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r198912-sparc.diff
@@ -0,0 +1,44 @@
+Pull in r198912 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ Give the linker the right ELF type for SPARC targets.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -6461,6 +6461,10 @@ void gnutools::Link::ConstructJob(Compilation &C,
+ CmdArgs.push_back("elf32ppclinux");
+ else if (ToolChain.getArch() == llvm::Triple::ppc64)
+ CmdArgs.push_back("elf64ppc");
++ else if (ToolChain.getArch() == llvm::Triple::sparc)
++ CmdArgs.push_back("elf32_sparc");
++ else if (ToolChain.getArch() == llvm::Triple::sparcv9)
++ CmdArgs.push_back("elf64_sparc");
+ else if (ToolChain.getArch() == llvm::Triple::mips)
+ CmdArgs.push_back("elf32btsmip");
+ else if (ToolChain.getArch() == llvm::Triple::mipsel)
+Index: tools/clang/test/Driver/linux-ld.c
+===================================================================
+--- tools/clang/test/Driver/linux-ld.c
++++ tools/clang/test/Driver/linux-ld.c
+@@ -384,6 +384,18 @@
+ // CHECK-MIPS64EL-N32: "-dynamic-linker" "{{.*}}/lib32/ld.so.1"
+ // CHECK-MIPS64EL-N32-NOT: "--hash-style={{gnu|both}}"
+ //
++// RUN: %clang %s -### -o %t.o 2>&1 \
++// RUN: --target=sparc-linux-gnu \
++// RUN: | FileCheck --check-prefix=CHECK-SPARCV8 %s
++// CHECK-SPARCV8: "{{.*}}ld{{(.exe)?}}"
++// CHECK-SPARCV8: "-m" "elf32_sparc"
++//
++// RUN: %clang %s -### -o %t.o 2>&1 \
++// RUN: --target=sparcv9-linux-gnu \
++// RUN: | FileCheck --check-prefix=CHECK-SPARCV9 %s
++// CHECK-SPARCV9: "{{.*}}ld{{(.exe)?}}"
++// CHECK-SPARCV9: "-m" "elf64_sparc"
++//
+ // Thoroughly exercise the Debian multiarch environment.
+ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+ // RUN: --target=i686-linux-gnu \
diff --git a/contrib/llvm/patches/patch-r262262-clang-r198918-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r198918-sparc.diff
new file mode 100644
index 0000000..a3c6026
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r198918-sparc.diff
@@ -0,0 +1,59 @@
+Pull in r198918 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ Locate GCC installations on SPARC systems.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/Driver/ToolChains.cpp
+===================================================================
+--- tools/clang/lib/Driver/ToolChains.cpp
++++ tools/clang/lib/Driver/ToolChains.cpp
+@@ -1164,6 +1164,13 @@ void Generic_GCC::GCCInstallationDetector::print(r
+ "powerpc64le-suse-linux",
+ "ppc64le-redhat-linux" };
+
++ static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" };
++ static const char *const SPARCv8Triples[] = { "sparc-linux-gnu",
++ "sparcv8-linux-gnu" };
++ static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" };
++ static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu",
++ "sparcv9-linux-gnu" };
++
+ static const char *const SystemZLibDirs[] = { "/lib64", "/lib" };
+ static const char *const SystemZTriples[] = {
+ "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
+@@ -1283,6 +1290,26 @@ void Generic_GCC::GCCInstallationDetector::print(r
+ TripleAliases.append(PPC64LETriples,
+ PPC64LETriples + llvm::array_lengthof(PPC64LETriples));
+ break;
++ case llvm::Triple::sparc:
++ LibDirs.append(SPARCv8LibDirs,
++ SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs));
++ TripleAliases.append(SPARCv8Triples,
++ SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples));
++ BiarchLibDirs.append(SPARCv9LibDirs,
++ SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs));
++ BiarchTripleAliases.append(
++ SPARCv9Triples, SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples));
++ break;
++ case llvm::Triple::sparcv9:
++ LibDirs.append(SPARCv9LibDirs,
++ SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs));
++ TripleAliases.append(SPARCv9Triples,
++ SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples));
++ BiarchLibDirs.append(SPARCv8LibDirs,
++ SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs));
++ BiarchTripleAliases.append(
++ SPARCv8Triples, SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples));
++ break;
+ case llvm::Triple::systemz:
+ LibDirs.append(SystemZLibDirs,
+ SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs));
+@@ -1379,6 +1406,7 @@ static bool findTargetBiarchSuffix(std::string &Su
+ Suffix = "/n32";
+ else if (TargetArch == llvm::Triple::x86_64 ||
+ TargetArch == llvm::Triple::ppc64 ||
++ TargetArch == llvm::Triple::sparcv9 ||
+ TargetArch == llvm::Triple::systemz ||
+ TargetArch == llvm::Triple::mips64 ||
+ TargetArch == llvm::Triple::mips64el)
diff --git a/contrib/llvm/patches/patch-r262262-clang-r198923-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r198923-sparc.diff
new file mode 100644
index 0000000..912aa62
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r198923-sparc.diff
@@ -0,0 +1,49 @@
+Pull in r198923 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ Use the right dynamic linker for SPARC Linux executables.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -6374,7 +6374,8 @@ static StringRef getLinuxDynamicLinker(const ArgLi
+ const toolchains::Linux &ToolChain) {
+ if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android)
+ return "/system/bin/linker";
+- else if (ToolChain.getArch() == llvm::Triple::x86)
++ else if (ToolChain.getArch() == llvm::Triple::x86 ||
++ ToolChain.getArch() == llvm::Triple::sparc)
+ return "/lib/ld-linux.so.2";
+ else if (ToolChain.getArch() == llvm::Triple::aarch64)
+ return "/lib/ld-linux-aarch64.so.1";
+@@ -6399,6 +6400,8 @@ static StringRef getLinuxDynamicLinker(const ArgLi
+ ToolChain.getArch() == llvm::Triple::ppc64le ||
+ ToolChain.getArch() == llvm::Triple::systemz)
+ return "/lib64/ld64.so.1";
++ else if (ToolChain.getArch() == llvm::Triple::sparcv9)
++ return "/lib64/ld-linux.so.2";
+ else
+ return "/lib64/ld-linux-x86-64.so.2";
+ }
+Index: tools/clang/test/Driver/linux-ld.c
+===================================================================
+--- tools/clang/test/Driver/linux-ld.c
++++ tools/clang/test/Driver/linux-ld.c
+@@ -389,6 +389,7 @@
+ // RUN: | FileCheck --check-prefix=CHECK-SPARCV8 %s
+ // CHECK-SPARCV8: "{{.*}}ld{{(.exe)?}}"
+ // CHECK-SPARCV8: "-m" "elf32_sparc"
++// CHECK-SPARCV8: "-dynamic-linker" "/lib/ld-linux.so.2"
+ //
+ // RUN: %clang %s -### -o %t.o 2>&1 \
+ // RUN: --target=sparcv9-linux-gnu \
+@@ -395,6 +396,7 @@
+ // RUN: | FileCheck --check-prefix=CHECK-SPARCV9 %s
+ // CHECK-SPARCV9: "{{.*}}ld{{(.exe)?}}"
+ // CHECK-SPARCV9: "-m" "elf64_sparc"
++// CHECK-SPARCV9: "-dynamic-linker" "/lib64/ld-linux.so.2"
+ //
+ // Thoroughly exercise the Debian multiarch environment.
+ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
diff --git a/contrib/llvm/patches/patch-r262262-clang-r199012-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r199012-sparc.diff
new file mode 100644
index 0000000..7bc4a78
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r199012-sparc.diff
@@ -0,0 +1,41 @@
+Pull in r199012 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ Select the UltraSPARC instruction set when invoking the assembler.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -6228,8 +6228,10 @@ void gnutools::Assemble::ConstructJob(Compilation
+ CmdArgs.push_back("-many");
+ } else if (getToolChain().getArch() == llvm::Triple::sparc) {
+ CmdArgs.push_back("-32");
++ CmdArgs.push_back("-Av8plusa");
+ } else if (getToolChain().getArch() == llvm::Triple::sparcv9) {
+ CmdArgs.push_back("-64");
++ CmdArgs.push_back("-Av9a");
+ } else if (getToolChain().getArch() == llvm::Triple::arm) {
+ StringRef MArch = getToolChain().getArchName();
+ if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
+Index: tools/clang/test/Driver/linux-as.c
+===================================================================
+--- tools/clang/test/Driver/linux-as.c
++++ tools/clang/test/Driver/linux-as.c
+@@ -65,6 +65,7 @@
+ // RUN: | FileCheck -check-prefix=CHECK-SPARCV9 %s
+ // CHECK-SPARCV9: as
+ // CHECK-SPARCV9: -64
++// CHECK-SPARCV9: -Av9a
+ // CHECK-SPARCV9: -o
+ //
+ // RUN: %clang -target sparc-linux -mcpu=invalid-cpu -### \
+@@ -72,6 +73,7 @@
+ // RUN: | FileCheck -check-prefix=CHECK-SPARCV8 %s
+ // CHECK-SPARCV8: as
+ // CHECK-SPARCV8: -32
++// CHECK-SPARCV8: -Av8plusa
+ // CHECK-SPARCV8: -o
+ //
+ // RUN: %clang -target s390x-linux -### -no-integrated-as -c %s 2>&1 \
diff --git a/contrib/llvm/patches/patch-r262262-clang-r199034-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r199034-sparc.diff
new file mode 100644
index 0000000..8043e1f
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r199034-sparc.diff
@@ -0,0 +1,81 @@
+Pull in r199034 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ MIPS and SPARC assemblers both take the -KPIC flag.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -6207,6 +6207,7 @@ void gnutools::Assemble::ConstructJob(Compilation
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ ArgStringList CmdArgs;
++ bool NeedsKPIC = false;
+
+ // Add --32/--64 to make sure we get the format we want.
+ // This is incomplete
+@@ -6229,9 +6230,11 @@ void gnutools::Assemble::ConstructJob(Compilation
+ } else if (getToolChain().getArch() == llvm::Triple::sparc) {
+ CmdArgs.push_back("-32");
+ CmdArgs.push_back("-Av8plusa");
++ NeedsKPIC = true;
+ } else if (getToolChain().getArch() == llvm::Triple::sparcv9) {
+ CmdArgs.push_back("-64");
+ CmdArgs.push_back("-Av9a");
++ NeedsKPIC = true;
+ } else if (getToolChain().getArch() == llvm::Triple::arm) {
+ StringRef MArch = getToolChain().getArchName();
+ if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
+@@ -6291,6 +6294,15 @@ void gnutools::Assemble::ConstructJob(Compilation
+ CmdArgs.push_back(Args.MakeArgString("-mmsa"));
+ }
+
++ NeedsKPIC = true;
++ } else if (getToolChain().getArch() == llvm::Triple::systemz) {
++ // Always pass an -march option, since our default of z10 is later
++ // than the GNU assembler's default.
++ StringRef CPUName = getSystemZTargetCPU(Args);
++ CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
++ }
++
++ if (NeedsKPIC) {
+ Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+ options::OPT_fpic, options::OPT_fno_pic,
+ options::OPT_fPIE, options::OPT_fno_PIE,
+@@ -6302,11 +6314,6 @@ void gnutools::Assemble::ConstructJob(Compilation
+ LastPICArg->getOption().matches(options::OPT_fpie))) {
+ CmdArgs.push_back("-KPIC");
+ }
+- } else if (getToolChain().getArch() == llvm::Triple::systemz) {
+- // Always pass an -march option, since our default of z10 is later
+- // than the GNU assembler's default.
+- StringRef CPUName = getSystemZTargetCPU(Args);
+- CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
+ }
+
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+Index: tools/clang/test/Driver/linux-as.c
+===================================================================
+--- tools/clang/test/Driver/linux-as.c
++++ tools/clang/test/Driver/linux-as.c
+@@ -66,8 +66,18 @@
+ // CHECK-SPARCV9: as
+ // CHECK-SPARCV9: -64
+ // CHECK-SPARCV9: -Av9a
++// CHECK-SPARCV9-NOT: -KPIC
+ // CHECK-SPARCV9: -o
+ //
++// RUN: %clang -target sparc64-linux -mcpu=invalid-cpu -### \
++// RUN: -no-integrated-as -fpic -c %s 2>&1 \
++// RUN: | FileCheck -check-prefix=CHECK-SPARCV9PIC %s
++// CHECK-SPARCV9PIC: as
++// CHECK-SPARCV9PIC: -64
++// CHECK-SPARCV9PIC: -Av9a
++// CHECK-SPARCV9PIC: -KPIC
++// CHECK-SPARCV9PIC: -o
++//
+ // RUN: %clang -target sparc-linux -mcpu=invalid-cpu -### \
+ // RUN: -no-integrated-as -c %s 2>&1 \
+ // RUN: | FileCheck -check-prefix=CHECK-SPARCV8 %s
diff --git a/contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff
new file mode 100644
index 0000000..beed0ed
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff
@@ -0,0 +1,53 @@
+Pull in r199037 from upstream clang trunk (by Jakob Stokund Olesen):
+
+ SPARC passes non-trivial C++ objects indirectly like everybody else.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/CodeGen/TargetInfo.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/TargetInfo.cpp
++++ tools/clang/lib/CodeGen/TargetInfo.cpp
+@@ -5349,6 +5349,11 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned
+ if (!isAggregateTypeForABI(Ty))
+ return ABIArgInfo::getDirect();
+
++ // If a C++ object has either a non-trivial copy constructor or a non-trivial
++ // destructor, it is passed with an explicit indirect pointer / sret pointer.
++ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
++ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
++
+ // This is a small aggregate type that should be passed in registers.
+ // Build a coercion type from the LLVM struct type.
+ llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
+Index: tools/clang/test/CodeGenCXX/sparcv9-abi.cpp
+===================================================================
+--- tools/clang/test/CodeGenCXX/sparcv9-abi.cpp
++++ tools/clang/test/CodeGenCXX/sparcv9-abi.cpp
+@@ -0,0 +1,26 @@
++// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
++
++struct pod {
++ int a, b;
++};
++
++void f0();
++void f1(struct pod);
++
++struct notpod {
++ int a, b;
++ ~notpod() { f0(); }
++};
++
++void f2(struct notpod);
++
++// CHECK-LABEL: caller
++// CHECK: call void @_Z2f13pod(i64
++// CHECK: call void @_Z2f26notpod(%struct.notpod*
++void caller()
++{
++ pod p1;
++ notpod p2;
++ f1(p1);
++ f2(p2);
++}
diff --git a/contrib/llvm/patches/patch-r262262-clang-r199188-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r199188-sparc.diff
new file mode 100644
index 0000000..77e5eaf
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r199188-sparc.diff
@@ -0,0 +1,35 @@
+Pull in r199188 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ Puny 24-byte structs are returned by value on SPARC.
+
+ Pad these structs up so they are sret-returned even on that
+ architecture.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/test/CodeGen/sret.c
+===================================================================
+--- tools/clang/test/CodeGen/sret.c
++++ tools/clang/test/CodeGen/sret.c
+@@ -4,6 +4,8 @@ struct abc {
+ long a;
+ long b;
+ long c;
++ long d;
++ long e;
+ };
+
+ struct abc foo1(void);
+Index: tools/clang/test/CodeGen/sret2.c
+===================================================================
+--- tools/clang/test/CodeGen/sret2.c
++++ tools/clang/test/CodeGen/sret2.c
+@@ -4,6 +4,8 @@ struct abc {
+ long a;
+ long b;
+ long c;
++ long d;
++ long e;
+ };
+
+ struct abc foo2(){}
diff --git a/contrib/llvm/patches/patch-r262262-clang-r199399-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r199399-sparc.diff
new file mode 100644
index 0000000..106ab89
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r199399-sparc.diff
@@ -0,0 +1,37 @@
+Pull in r199399 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ SPARCv9 implements long double as an IEEE quad.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/test/CodeGen/sparcv9-abi.c
+===================================================================
+--- tools/clang/test/CodeGen/sparcv9-abi.c
++++ tools/clang/test/CodeGen/sparcv9-abi.c
+@@ -18,6 +18,9 @@ long long f_int_3(long long x) { return x; }
+ // CHECK-LABEL: define signext i8 @f_int_4(i8 signext %x)
+ char f_int_4(char x) { return x; }
+
++// CHECK-LABEL: define fp128 @f_ld(fp128 %x)
++long double f_ld(long double x) { return x; }
++
+ // Small structs are passed in registers.
+ struct small {
+ int *a, *b;
+Index: tools/clang/lib/Basic/Targets.cpp
+===================================================================
+--- tools/clang/lib/Basic/Targets.cpp
++++ tools/clang/lib/Basic/Targets.cpp
+@@ -4529,6 +4529,12 @@ class SparcV9TargetInfo : public SparcTargetInfo {
+ UIntMaxType = UnsignedLong;
+ }
+ Int64Type = IntMaxType;
++
++ // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
++ // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
++ LongDoubleWidth = 128;
++ LongDoubleAlign = 128;
++ LongDoubleFormat = &llvm::APFloat::IEEEquad;
+ }
+
+ virtual void getTargetDefines(const LangOptions &Opts,
diff --git a/contrib/llvm/patches/patch-r262262-clang-r200452-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r200452-sparc.diff
new file mode 100644
index 0000000..e14306d
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262262-clang-r200452-sparc.diff
@@ -0,0 +1,20 @@
+Pull in r200452 from upstream clang trunk (by Jakob Stoklund Olesen):
+
+ SPARCv9 supports atomic operations up to 64 bits.
+
+ Patch by Roman Divacky!
+
+Introduced here: http://svn.freebsd.org/changeset/base/262262
+
+Index: tools/clang/lib/Basic/Targets.cpp
+===================================================================
+--- tools/clang/lib/Basic/Targets.cpp
++++ tools/clang/lib/Basic/Targets.cpp
+@@ -4535,6 +4535,7 @@ class SparcV9TargetInfo : public SparcTargetInfo {
+ LongDoubleWidth = 128;
+ LongDoubleAlign = 128;
+ LongDoubleFormat = &llvm::APFloat::IEEEquad;
++ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ }
+
+ virtual void getTargetDefines(const LangOptions &Opts,
diff --git a/contrib/llvm/patches/patch-r262264-llvm-r200453-sparc.diff b/contrib/llvm/patches/patch-r262264-llvm-r200453-sparc.diff
new file mode 100644
index 0000000..2c4470c
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262264-llvm-r200453-sparc.diff
@@ -0,0 +1,91 @@
+Pull in r200453 from upstream llvm trunk (by Jakob Stoklund Olesen):
+
+ Implement SPARCv9 atomic_swap_64 with a pseudo.
+
+ The SWAP instruction only exists in a 32-bit variant, but the 64-bit
+ atomic swap can be implemented in terms of CASX, like the other atomic
+ rmw primitives.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262264
+
+Index: lib/Target/Sparc/SparcInstr64Bit.td
+===================================================================
+--- lib/Target/Sparc/SparcInstr64Bit.td
++++ lib/Target/Sparc/SparcInstr64Bit.td
+@@ -463,6 +463,14 @@ defm ATOMIC_LOAD_MAX : AtomicRMW<atomic_load_max_
+ defm ATOMIC_LOAD_UMIN : AtomicRMW<atomic_load_umin_32, atomic_load_umin_64>;
+ defm ATOMIC_LOAD_UMAX : AtomicRMW<atomic_load_umax_32, atomic_load_umax_64>;
+
++// There is no 64-bit variant of SWAP, so use a pseudo.
++let usesCustomInserter = 1, hasCtrlDep = 1, mayLoad = 1, mayStore = 1,
++ Defs = [ICC], Predicates = [Is64Bit] in
++def ATOMIC_SWAP_64 : Pseudo<(outs I64Regs:$rd),
++ (ins ptr_rc:$addr, I64Regs:$rs2), "",
++ [(set i64:$rd,
++ (atomic_swap_64 iPTR:$addr, i64:$rs2))]>;
++
+ // Global addresses, constant pool entries
+ let Predicates = [Is64Bit] in {
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1498,7 +1498,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+
+ if (Subtarget->is64Bit()) {
+ setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, Legal);
+- setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Expand);
++ setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Legal);
+ setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Custom);
+ setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Custom);
+ }
+@@ -2885,6 +2885,9 @@ SparcTargetLowering::EmitInstrWithCustomInserter(M
+ case SP::ATOMIC_LOAD_NAND_64:
+ return expandAtomicRMW(MI, BB, SP::ANDXrr);
+
++ case SP::ATOMIC_SWAP_64:
++ return expandAtomicRMW(MI, BB, 0);
++
+ case SP::ATOMIC_LOAD_MAX_32:
+ return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_G);
+ case SP::ATOMIC_LOAD_MAX_64:
+@@ -3023,7 +3026,8 @@ SparcTargetLowering::expandAtomicRMW(MachineInstr
+
+ // Build the loop block.
+ unsigned ValReg = MRI.createVirtualRegister(ValueRC);
+- unsigned UpdReg = MRI.createVirtualRegister(ValueRC);
++ // Opcode == 0 means try to write Rs2Reg directly (ATOMIC_SWAP).
++ unsigned UpdReg = (Opcode ? MRI.createVirtualRegister(ValueRC) : Rs2Reg);
+
+ BuildMI(LoopMBB, DL, TII.get(SP::PHI), ValReg)
+ .addReg(Val0Reg).addMBB(MBB)
+@@ -3035,7 +3039,7 @@ SparcTargetLowering::expandAtomicRMW(MachineInstr
+ BuildMI(LoopMBB, DL, TII.get(SP::CMPrr)).addReg(ValReg).addReg(Rs2Reg);
+ BuildMI(LoopMBB, DL, TII.get(Opcode), UpdReg)
+ .addReg(ValReg).addReg(Rs2Reg).addImm(CondCode);
+- } else {
++ } else if (Opcode) {
+ BuildMI(LoopMBB, DL, TII.get(Opcode), UpdReg)
+ .addReg(ValReg).addReg(Rs2Reg);
+ }
+Index: test/CodeGen/SPARC/atomics.ll
+===================================================================
+--- test/CodeGen/SPARC/atomics.ll
++++ test/CodeGen/SPARC/atomics.ll
+@@ -62,6 +62,15 @@ entry:
+ ret i32 %b
+ }
+
++; CHECK-LABEL: test_swap_i64
++; CHECK: casx [%o1],
++
++define i64 @test_swap_i64(i64 %a, i64* %ptr) {
++entry:
++ %b = atomicrmw xchg i64* %ptr, i64 42 monotonic
++ ret i64 %b
++}
++
+ ; CHECK-LABEL: test_load_add_32
+ ; CHECK: membar
+ ; CHECK: add [[V:%[gilo][0-7]]], %o1, [[U:%[gilo][0-7]]]
diff --git a/contrib/llvm/patches/patch-r262265-llvm-r201718-sparc.diff b/contrib/llvm/patches/patch-r262265-llvm-r201718-sparc.diff
new file mode 100644
index 0000000..d9ca427
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262265-llvm-r201718-sparc.diff
@@ -0,0 +1,40 @@
+Pull in r201718 from upstream llvm trunk (by Roman Divacky):
+
+ Expand 64bit {SHL,SHR,SRA}_PARTS on sparcv9.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262265
+
+Index: test/CodeGen/SPARC/parts.ll
+===================================================================
+--- test/CodeGen/SPARC/parts.ll
++++ test/CodeGen/SPARC/parts.ll
+@@ -0,0 +1,14 @@
++; RUN: llc < %s -march=sparcv9 | FileCheck %s
++
++; CHECK-LABEL: test
++; CHECK: srl %i1, 0, %o2
++; CHECK-NEXT: or %g0, %i2, %o0
++; CHECK-NEXT: call __ashlti3
++; CHECK-NEXT: or %g0, %i3, %o1
++; CHECK-NEXT: or %g0, %o0, %i0
++
++define i128 @test(i128 %a, i128 %b) {
++entry:
++ %tmp = shl i128 %b, %a
++ ret i128 %tmp
++}
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1554,6 +1554,10 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+
+ setOperationAction(ISD::UMULO, MVT::i64, Custom);
+ setOperationAction(ISD::SMULO, MVT::i64, Custom);
++
++ setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
++ setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
++ setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand);
+ }
+
+ // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
diff --git a/contrib/llvm/patches/patch-r262303-enable-ppc-integrated-as.diff b/contrib/llvm/patches/patch-r262303-enable-ppc-integrated-as.diff
new file mode 100644
index 0000000..3d2e107
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262303-enable-ppc-integrated-as.diff
@@ -0,0 +1,25 @@
+Pull in r197521 from upstream clang trunk (by Roman Divacky):
+
+ Use the integrated assembler by default on FreeBSD/ppc and ppc64.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262303
+
+Index: tools/clang/lib/Driver/ToolChains.h
+===================================================================
+--- tools/clang/lib/Driver/ToolChains.h
++++ tools/clang/lib/Driver/ToolChains.h
+@@ -512,8 +512,13 @@ class LLVM_LIBRARY_VISIBILITY FreeBSD : public Gen
+ virtual void
+ AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
++ virtual bool IsIntegratedAssemblerDefault() const {
++ if (getTriple().getArch() == llvm::Triple::ppc ||
++ getTriple().getArch() == llvm::Triple::ppc64)
++ return true;
++ return Generic_ELF::IsIntegratedAssemblerDefault();
++ }
+
+-
+ virtual bool UseSjLjExceptions() const;
+ protected:
+ virtual Tool *buildAssembler() const;
diff --git a/contrib/llvm/patches/patch-r262415-llvm-r201994-sparc.diff b/contrib/llvm/patches/patch-r262415-llvm-r201994-sparc.diff
new file mode 100644
index 0000000..4f9b916
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262415-llvm-r201994-sparc.diff
@@ -0,0 +1,49 @@
+Pull in r201994 from upstream llvm trunk (by Benjamin Kramer):
+
+ SPARC: Implement TRAP lowering. Matches what GCC emits.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262415
+
+Index: lib/Target/Sparc/SparcInstrInfo.td
+===================================================================
+--- lib/Target/Sparc/SparcInstrInfo.td
++++ lib/Target/Sparc/SparcInstrInfo.td
+@@ -312,6 +312,9 @@ let hasSideEffects = 1, mayStore = 1 in {
+ [(flushw)]>;
+ }
+
++let isBarrier = 1, isTerminator = 1, rd = 0b1000, rs1 = 0, simm13 = 5 in
++ def TA5 : F3_2<0b10, 0b111010, (outs), (ins), "ta 5", [(trap)]>;
++
+ let rd = 0 in
+ def UNIMP : F2_1<0b000, (outs), (ins i32imm:$val),
+ "unimp $val", []>;
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -1565,6 +1565,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
+ // VAARG needs to be lowered to not do unaligned accesses for doubles.
+ setOperationAction(ISD::VAARG , MVT::Other, Custom);
+
++ setOperationAction(ISD::TRAP , MVT::Other, Legal);
++
+ // Use the default implementation.
+ setOperationAction(ISD::VACOPY , MVT::Other, Expand);
+ setOperationAction(ISD::VAEND , MVT::Other, Expand);
+Index: test/CodeGen/SPARC/trap.ll
+===================================================================
+--- test/CodeGen/SPARC/trap.ll
++++ test/CodeGen/SPARC/trap.ll
+@@ -0,0 +1,11 @@
++; RUN: llc -mtriple=sparc-linux-gnu < %s -show-mc-encoding | FileCheck %s
++
++define void @test1() {
++ tail call void @llvm.trap()
++ unreachable
++
++; CHECK-LABEL: test1:
++; CHECK: ta 5 ! encoding: [0x91,0xd0,0x20,0x05]
++}
++
++declare void @llvm.trap()
diff --git a/contrib/llvm/patches/patch-r262460-llvm-r202059-sparc.diff b/contrib/llvm/patches/patch-r262460-llvm-r202059-sparc.diff
new file mode 100644
index 0000000..e683e33
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262460-llvm-r202059-sparc.diff
@@ -0,0 +1,62 @@
+Pull in r202059 from upstream clang trunk (by Roman Divacky):
+
+ Implement getDwarfEHStackPointer() and initDwarfEHRegSizeTable() for sparcv9.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262460
+
+Index: tools/clang/lib/CodeGen/TargetInfo.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/TargetInfo.cpp
++++ tools/clang/lib/CodeGen/TargetInfo.cpp
+@@ -5435,10 +5435,51 @@ class SparcV9TargetCodeGenInfo : public TargetCode
+ public:
+ SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
+ : TargetCodeGenInfo(new SparcV9ABIInfo(CGT)) {}
++
++ int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
++ return 14;
++ }
++
++ bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
++ llvm::Value *Address) const;
+ };
+ } // end anonymous namespace
+
++bool
++SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
++ llvm::Value *Address) const {
++ // This is calculated from the LLVM and GCC tables and verified
++ // against gcc output. AFAIK all ABIs use the same encoding.
+
++ CodeGen::CGBuilderTy &Builder = CGF.Builder;
++
++ llvm::IntegerType *i8 = CGF.Int8Ty;
++ llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
++ llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
++
++ // 0-31: the 8-byte general-purpose registers
++ AssignToArrayRange(Builder, Address, Eight8, 0, 31);
++
++ // 32-63: f0-31, the 4-byte floating-point registers
++ AssignToArrayRange(Builder, Address, Four8, 32, 63);
++
++ // Y = 64
++ // PSR = 65
++ // WIM = 66
++ // TBR = 67
++ // PC = 68
++ // NPC = 69
++ // FSR = 70
++ // CSR = 71
++ AssignToArrayRange(Builder, Address, Eight8, 64, 71);
++
++ // 72-87: d0-15, the 8-byte floating-point registers
++ AssignToArrayRange(Builder, Address, Eight8, 72, 87);
++
++ return false;
++}
++
++
+ //===----------------------------------------------------------------------===//
+ // Xcore ABI Implementation
+ //===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/patches/patch-r262535-clang-r202177-sparc.diff b/contrib/llvm/patches/patch-r262535-clang-r202177-sparc.diff
new file mode 100644
index 0000000..00514eb
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262535-clang-r202177-sparc.diff
@@ -0,0 +1,84 @@
+Pull in r202177 from upstream clang trunk (by Roman Divacky):
+
+ Give sparcv9 the ability to set the target cpu. Change it from accepting
+ -march which doesnt exist on sparc gcc to -mcpu. While here adjust a
+ few tests to not write an unused temporary file.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262535
+
+Index: tools/clang/lib/Basic/Targets.cpp
+===================================================================
+--- tools/clang/lib/Basic/Targets.cpp
++++ tools/clang/lib/Basic/Targets.cpp
+@@ -4552,6 +4552,22 @@ class SparcV9TargetInfo : public SparcTargetInfo {
+ Builder.defineMacro("__sparcv9__");
+ }
+ }
++
++ virtual bool setCPU(const std::string &Name) {
++ bool CPUKnown = llvm::StringSwitch<bool>(Name)
++ .Case("v9", true)
++ .Case("ultrasparc", true)
++ .Case("ultrasparc3", true)
++ .Case("niagara", true)
++ .Case("niagara2", true)
++ .Case("niagara3", true)
++ .Case("niagara4", true)
++ .Default(false);
++
++ // No need to store the CPU yet. There aren't any CPU-specific
++ // macros to define.
++ return CPUKnown;
++ }
+ };
+
+ } // end anonymous namespace.
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -1373,7 +1373,8 @@ static std::string getCPUName(const ArgList &Args,
+ }
+
+ case llvm::Triple::sparc:
+- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
++ case llvm::Triple::sparcv9:
++ if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+ return A->getValue();
+ return "";
+
+Index: tools/clang/test/Driver/freebsd.c
+===================================================================
+--- tools/clang/test/Driver/freebsd.c
++++ tools/clang/test/Driver/freebsd.c
+@@ -59,13 +59,13 @@
+ // CHECK-MIPSEL: "{{[^" ]*}}ld{{[^" ]*}}"
+ // CHECK-MIPSEL: "-dynamic-linker" "{{.*}}/libexec/ld-elf.so.1"
+ // CHECK-MIPSEL-NOT: "--hash-style={{gnu|both}}"
+-// RUN: %clang %s -### -o %t.o 2>&1 \
++// RUN: %clang %s -### 2>&1 \
+ // RUN: -target mips64-unknown-freebsd10.0 \
+ // RUN: | FileCheck --check-prefix=CHECK-MIPS64 %s
+ // CHECK-MIPS64: "{{[^" ]*}}ld{{[^" ]*}}"
+ // CHECK-MIPS64: "-dynamic-linker" "{{.*}}/libexec/ld-elf.so.1"
+ // CHECK-MIPS64-NOT: "--hash-style={{gnu|both}}"
+-// RUN: %clang %s -### -o %t.o 2>&1 \
++// RUN: %clang %s -### 2>&1 \
+ // RUN: -target mips64el-unknown-freebsd10.0 \
+ // RUN: | FileCheck --check-prefix=CHECK-MIPS64EL %s
+ // CHECK-MIPS64EL: "{{[^" ]*}}ld{{[^" ]*}}"
+@@ -97,12 +97,12 @@
+ // CHECK-NORMAL: crt1.o
+ // CHECK-NORMAL: crtbegin.o
+
+-// RUN: %clang %s -### -o %t.o -target arm-unknown-freebsd10.0 2>&1 \
++// RUN: %clang %s -### -target arm-unknown-freebsd10.0 2>&1 \
+ // RUN: | FileCheck --check-prefix=CHECK-ARM %s
+ // CHECK-ARM: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions"
+ // CHECK-ARM: as{{.*}}" "-mfpu=softvfp"{{.*}}"-matpcs"
+
+-// RUN: %clang %s -### -o %t.o -target arm-gnueabi-freebsd10.0 2>&1 \
++// RUN: %clang %s -### -target arm-gnueabi-freebsd10.0 2>&1 \
+ // RUN: | FileCheck --check-prefix=CHECK-ARM-EABI %s
+ // CHECK-ARM-EABI-NOT: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions"
+ // CHECK-ARM-EABI: as{{.*}}" "-mfpu=softvfp" "-meabi=5"
diff --git a/contrib/llvm/patches/patch-r262536-clang-r202179-sparc.diff b/contrib/llvm/patches/patch-r262536-clang-r202179-sparc.diff
new file mode 100644
index 0000000..5912dac
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262536-clang-r202179-sparc.diff
@@ -0,0 +1,22 @@
+Pull in r202179 from upstream clang trunk (by Roman Divacky):
+
+ Pass the sparc architecture variant to the assembler.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262536
+
+Index: tools/clang/lib/Driver/Tools.cpp
+===================================================================
+--- tools/clang/lib/Driver/Tools.cpp
++++ tools/clang/lib/Driver/Tools.cpp
+@@ -5788,6 +5788,11 @@ void freebsd::Assemble::ConstructJob(Compilation &
+ }
+ } else if (getToolChain().getArch() == llvm::Triple::sparc ||
+ getToolChain().getArch() == llvm::Triple::sparcv9) {
++ if (getToolChain().getArch() == llvm::Triple::sparc)
++ CmdArgs.push_back("-Av8plusa");
++ else
++ CmdArgs.push_back("-Av9a");
++
+ Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+ options::OPT_fpic, options::OPT_fno_pic,
+ options::OPT_fPIE, options::OPT_fno_PIE,
diff --git a/contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff b/contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff
new file mode 100644
index 0000000..589dd47
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262582-llvm-r202422-sparc.diff
@@ -0,0 +1,89 @@
+Pull in r202422 from upstream llvm trunk (by Roman Divacky):
+
+ Lower FNEG just like FABS to fneg[ds] and fmov[ds], thus avoiding
+ expensive libcall. Also, Qp_neg is not implemented on at least
+ FreeBSD. This is also what gcc is doing.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262582
+
+Index: lib/Target/Sparc/SparcISelLowering.cpp
+===================================================================
+--- lib/Target/Sparc/SparcISelLowering.cpp
++++ lib/Target/Sparc/SparcISelLowering.cpp
+@@ -2643,24 +2643,16 @@ static SDValue LowerF128Store(SDValue Op, Selectio
+ &OutChains[0], 2);
+ }
+
+-static SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG,
+- const SparcTargetLowering &TLI,
+- bool is64Bit) {
+- if (Op.getValueType() == MVT::f64)
+- return LowerF64Op(Op, DAG, ISD::FNEG);
+- if (Op.getValueType() == MVT::f128)
+- return TLI.LowerF128Op(Op, DAG, ((is64Bit) ? "_Qp_neg" : "_Q_neg"), 1);
+- return Op;
+-}
++static SDValue LowerFNEGorFABS(SDValue Op, SelectionDAG &DAG, bool isV9) {
++ assert((Op.getOpcode() == ISD::FNEG || Op.getOpcode() == ISD::FABS) && "invalid");
+
+-static SDValue LowerFABS(SDValue Op, SelectionDAG &DAG, bool isV9) {
+ if (Op.getValueType() == MVT::f64)
+- return LowerF64Op(Op, DAG, ISD::FABS);
++ return LowerF64Op(Op, DAG, Op.getOpcode());
+ if (Op.getValueType() != MVT::f128)
+ return Op;
+
+- // Lower fabs on f128 to fabs on f64
+- // fabs f128 => fabs f64:sub_even64, fmov f64:sub_odd64
++ // Lower fabs/fneg on f128 to fabs/fneg on f64
++ // fabs/fneg f128 => fabs/fneg f64:sub_even64, fmov f64:sub_odd64
+
+ SDLoc dl(Op);
+ SDValue SrcReg128 = Op.getOperand(0);
+@@ -2671,7 +2663,7 @@ static SDValue LowerF128Store(SDValue Op, Selectio
+ if (isV9)
+ Hi64 = DAG.getNode(Op.getOpcode(), dl, MVT::f64, Hi64);
+ else
+- Hi64 = LowerF64Op(Hi64, DAG, ISD::FABS);
++ Hi64 = LowerF64Op(Hi64, DAG, Op.getOpcode());
+
+ SDValue DstReg128 = SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF,
+ dl, MVT::f128), 0);
+@@ -2792,7 +2784,6 @@ SDValue SparcTargetLowering::
+ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
+
+ bool hasHardQuad = Subtarget->hasHardQuad();
+- bool is64Bit = Subtarget->is64Bit();
+ bool isV9 = Subtarget->isV9();
+
+ switch (Op.getOpcode()) {
+@@ -2835,8 +2826,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
+ getLibcallName(RTLIB::DIV_F128), 2);
+ case ISD::FSQRT: return LowerF128Op(Op, DAG,
+ getLibcallName(RTLIB::SQRT_F128),1);
+- case ISD::FNEG: return LowerFNEG(Op, DAG, *this, is64Bit);
+- case ISD::FABS: return LowerFABS(Op, DAG, isV9);
++ case ISD::FABS:
++ case ISD::FNEG: return LowerFNEGorFABS(Op, DAG, isV9);
+ case ISD::FP_EXTEND: return LowerF128_FPEXTEND(Op, DAG, *this);
+ case ISD::FP_ROUND: return LowerF128_FPROUND(Op, DAG, *this);
+ case ISD::ADDC:
+Index: test/CodeGen/SPARC/fp128.ll
+===================================================================
+--- test/CodeGen/SPARC/fp128.ll
++++ test/CodeGen/SPARC/fp128.ll
+@@ -232,3 +232,14 @@ entry:
+ store i32 %3, i32* %4, align 8
+ ret void
+ }
++
++; SOFT-LABEL: f128_neg
++; SOFT: fnegs
++
++define void @f128_neg(fp128* noalias sret %scalar.result, fp128* byval %a) {
++entry:
++ %0 = load fp128* %a, align 8
++ %1 = fsub fp128 0xL00000000000000008000000000000000, %0
++ store fp128 %1, fp128* %scalar.result, align 8
++ ret void
++}
diff --git a/contrib/llvm/patches/patch-r262611-llvm-r196874-fix-invalid-pwd-crash.diff b/contrib/llvm/patches/patch-r262611-llvm-r196874-fix-invalid-pwd-crash.diff
new file mode 100644
index 0000000..587693d
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262611-llvm-r196874-fix-invalid-pwd-crash.diff
@@ -0,0 +1,76 @@
+Pull in r196874 from upstream llvm trunk (by Andrew Trick):
+
+ Fix a crash that occurs when PWD is invalid.
+
+ MCJIT needs to be able to run in hostile environments, even when PWD
+ is invalid. There's no need to crash MCJIT in this case.
+
+ The obvious fix is to simply leave MCContext's CompilationDir empty
+ when PWD can't be determined. This way, MCJIT clients,
+ and other clients that link with LLVM don?\226?\128?\153t need a valid working directory.
+
+ If we do want to guarantee valid CompilationDir, that should be done
+ only for clients of getCompilationDir(). This is as simple as checking
+ for an empty string.
+
+ The only current use of getCompilationDir is EmitGenDwarfInfo, which
+ won?\226?\128?\153t conceivably run with an invalid working dir. However, in the
+ purely hypothetically and untestable case that this happens, the
+ AT_comp_dir will be omitted from the compilation_unit DIE.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262611
+
+Index: include/llvm/MC/MCContext.h
+===================================================================
+--- include/llvm/MC/MCContext.h
++++ include/llvm/MC/MCContext.h
+@@ -278,6 +278,7 @@ namespace llvm {
+ /// This can be overridden by clients which want to control the reported
+ /// compilation directory and have it be something other than the current
+ /// working directory.
++ /// Returns an empty string if the current directory cannot be determined.
+ StringRef getCompilationDir() const { return CompilationDir; }
+
+ /// \brief Set the compilation directory for DW_AT_comp_dir
+Index: lib/MC/MCContext.cpp
+===================================================================
+--- lib/MC/MCContext.cpp
++++ lib/MC/MCContext.cpp
+@@ -47,8 +47,8 @@ MCContext::MCContext(const MCAsmInfo *mai, const M
+ AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) {
+
+ error_code EC = llvm::sys::fs::current_path(CompilationDir);
+- assert(!EC && "Could not determine the current directory");
+- (void)EC;
++ if (EC)
++ CompilationDir.clear();
+
+ MachOUniquingMap = 0;
+ ELFUniquingMap = 0;
+Index: lib/MC/MCDwarf.cpp
+===================================================================
+--- lib/MC/MCDwarf.cpp
++++ lib/MC/MCDwarf.cpp
+@@ -467,7 +467,8 @@ static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
+ EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
+ EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
+ EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
+- EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
++ if (!context.getCompilationDir().empty())
++ EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
+ StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
+ if (!DwarfDebugFlags.empty())
+ EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
+@@ -643,8 +644,10 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
+ MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
+
+ // AT_comp_dir, the working directory the assembly was done in.
+- MCOS->EmitBytes(context.getCompilationDir());
+- MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
++ if (!context.getCompilationDir().empty()) {
++ MCOS->EmitBytes(context.getCompilationDir());
++ MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
++ }
+
+ // AT_APPLE_flags, the command line arguments of the assembler tool.
+ StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
diff --git a/contrib/llvm/patches/patch-r262809-clang-r203007-destructor-calling-conv.diff b/contrib/llvm/patches/patch-r262809-clang-r203007-destructor-calling-conv.diff
new file mode 100644
index 0000000..5341b8b
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262809-clang-r203007-destructor-calling-conv.diff
@@ -0,0 +1,61 @@
+Pull in r203007 from upstream clang trunk (by Rafael Espindola):
+
+ Don't produce an alias between destructors with different calling conventions.
+
+ Fixes pr19007.
+
+Introduced here: http://svn.freebsd.org/changeset/base/262809
+
+Index: tools/clang/lib/CodeGen/CGCXX.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/CGCXX.cpp
++++ tools/clang/lib/CodeGen/CGCXX.cpp
+@@ -92,7 +92,13 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(c
+ if (!ClassLayout.getBaseClassOffset(UniqueBase).isZero())
+ return true;
+
++ // Give up if the calling conventions don't match. We could update the call,
++ // but it is probably not worth it.
+ const CXXDestructorDecl *BaseD = UniqueBase->getDestructor();
++ if (BaseD->getType()->getAs<FunctionType>()->getCallConv() !=
++ D->getType()->getAs<FunctionType>()->getCallConv())
++ return true;
++
+ return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base),
+ GlobalDecl(BaseD, Dtor_Base),
+ false);
+Index: tools/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
+===================================================================
+--- tools/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
++++ tools/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
+@@ -1,5 +1,5 @@
+-// RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
+-// RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
++// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
++// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
+
+ // RUN: %clang_cc1 -cc1 -triple x86_64--netbsd -emit-llvm \
+ // RUN: -mconstructor-aliases -O2 %s -o - | FileCheck --check-prefix=CHECK-RAUW %s
+@@ -133,6 +133,22 @@ namespace test8 {
+ zed foo;
+ }
+
++namespace test9 {
++struct foo {
++ __attribute__((stdcall)) ~foo() {
++ }
++};
++
++struct bar : public foo {};
++
++void zed() {
++ // Test that we produce a call to bar's destructor. We used to call foo's, but
++ // it has a different calling conversion.
++ // CHECK-DAG: call void @_ZN5test93barD2Ev
++ bar ptr;
++}
++}
++
+ // CHECK-RAUW: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
+ // r194296 replaced C::~C with B::~B without emitting the later.
+
diff --git a/contrib/llvm/patches/patch-r263048-clang-r203624-fix-CC-aliases.diff b/contrib/llvm/patches/patch-r263048-clang-r203624-fix-CC-aliases.diff
new file mode 100644
index 0000000..1aac8cb
--- /dev/null
+++ b/contrib/llvm/patches/patch-r263048-clang-r203624-fix-CC-aliases.diff
@@ -0,0 +1,24 @@
+Pull in r203624 from upstream clang trunk (by Hans Wennborg):
+
+ Be case sensitive when determining driver mode based on argv[0] except on Windows
+
+ This narrows the impact of r188833 after Dimitry pointed out that it's good to be
+ able to tell the difference between 'cc' and 'CC'.
+
+Introduced here: http://svn.freebsd.org/changeset/base/263048
+
+Index: tools/clang/tools/driver/driver.cpp
+===================================================================
+--- tools/clang/tools/driver/driver.cpp
++++ tools/clang/tools/driver/driver.cpp
+@@ -229,8 +229,10 @@ static void ParseProgName(SmallVectorImpl<const ch
+ { "++", "--driver-mode=g++" },
+ };
+ std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
++#ifdef _WIN32
+ std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
+ toLowercase);
++#endif
+ StringRef ProgNameRef(ProgName);
+ StringRef Prefix;
+
diff --git a/contrib/llvm/patches/patch-r263312-llvm-r169939-inline-asm-with-realign.diff b/contrib/llvm/patches/patch-r263312-llvm-r169939-inline-asm-with-realign.diff
new file mode 100644
index 0000000..f92dd3a
--- /dev/null
+++ b/contrib/llvm/patches/patch-r263312-llvm-r169939-inline-asm-with-realign.diff
@@ -0,0 +1,338 @@
+Pull in r196939 from upstream llvm trunk (by Reid Kleckner):
+
+ Reland "Fix miscompile of MS inline assembly with stack realignment"
+
+ This re-lands commit r196876, which was reverted in r196879.
+
+ The tests have been fixed to pass on platforms with a stack alignment
+ larger than 4.
+
+ Update to clang side tests will land shortly.
+
+Introduced here: http://svn.freebsd.org/changeset/base/263312
+
+Index: test/CodeGen/X86/inline-asm-stack-realign2.ll
+===================================================================
+--- test/CodeGen/X86/inline-asm-stack-realign2.ll
++++ test/CodeGen/X86/inline-asm-stack-realign2.ll
+@@ -0,0 +1,15 @@
++; RUN: not llc -mtriple=i686-pc-win32 < %s 2>&1 | FileCheck %s
++
++; We don't currently support realigning the stack and adjusting the stack
++; pointer in inline asm. This can even happen in GNU asm.
++
++; CHECK: Stack realignment in presence of dynamic stack adjustments is not supported with inline assembly
++
++define i32 @foo() {
++entry:
++ %r = alloca i32, align 16
++ store i32 -1, i32* %r, align 16
++ call void asm sideeffect "push %esi\0A\09xor %esi, %esi\0A\09mov %esi, $0\0A\09pop %esi", "=*m,~{flags},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %r)
++ %0 = load i32* %r, align 16
++ ret i32 %0
++}
+Index: test/CodeGen/X86/inline-asm-stack-realign.ll
+===================================================================
+--- test/CodeGen/X86/inline-asm-stack-realign.ll
++++ test/CodeGen/X86/inline-asm-stack-realign.ll
+@@ -0,0 +1,16 @@
++; RUN: not llc -mtriple=i686-pc-win32 < %s 2>&1 | FileCheck %s
++
++; We don't currently support realigning the stack and adjusting the stack
++; pointer in inline asm. This commonly happens in MS inline assembly using
++; push and pop.
++
++; CHECK: Stack realignment in presence of dynamic stack adjustments is not supported with inline assembly
++
++define i32 @foo() {
++entry:
++ %r = alloca i32, align 16
++ store i32 -1, i32* %r, align 16
++ call void asm sideeffect inteldialect "push esi\0A\09xor esi, esi\0A\09mov dword ptr $0, esi\0A\09pop esi", "=*m,~{flags},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %r)
++ %0 = load i32* %r, align 16
++ ret i32 %0
++}
+Index: test/CodeGen/X86/ms-inline-asm.ll
+===================================================================
+--- test/CodeGen/X86/ms-inline-asm.ll
++++ test/CodeGen/X86/ms-inline-asm.ll
+@@ -5,7 +5,6 @@ entry:
+ %0 = tail call i32 asm sideeffect inteldialect "mov eax, $1\0A\09mov $0, eax", "=r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32 1) nounwind
+ ret i32 %0
+ ; CHECK: t1
+-; CHECK: movl %esp, %ebp
+ ; CHECK: {{## InlineAsm Start|#APP}}
+ ; CHECK: .intel_syntax
+ ; CHECK: mov eax, ecx
+@@ -19,7 +18,6 @@ entry:
+ call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+ ret void
+ ; CHECK: t2
+-; CHECK: movl %esp, %ebp
+ ; CHECK: {{## InlineAsm Start|#APP}}
+ ; CHECK: .intel_syntax
+ ; CHECK: mov eax, 1
+@@ -34,7 +32,6 @@ entry:
+ call void asm sideeffect inteldialect "mov eax, DWORD PTR [$0]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %V.addr) nounwind
+ ret void
+ ; CHECK: t3
+-; CHECK: movl %esp, %ebp
+ ; CHECK: {{## InlineAsm Start|#APP}}
+ ; CHECK: .intel_syntax
+ ; CHECK: mov eax, DWORD PTR {{[[esp]}}
+@@ -56,7 +53,6 @@ entry:
+ %0 = load i32* %b1, align 4
+ ret i32 %0
+ ; CHECK: t18
+-; CHECK: movl %esp, %ebp
+ ; CHECK: {{## InlineAsm Start|#APP}}
+ ; CHECK: .intel_syntax
+ ; CHECK: lea ebx, foo
+@@ -76,7 +72,6 @@ entry:
+ call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(void ()* @t19_helper) nounwind
+ ret void
+ ; CHECK-LABEL: t19:
+-; CHECK: movl %esp, %ebp
+ ; CHECK: movl ${{_?}}t19_helper, %eax
+ ; CHECK: {{## InlineAsm Start|#APP}}
+ ; CHECK: .intel_syntax
+@@ -95,7 +90,6 @@ entry:
+ %0 = load i32** %res, align 4
+ ret i32* %0
+ ; CHECK-LABEL: t30:
+-; CHECK: movl %esp, %ebp
+ ; CHECK: {{## InlineAsm Start|#APP}}
+ ; CHECK: .intel_syntax
+ ; CHECK: lea edi, dword ptr [{{_?}}results]
+@@ -103,8 +97,31 @@ entry:
+ ; CHECK: {{## InlineAsm End|#NO_APP}}
+ ; CHECK: {{## InlineAsm Start|#APP}}
+ ; CHECK: .intel_syntax
+-; CHECK: mov dword ptr [esi], edi
++; CHECK: mov dword ptr [esp], edi
+ ; CHECK: .att_syntax
+ ; CHECK: {{## InlineAsm End|#NO_APP}}
+-; CHECK: movl (%esi), %eax
++; CHECK: movl (%esp), %eax
+ }
++
++; Stack realignment plus MS inline asm that does *not* adjust the stack is no
++; longer an error.
++
++define i32 @t31() {
++entry:
++ %val = alloca i32, align 64
++ store i32 -1, i32* %val, align 64
++ call void asm sideeffect inteldialect "mov dword ptr $0, esp", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %val) #1
++ %sp = load i32* %val, align 64
++ ret i32 %sp
++; CHECK-LABEL: t31:
++; CHECK: pushl %ebp
++; CHECK: movl %esp, %ebp
++; CHECK: andl $-64, %esp
++; CHECK: {{## InlineAsm Start|#APP}}
++; CHECK: .intel_syntax
++; CHECK: mov dword ptr [esp], esp
++; CHECK: .att_syntax
++; CHECK: {{## InlineAsm End|#NO_APP}}
++; CHECK: movl (%esp), %eax
++; CHECK: ret
++}
+Index: include/llvm/CodeGen/MachineFrameInfo.h
+===================================================================
+--- include/llvm/CodeGen/MachineFrameInfo.h
++++ include/llvm/CodeGen/MachineFrameInfo.h
+@@ -223,6 +223,10 @@ class MachineFrameInfo {
+ /// Whether the "realign-stack" option is on.
+ bool RealignOption;
+
++ /// True if the function includes inline assembly that adjusts the stack
++ /// pointer.
++ bool HasInlineAsmWithSPAdjust;
++
+ const TargetFrameLowering *getFrameLowering() const;
+ public:
+ explicit MachineFrameInfo(const TargetMachine &TM, bool RealignOpt)
+@@ -451,6 +455,10 @@ class MachineFrameInfo {
+ bool hasCalls() const { return HasCalls; }
+ void setHasCalls(bool V) { HasCalls = V; }
+
++ /// Returns true if the function contains any stack-adjusting inline assembly.
++ bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; }
++ void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; }
++
+ /// getMaxCallFrameSize - Return the maximum size of a call frame that must be
+ /// allocated for an outgoing function call. This is only available if
+ /// CallFrameSetup/Destroy pseudo instructions are used by the target, and
+Index: include/llvm/CodeGen/MachineFunction.h
+===================================================================
+--- include/llvm/CodeGen/MachineFunction.h
++++ include/llvm/CodeGen/MachineFunction.h
+@@ -131,8 +131,8 @@ class MachineFunction {
+ /// about the control flow of such functions.
+ bool ExposesReturnsTwice;
+
+- /// True if the function includes MS-style inline assembly.
+- bool HasMSInlineAsm;
++ /// True if the function includes any inline assembly.
++ bool HasInlineAsm;
+
+ MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
+ void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
+@@ -218,15 +218,14 @@ class MachineFunction {
+ ExposesReturnsTwice = B;
+ }
+
+- /// Returns true if the function contains any MS-style inline assembly.
+- bool hasMSInlineAsm() const {
+- return HasMSInlineAsm;
++ /// Returns true if the function contains any inline assembly.
++ bool hasInlineAsm() const {
++ return HasInlineAsm;
+ }
+
+- /// Set a flag that indicates that the function contains MS-style inline
+- /// assembly.
+- void setHasMSInlineAsm(bool B) {
+- HasMSInlineAsm = B;
++ /// Set a flag that indicates that the function contains inline assembly.
++ void setHasInlineAsm(bool B) {
++ HasInlineAsm = B;
+ }
+
+ /// getInfo - Keep track of various per-function pieces of information for
+Index: lib/Target/X86/X86FrameLowering.cpp
+===================================================================
+--- lib/Target/X86/X86FrameLowering.cpp
++++ lib/Target/X86/X86FrameLowering.cpp
+@@ -50,7 +50,7 @@ bool X86FrameLowering::hasFP(const MachineFunction
+ return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
+ RegInfo->needsStackRealignment(MF) ||
+ MFI->hasVarSizedObjects() ||
+- MFI->isFrameAddressTaken() || MF.hasMSInlineAsm() ||
++ MFI->isFrameAddressTaken() || MFI->hasInlineAsmWithSPAdjust() ||
+ MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
+ MMI.callsUnwindInit() || MMI.callsEHReturn());
+ }
+Index: lib/Target/X86/X86RegisterInfo.cpp
+===================================================================
+--- lib/Target/X86/X86RegisterInfo.cpp
++++ lib/Target/X86/X86RegisterInfo.cpp
+@@ -347,6 +347,12 @@ BitVector X86RegisterInfo::getReservedRegs(const M
+ "Stack realignment in presence of dynamic allocas is not supported with"
+ "this calling convention.");
+
++ // FIXME: Do a proper analysis of the inline asm to see if it actually
++ // conflicts with the base register we chose.
++ if (MF.hasInlineAsm())
++ report_fatal_error("Stack realignment in presence of dynamic stack "
++ "adjustments is not supported with inline assembly.");
++
+ for (MCSubRegIterator I(getBaseRegister(), this, /*IncludeSelf=*/true);
+ I.isValid(); ++I)
+ Reserved.set(*I);
+@@ -403,18 +409,15 @@ bool X86RegisterInfo::hasBasePointer(const Machine
+ if (!EnableBasePointer)
+ return false;
+
+- // When we need stack realignment and there are dynamic allocas, we can't
+- // reference off of the stack pointer, so we reserve a base pointer.
+- //
+- // This is also true if the function contain MS-style inline assembly. We
+- // do this because if any stack changes occur in the inline assembly, e.g.,
+- // "pusha", then any C local variable or C argument references in the
+- // inline assembly will be wrong because the SP is not properly tracked.
+- if ((needsStackRealignment(MF) && MFI->hasVarSizedObjects()) ||
+- MF.hasMSInlineAsm())
+- return true;
+-
+- return false;
++ // When we need stack realignment, we can't address the stack from the frame
++ // pointer. When we have dynamic allocas or stack-adjusting inline asm, we
++ // can't address variables from the stack pointer. MS inline asm can
++ // reference locals while also adjusting the stack pointer. When we can't
++ // use both the SP and the FP, we need a separate base pointer register.
++ bool CantUseFP = needsStackRealignment(MF);
++ bool CantUseSP =
++ MFI->hasVarSizedObjects() || MFI->hasInlineAsmWithSPAdjust();
++ return CantUseFP && CantUseSP;
+ }
+
+ bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
+Index: lib/MC/MCParser/AsmParser.cpp
+===================================================================
+--- lib/MC/MCParser/AsmParser.cpp
++++ lib/MC/MCParser/AsmParser.cpp
+@@ -4192,6 +4192,11 @@ bool AsmParser::parseMSInlineAsm(
+ AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size()));
+ }
+ }
++
++ // Consider implicit defs to be clobbers. Think of cpuid and push.
++ const uint16_t *ImpDefs = Desc.getImplicitDefs();
++ for (unsigned I = 0, E = Desc.getNumImplicitDefs(); I != E; ++I)
++ ClobberRegs.push_back(ImpDefs[I]);
+ }
+
+ // Set the number of Outputs and Inputs.
+Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+===================================================================
+--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
++++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+@@ -851,12 +851,20 @@ void RegsForValue::AddInlineAsmOperands(unsigned C
+ SDValue Res = DAG.getTargetConstant(Flag, MVT::i32);
+ Ops.push_back(Res);
+
++ unsigned SP = TLI.getStackPointerRegisterToSaveRestore();
+ for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) {
+ unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), ValueVTs[Value]);
+ MVT RegisterVT = RegVTs[Value];
+ for (unsigned i = 0; i != NumRegs; ++i) {
+ assert(Reg < Regs.size() && "Mismatch in # registers expected");
+- Ops.push_back(DAG.getRegister(Regs[Reg++], RegisterVT));
++ unsigned TheReg = Regs[Reg++];
++ Ops.push_back(DAG.getRegister(TheReg, RegisterVT));
++
++ // Notice if we clobbered the stack pointer. Yes, inline asm can do this.
++ if (TheReg == SP && Code == InlineAsm::Kind_Clobber) {
++ MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
++ MFI->setHasInlineAsmWithSPAdjust(true);
++ }
+ }
+ }
+ }
+Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+===================================================================
+--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
++++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+@@ -428,7 +428,9 @@ bool SelectionDAGISel::runOnMachineFunction(Machin
+
+ SDB->init(GFI, *AA, LibInfo);
+
+- MF->setHasMSInlineAsm(false);
++ MF->setHasInlineAsm(false);
++ MF->getFrameInfo()->setHasInlineAsmWithSPAdjust(false);
++
+ SelectAllBasicBlocks(Fn);
+
+ // If the first basic block in the function has live ins that need to be
+@@ -511,7 +513,7 @@ bool SelectionDAGISel::runOnMachineFunction(Machin
+ for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E;
+ ++I) {
+
+- if (MFI->hasCalls() && MF->hasMSInlineAsm())
++ if (MFI->hasCalls() && MF->hasInlineAsm())
+ break;
+
+ const MachineBasicBlock *MBB = I;
+@@ -522,8 +524,8 @@ bool SelectionDAGISel::runOnMachineFunction(Machin
+ II->isStackAligningInlineAsm()) {
+ MFI->setHasCalls(true);
+ }
+- if (II->isMSInlineAsm()) {
+- MF->setHasMSInlineAsm(true);
++ if (II->isInlineAsm()) {
++ MF->setHasInlineAsm(true);
+ }
+ }
+ }
diff --git a/contrib/llvm/patches/patch-r263312-llvm-r196940-update-inline-asm-test.diff b/contrib/llvm/patches/patch-r263312-llvm-r196940-update-inline-asm-test.diff
new file mode 100644
index 0000000..6ce56cb
--- /dev/null
+++ b/contrib/llvm/patches/patch-r263312-llvm-r196940-update-inline-asm-test.diff
@@ -0,0 +1,78 @@
+Pull in r196940 from upstream clang trunk (by Reid Kleckner):
+
+ Update clang MS inline asm tests for r196939
+
+Introduced here: http://svn.freebsd.org/changeset/base/263312
+
+Index: tools/clang/test/CodeGen/ms-inline-asm.cpp
+===================================================================
+--- tools/clang/test/CodeGen/ms-inline-asm.cpp
++++ tools/clang/test/CodeGen/ms-inline-asm.cpp
+@@ -97,7 +97,7 @@ void test5() {
+ // CHECK: [[Y:%.*]] = alloca i32
+ int x, y;
+ __asm push y
+- // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[Y]])
++ // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* [[Y]])
+ __asm call T5<int>::create<float>
+ // CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(i32 (float)* @_ZN2T5IiE6createIfEEiT_)
+ __asm mov x, eax
+Index: tools/clang/test/CodeGen/ms-inline-asm.c
+===================================================================
+--- tools/clang/test/CodeGen/ms-inline-asm.c
++++ tools/clang/test/CodeGen/ms-inline-asm.c
+@@ -77,7 +77,7 @@ void t9() {
+ pop ebx
+ }
+ // CHECK: t9
+-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
++// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
+ }
+
+ unsigned t10(void) {
+@@ -211,7 +211,7 @@ void t21() {
+ __asm pop ebx
+ }
+ // CHECK: t21
+-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
++// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
+ }
+
+ extern void t22_helper(int x);
+@@ -227,7 +227,7 @@ void t22() {
+ __asm pop ebx
+ }
+ // CHECK: t22
+-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
++// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
+ // CHECK: call void @t22_helper
+ // CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
+ }
+@@ -268,13 +268,14 @@ void t26() {
+ __asm __emit 0a2h
+ __asm __EMIT 0a2h
+ __asm popad
++// FIXME: These all need to be merged into the same asm blob.
+ // CHECK: t26
+-// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"()
++// CHECK: call void asm sideeffect inteldialect "pushad", "~{esp},~{dirflag},~{fpsr},~{flags}"()
+ // CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ // CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"()
+ // CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
+ // CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
+-// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"()
++// CHECK: call void asm sideeffect inteldialect "popad", "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
+ }
+
+ void t27() {
+@@ -323,8 +324,8 @@ void t31() {
+ __asm pushad
+ __asm popad
+ // CHECK: t31
+-// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"()
+-// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"()
++// CHECK: call void asm sideeffect inteldialect "pushad", "~{esp},~{dirflag},~{fpsr},~{flags}"()
++// CHECK: call void asm sideeffect inteldialect "popad", "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
+ }
+
+ void t32() {
diff --git a/contrib/llvm/patches/patch-r263312-llvm-r196986-allow-realign-alloca.diff b/contrib/llvm/patches/patch-r263312-llvm-r196986-allow-realign-alloca.diff
new file mode 100644
index 0000000..2c0b759
--- /dev/null
+++ b/contrib/llvm/patches/patch-r263312-llvm-r196986-allow-realign-alloca.diff
@@ -0,0 +1,98 @@
+Pull in r196986 from upstream llvm trunk (by Reid Kleckner):
+
+ Revert the backend fatal error from r196939
+
+ The combination of inline asm, stack realignment, and dynamic allocas
+ turns out to be too common to reject out of hand.
+
+ ASan inserts empy inline asm fragments and uses aligned allocas.
+ Compiling any trivial function containing a dynamic alloca with ASan is
+ enough to trigger the check.
+
+ XFAIL the test cases that would be miscompiled and add one that uses the
+ relevant functionality.
+
+Introduced here: http://svn.freebsd.org/changeset/base/263312
+
+Index: lib/Target/X86/X86RegisterInfo.cpp
+===================================================================
+--- lib/Target/X86/X86RegisterInfo.cpp
++++ lib/Target/X86/X86RegisterInfo.cpp
+@@ -347,12 +347,6 @@ BitVector X86RegisterInfo::getReservedRegs(const M
+ "Stack realignment in presence of dynamic allocas is not supported with"
+ "this calling convention.");
+
+- // FIXME: Do a proper analysis of the inline asm to see if it actually
+- // conflicts with the base register we chose.
+- if (MF.hasInlineAsm())
+- report_fatal_error("Stack realignment in presence of dynamic stack "
+- "adjustments is not supported with inline assembly.");
+-
+ for (MCSubRegIterator I(getBaseRegister(), this, /*IncludeSelf=*/true);
+ I.isValid(); ++I)
+ Reserved.set(*I);
+Index: test/CodeGen/X86/inline-asm-stack-realign3.ll
+===================================================================
+--- test/CodeGen/X86/inline-asm-stack-realign3.ll
++++ test/CodeGen/X86/inline-asm-stack-realign3.ll
+@@ -0,0 +1,29 @@
++; RUN: llc -march=x86 < %s | FileCheck %s
++
++declare void @bar(i32* %junk)
++
++define i32 @foo(i1 %cond) {
++entry:
++ %r = alloca i32, align 128
++ store i32 -1, i32* %r, align 128
++ br i1 %cond, label %doit, label %skip
++
++doit:
++ call void asm sideeffect "xor %ecx, %ecx\0A\09mov %ecx, $0", "=*m,~{ecx},~{flags}"(i32* %r)
++ %junk = alloca i32
++ call void @bar(i32* %junk)
++ br label %skip
++
++skip:
++ %0 = load i32* %r, align 128
++ ret i32 %0
++}
++
++; CHECK-LABEL: foo:
++; CHECK: pushl %ebp
++; CHECK: andl $-128, %esp
++; CHECK: xor %ecx, %ecx
++; CHECK-NEXT: mov %ecx, (%esi)
++; CHECK: movl (%esi), %eax
++; CHECK: popl %ebp
++; CHECK: ret
+Index: test/CodeGen/X86/inline-asm-stack-realign.ll
+===================================================================
+--- test/CodeGen/X86/inline-asm-stack-realign.ll
++++ test/CodeGen/X86/inline-asm-stack-realign.ll
+@@ -1,8 +1,8 @@
+ ; RUN: not llc -mtriple=i686-pc-win32 < %s 2>&1 | FileCheck %s
+
+-; We don't currently support realigning the stack and adjusting the stack
+-; pointer in inline asm. This commonly happens in MS inline assembly using
+-; push and pop.
++; FIXME: This is miscompiled due to our unconditional use of ESI as the base
++; pointer.
++; XFAIL:
+
+ ; CHECK: Stack realignment in presence of dynamic stack adjustments is not supported with inline assembly
+
+Index: test/CodeGen/X86/inline-asm-stack-realign2.ll
+===================================================================
+--- test/CodeGen/X86/inline-asm-stack-realign2.ll
++++ test/CodeGen/X86/inline-asm-stack-realign2.ll
+@@ -1,7 +1,8 @@
+ ; RUN: not llc -mtriple=i686-pc-win32 < %s 2>&1 | FileCheck %s
+
+-; We don't currently support realigning the stack and adjusting the stack
+-; pointer in inline asm. This can even happen in GNU asm.
++; FIXME: This is miscompiled due to our unconditional use of ESI as the base
++; pointer.
++; XFAIL:
+
+ ; CHECK: Stack realignment in presence of dynamic stack adjustments is not supported with inline assembly
+
diff --git a/contrib/llvm/patches/patch-r263312-llvm-r202930-fix-alloca-esi-clobber.diff b/contrib/llvm/patches/patch-r263312-llvm-r202930-fix-alloca-esi-clobber.diff
new file mode 100644
index 0000000..b4017c9
--- /dev/null
+++ b/contrib/llvm/patches/patch-r263312-llvm-r202930-fix-alloca-esi-clobber.diff
@@ -0,0 +1,263 @@
+Pull in r202930 from upstream llvm trunk (by Hans Wennborg):
+
+ Check for dynamic allocas and inline asm that clobbers sp before building
+ selection dag (PR19012)
+
+ In X86SelectionDagInfo::EmitTargetCodeForMemcpy we check with MachineFrameInfo
+ to make sure that ESI isn't used as a base pointer register before we choose to
+ emit rep movs (which clobbers esi).
+
+ The problem is that MachineFrameInfo wouldn't know about dynamic allocas or
+ inline asm that clobbers the stack pointer until SelectionDAGBuilder has
+ encountered them.
+
+ This patch fixes the problem by checking for such things when building the
+ FunctionLoweringInfo.
+
+ Differential Revision: http://llvm-reviews.chandlerc.com/D2954
+
+Introduced here: http://svn.freebsd.org/changeset/base/263312
+
+Index: lib/CodeGen/MachineFunction.cpp
+===================================================================
+--- lib/CodeGen/MachineFunction.cpp
++++ lib/CodeGen/MachineFunction.cpp
+@@ -525,13 +525,14 @@ int MachineFrameInfo::CreateSpillStackObject(uint6
+ /// variable sized object is created, whether or not the index returned is
+ /// actually used.
+ ///
+-int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment) {
++int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment,
++ const AllocaInst *Alloca) {
+ HasVarSizedObjects = true;
+ Alignment =
+ clampStackAlignment(!getFrameLowering()->isStackRealignable() ||
+ !RealignOption,
+ Alignment, getFrameLowering()->getStackAlignment());
+- Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0));
++ Objects.push_back(StackObject(0, Alignment, 0, false, false, true, Alloca));
+ ensureMaxAlignment(Alignment);
+ return (int)Objects.size()-NumFixedObjects-1;
+ }
+Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+===================================================================
+--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
++++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+@@ -419,7 +419,7 @@ bool SelectionDAGISel::runOnMachineFunction(Machin
+ SplitCriticalSideEffectEdges(const_cast<Function&>(Fn), this);
+
+ CurDAG->init(*MF, TTI, TLI);
+- FuncInfo->set(Fn, *MF);
++ FuncInfo->set(Fn, *MF, CurDAG);
+
+ if (UseMBPI && OptLevel != CodeGenOpt::None)
+ FuncInfo->BPI = &getAnalysis<BranchProbabilityInfo>();
+@@ -429,7 +429,6 @@ bool SelectionDAGISel::runOnMachineFunction(Machin
+ SDB->init(GFI, *AA, LibInfo);
+
+ MF->setHasInlineAsm(false);
+- MF->getFrameInfo()->setHasInlineAsmWithSPAdjust(false);
+
+ SelectAllBasicBlocks(Fn);
+
+Index: lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+===================================================================
+--- lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
++++ lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+@@ -33,6 +33,7 @@
+ #include "llvm/Support/ErrorHandling.h"
+ #include "llvm/Support/MathExtras.h"
+ #include "llvm/Target/TargetInstrInfo.h"
++#include "llvm/Target/TargetFrameLowering.h"
+ #include "llvm/Target/TargetLowering.h"
+ #include "llvm/Target/TargetOptions.h"
+ #include "llvm/Target/TargetRegisterInfo.h"
+@@ -55,7 +56,8 @@ static bool isUsedOutsideOfDefiningBlock(const Ins
+ return false;
+ }
+
+-void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) {
++void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
++ SelectionDAG *DAG) {
+ const TargetLowering *TLI = TM.getTargetLowering();
+
+ Fn = &fn;
+@@ -100,6 +102,43 @@ static bool isUsedOutsideOfDefiningBlock(const Ins
+ for (; BB != EB; ++BB)
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+ I != E; ++I) {
++ // Look for dynamic allocas.
++ if (const AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
++ if (!AI->isStaticAlloca()) {
++ unsigned Align = std::max(
++ (unsigned)TLI->getDataLayout()->getPrefTypeAlignment(
++ AI->getAllocatedType()),
++ AI->getAlignment());
++ unsigned StackAlign = TM.getFrameLowering()->getStackAlignment();
++ if (Align <= StackAlign)
++ Align = 0;
++ // Inform the Frame Information that we have variable-sized objects.
++ MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1, AI);
++ }
++ }
++
++ // Look for inline asm that clobbers the SP register.
++ if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
++ ImmutableCallSite CS(I);
++ if (const InlineAsm *IA = dyn_cast<InlineAsm>(CS.getCalledValue())) {
++ unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
++ std::vector<TargetLowering::AsmOperandInfo> Ops =
++ TLI->ParseConstraints(CS);
++ for (size_t I = 0, E = Ops.size(); I != E; ++I) {
++ TargetLowering::AsmOperandInfo &Op = Ops[I];
++ if (Op.Type == InlineAsm::isClobber) {
++ // Clobbers don't have SDValue operands, hence SDValue().
++ TLI->ComputeConstraintToUse(Op, SDValue(), DAG);
++ std::pair<unsigned, const TargetRegisterClass*> PhysReg =
++ TLI->getRegForInlineAsmConstraint(Op.ConstraintCode,
++ Op.ConstraintVT);
++ if (PhysReg.first == SP)
++ MF->getFrameInfo()->setHasInlineAsmWithSPAdjust(true);
++ }
++ }
++ }
++ }
++
+ // Mark values used outside their block as exported, by allocating
+ // a virtual register for them.
+ if (isUsedOutsideOfDefiningBlock(I))
+Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+===================================================================
+--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
++++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+@@ -860,10 +860,10 @@ void RegsForValue::AddInlineAsmOperands(unsigned C
+ unsigned TheReg = Regs[Reg++];
+ Ops.push_back(DAG.getRegister(TheReg, RegisterVT));
+
+- // Notice if we clobbered the stack pointer. Yes, inline asm can do this.
+ if (TheReg == SP && Code == InlineAsm::Kind_Clobber) {
+- MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+- MFI->setHasInlineAsmWithSPAdjust(true);
++ // If we clobbered the stack pointer, MFI should know about it.
++ assert(DAG.getMachineFunction().getFrameInfo()->
++ hasInlineAsmWithSPAdjust());
+ }
+ }
+ }
+@@ -3378,9 +3378,7 @@ void SelectionDAGBuilder::visitAlloca(const Alloca
+ setValue(&I, DSA);
+ DAG.setRoot(DSA.getValue(1));
+
+- // Inform the Frame Information that we have just allocated a variable-sized
+- // object.
+- FuncInfo.MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1);
++ assert(FuncInfo.MF->getFrameInfo()->hasVarSizedObjects());
+ }
+
+ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
+Index: test/CodeGen/X86/stack-align-memcpy.ll
+===================================================================
+--- test/CodeGen/X86/stack-align-memcpy.ll
++++ test/CodeGen/X86/stack-align-memcpy.ll
+@@ -2,6 +2,9 @@
+
+ %struct.foo = type { [88 x i8] }
+
++declare void @bar(i8* nocapture, %struct.foo* align 4 byval) nounwind
++declare void @baz(i8*) nounwind
++
+ ; PR15249
+ ; We can't use rep;movsl here because it clobbers the base pointer in %esi.
+ define void @test1(%struct.foo* nocapture %x, i32 %y) nounwind {
+@@ -15,4 +18,26 @@ define void @test1(%struct.foo* nocapture %x, i32
+ ; CHECK-NOT: rep;movsl
+ }
+
+-declare void @bar(i8* nocapture, %struct.foo* align 4 byval) nounwind
++; PR19012
++; Also don't clobber %esi if the dynamic alloca comes after the memcpy.
++define void @test2(%struct.foo* nocapture %x, i32 %y, i8* %z) nounwind {
++ call void @bar(i8* %z, %struct.foo* align 4 byval %x)
++ %dynalloc = alloca i8, i32 %y, align 1
++ call void @baz(i8* %dynalloc)
++ ret void
++
++; CHECK-LABEL: test2:
++; CHECK: movl %esp, %esi
++; CHECK-NOT: rep;movsl
++}
++
++; Check that we do use rep movs if we make the alloca static.
++define void @test3(%struct.foo* nocapture %x, i32 %y, i8* %z) nounwind {
++ call void @bar(i8* %z, %struct.foo* align 4 byval %x)
++ %statalloc = alloca i8, i32 8, align 1
++ call void @baz(i8* %statalloc)
++ ret void
++
++; CHECK-LABEL: test3:
++; CHECK: rep;movsl
++}
+Index: test/CodeGen/X86/inline-asm-sp-clobber-memcpy.ll
+===================================================================
+--- test/CodeGen/X86/inline-asm-sp-clobber-memcpy.ll
++++ test/CodeGen/X86/inline-asm-sp-clobber-memcpy.ll
+@@ -0,0 +1,17 @@
++; RUN: llc < %s -force-align-stack -mtriple i386-apple-darwin -mcpu=i486 | FileCheck %s
++
++%struct.foo = type { [88 x i8] }
++
++declare void @bar(i8* nocapture, %struct.foo* align 4 byval) nounwind
++
++; PR19012
++; Don't clobber %esi if we have inline asm that clobbers %esp.
++define void @test1(%struct.foo* nocapture %x, i32 %y, i8* %z) nounwind {
++ call void @bar(i8* %z, %struct.foo* align 4 byval %x)
++ call void asm sideeffect inteldialect "xor esp, esp", "=*m,~{flags},~{esp},~{esp},~{dirflag},~{fpsr},~{flags}"(i8* %z)
++ ret void
++
++; CHECK-LABEL: test1:
++; CHECK: movl %esp, %esi
++; CHECK-NOT: rep;movsl
++}
+Index: include/llvm/CodeGen/FunctionLoweringInfo.h
+===================================================================
+--- include/llvm/CodeGen/FunctionLoweringInfo.h
++++ include/llvm/CodeGen/FunctionLoweringInfo.h
+@@ -41,6 +41,7 @@ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineModuleInfo;
+ class MachineRegisterInfo;
++class SelectionDAG;
+ class TargetLowering;
+ class Value;
+
+@@ -125,7 +126,7 @@ class FunctionLoweringInfo {
+ /// set - Initialize this FunctionLoweringInfo with the given Function
+ /// and its associated MachineFunction.
+ ///
+- void set(const Function &Fn, MachineFunction &MF);
++ void set(const Function &Fn, MachineFunction &MF, SelectionDAG *DAG);
+
+ /// clear - Clear out all the function-specific state. This returns this
+ /// FunctionLoweringInfo to an empty state, ready to be used for a
+Index: include/llvm/CodeGen/MachineFrameInfo.h
+===================================================================
+--- include/llvm/CodeGen/MachineFrameInfo.h
++++ include/llvm/CodeGen/MachineFrameInfo.h
+@@ -244,6 +244,7 @@ class MachineFrameInfo {
+ LocalFrameSize = 0;
+ LocalFrameMaxAlign = 0;
+ UseLocalStackAllocationBlock = false;
++ HasInlineAsmWithSPAdjust = false;
+ }
+
+ /// hasStackObjects - Return true if there are any stack objects in this
+@@ -529,7 +530,7 @@ class MachineFrameInfo {
+ /// variable sized object is created, whether or not the index returned is
+ /// actually used.
+ ///
+- int CreateVariableSizedObject(unsigned Alignment);
++ int CreateVariableSizedObject(unsigned Alignment, const AllocaInst *Alloca);
+
+ /// getCalleeSavedInfo - Returns a reference to call saved info vector for the
+ /// current function.
diff --git a/contrib/llvm/patches/patch-r263313-llvm-r203311-fix-sse1-oom.diff b/contrib/llvm/patches/patch-r263313-llvm-r203311-fix-sse1-oom.diff
new file mode 100644
index 0000000..43efd12
--- /dev/null
+++ b/contrib/llvm/patches/patch-r263313-llvm-r203311-fix-sse1-oom.diff
@@ -0,0 +1,60 @@
+Pull in r203311 from upstream llvm trunk (by Arnold Schwaighofer):
+
+ ISel: Make VSELECT selection terminate in cases where the condition type has to
+ be split and the result type widened.
+
+ When the condition of a vselect has to be split it makes no sense widening the
+ vselect and thereby widening the condition. We end up in an endless loop of
+ widening (vselect result type) and splitting (condition mask type) doing this.
+ Instead, split both the condition and the vselect and widen the result.
+
+ I ran this over the test suite with i686 and mattr=+sse and saw no regressions.
+
+ Fixes PR18036.
+
+Introduced here: http://svn.freebsd.org/changeset/base/263313
+
+Index: test/CodeGen/X86/sse1.ll
+===================================================================
+--- test/CodeGen/X86/sse1.ll
++++ test/CodeGen/X86/sse1.ll
+@@ -43,3 +43,17 @@ entry:
+ ; CHECK-NOT: shufps $16
+ ; CHECK: ret
+ }
++
++; We used to get stuck in type legalization for this example when lowering the
++; vselect. With SSE1 v4f32 is a legal type but v4i1 (or any vector integer type)
++; is not. We used to ping pong between splitting the vselect for the v4i
++; condition operand and widening the resulting vselect for the v4f32 result.
++; PR18036
++
++; CHECK-LABEL: vselect
++define <4 x float> @vselect(<4 x float>*%p, <4 x i32> %q) {
++entry:
++ %a1 = icmp eq <4 x i32> %q, zeroinitializer
++ %a14 = select <4 x i1> %a1, <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+0> , <4 x float> zeroinitializer
++ ret <4 x float> %a14
++}
+Index: lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+===================================================================
+--- lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
++++ lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+@@ -2180,6 +2180,17 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNod
+ if (getTypeAction(CondVT) == TargetLowering::TypeWidenVector)
+ Cond1 = GetWidenedVector(Cond1);
+
++ // If we have to split the condition there is no point in widening the
++ // select. This would result in an cycle of widening the select ->
++ // widening the condition operand -> splitting the condition operand ->
++ // splitting the select -> widening the select. Instead split this select
++ // further and widen the resulting type.
++ if (getTypeAction(CondVT) == TargetLowering::TypeSplitVector) {
++ SDValue SplitSelect = SplitVecOp_VSELECT(N, 0);
++ SDValue Res = ModifyToType(SplitSelect, WidenVT);
++ return Res;
++ }
++
+ if (Cond1.getValueType() != CondWidenVT)
+ Cond1 = ModifyToType(Cond1, CondWidenVT);
+ }
OpenPOWER on IntegriCloud