diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff | 200 |
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) |