From ce0b21596585c6ddd828c54e5077ba0aecfae8fc Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Tue, 18 Mar 2014 22:07:45 +0000
Subject: Add separate patch files for all the customizations we have currently
 applied to our copy of llvm/clang.  These can be applied in alphabetical
 order to a pristine llvm/clang 3.4 release source tree, to result in the same
 version used in FreeBSD.

This is intended to clearly document all the changes until now, which
mostly consist of cherry pickings from the respective upstream trunks,
plus a number of hand-written FreeBSD-specific ones.  Hopefully those
can eventually be cleaned up and sent upstream too.

MFC after:	1 week
X-MFC-With:	r263313
---
 .../patches/patch-r262261-llvm-r199775-sparc.diff  | 200 +++++++++++++++++++++
 1 file changed, 200 insertions(+)
 create mode 100644 contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff

(limited to 'contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff')

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)
-- 
cgit v1.1