summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff200
1 files changed, 200 insertions, 0 deletions
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)
OpenPOWER on IntegriCloud