1Pull in r199775 from upstream llvm trunk (by Venkatraman Govindaraju): 2 3 [Sparc] Do not add PC to _GLOBAL_OFFSET_TABLE_ address to access GOT in absolute code. 4 Fixes PR#18521 5 6Introduced here: http://svn.freebsd.org/changeset/base/262261 7 8Index: lib/Target/Sparc/SparcAsmPrinter.cpp 9=================================================================== 10--- lib/Target/Sparc/SparcAsmPrinter.cpp 11+++ lib/Target/Sparc/SparcAsmPrinter.cpp 12@@ -65,18 +65,24 @@ namespace { 13 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 14 unsigned AsmVariant, const char *ExtraCode, 15 raw_ostream &O); 16+ 17+ void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI); 18+ 19 }; 20 } // end of anonymous namespace 21 22-static MCOperand createPCXCallOP(MCSymbol *Label, 23- MCContext &OutContext) 24-{ 25- const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label, 26+static MCOperand createSparcMCOperand(SparcMCExpr::VariantKind Kind, 27+ MCSymbol *Sym, MCContext &OutContext) { 28+ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Sym, 29 OutContext); 30- const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None, 31- MCSym, OutContext); 32+ const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, OutContext); 33 return MCOperand::CreateExpr(expr); 34+ 35 } 36+static MCOperand createPCXCallOP(MCSymbol *Label, 37+ MCContext &OutContext) { 38+ return createSparcMCOperand(SparcMCExpr::VK_Sparc_None, Label, OutContext); 39+} 40 41 static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind, 42 MCSymbol *GOTLabel, MCSymbol *StartLabel, 43@@ -115,43 +121,101 @@ static void EmitSETHI(MCStreamer &OutStreamer, 44 OutStreamer.EmitInstruction(SETHIInst); 45 } 46 47-static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1, 48- MCOperand &Imm, MCOperand &RD) 49+static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode, 50+ MCOperand &RS1, MCOperand &Src2, MCOperand &RD) 51 { 52- MCInst ORInst; 53- ORInst.setOpcode(SP::ORri); 54- ORInst.addOperand(RD); 55- ORInst.addOperand(RS1); 56- ORInst.addOperand(Imm); 57- OutStreamer.EmitInstruction(ORInst); 58+ MCInst Inst; 59+ Inst.setOpcode(Opcode); 60+ Inst.addOperand(RD); 61+ Inst.addOperand(RS1); 62+ Inst.addOperand(Src2); 63+ OutStreamer.EmitInstruction(Inst); 64 } 65 66+static void EmitOR(MCStreamer &OutStreamer, 67+ MCOperand &RS1, MCOperand &Imm, MCOperand &RD) { 68+ EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD); 69+} 70+ 71 static void EmitADD(MCStreamer &OutStreamer, 72- MCOperand &RS1, MCOperand &RS2, MCOperand &RD) 73-{ 74- MCInst ADDInst; 75- ADDInst.setOpcode(SP::ADDrr); 76- ADDInst.addOperand(RD); 77- ADDInst.addOperand(RS1); 78- ADDInst.addOperand(RS2); 79- OutStreamer.EmitInstruction(ADDInst); 80+ MCOperand &RS1, MCOperand &RS2, MCOperand &RD) { 81+ EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD); 82 } 83 84-static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, 85- MCStreamer &OutStreamer, 86- MCContext &OutContext) 87+static void EmitSHL(MCStreamer &OutStreamer, 88+ MCOperand &RS1, MCOperand &Imm, MCOperand &RD) { 89+ EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD); 90+} 91+ 92+ 93+static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, 94+ SparcMCExpr::VariantKind HiKind, 95+ SparcMCExpr::VariantKind LoKind, 96+ MCOperand &RD, 97+ MCContext &OutContext) { 98+ 99+ MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext); 100+ MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext); 101+ EmitSETHI(OutStreamer, hi, RD); 102+ EmitOR(OutStreamer, RD, lo, RD); 103+} 104+ 105+void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI) 106 { 107- const MachineOperand &MO = MI->getOperand(0); 108- MCSymbol *StartLabel = OutContext.CreateTempSymbol(); 109- MCSymbol *EndLabel = OutContext.CreateTempSymbol(); 110- MCSymbol *SethiLabel = OutContext.CreateTempSymbol(); 111 MCSymbol *GOTLabel = 112 OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); 113 114+ const MachineOperand &MO = MI->getOperand(0); 115 assert(MO.getReg() != SP::O7 && 116 "%o7 is assigned as destination for getpcx!"); 117 118 MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg()); 119+ 120+ 121+ if (TM.getRelocationModel() != Reloc::PIC_) { 122+ // Just load the address of GOT to MCRegOP. 123+ switch(TM.getCodeModel()) { 124+ default: 125+ llvm_unreachable("Unsupported absolute code model"); 126+ case CodeModel::Small: 127+ EmitHiLo(OutStreamer, GOTLabel, 128+ SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO, 129+ MCRegOP, OutContext); 130+ break; 131+ case CodeModel::Medium: { 132+ EmitHiLo(OutStreamer, GOTLabel, 133+ SparcMCExpr::VK_Sparc_H44, SparcMCExpr::VK_Sparc_M44, 134+ MCRegOP, OutContext); 135+ MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(12, 136+ OutContext)); 137+ EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP); 138+ MCOperand lo = createSparcMCOperand(SparcMCExpr::VK_Sparc_L44, 139+ GOTLabel, OutContext); 140+ EmitOR(OutStreamer, MCRegOP, lo, MCRegOP); 141+ break; 142+ } 143+ case CodeModel::Large: { 144+ EmitHiLo(OutStreamer, GOTLabel, 145+ SparcMCExpr::VK_Sparc_HH, SparcMCExpr::VK_Sparc_HM, 146+ MCRegOP, OutContext); 147+ MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(32, 148+ OutContext)); 149+ EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP); 150+ // Use register %o7 to load the lower 32 bits. 151+ MCOperand RegO7 = MCOperand::CreateReg(SP::O7); 152+ EmitHiLo(OutStreamer, GOTLabel, 153+ SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO, 154+ RegO7, OutContext); 155+ EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP); 156+ } 157+ } 158+ return; 159+ } 160+ 161+ MCSymbol *StartLabel = OutContext.CreateTempSymbol(); 162+ MCSymbol *EndLabel = OutContext.CreateTempSymbol(); 163+ MCSymbol *SethiLabel = OutContext.CreateTempSymbol(); 164+ 165 MCOperand RegO7 = MCOperand::CreateReg(SP::O7); 166 167 // <StartLabel>: 168@@ -187,7 +251,7 @@ void SparcAsmPrinter::EmitInstruction(const Machin 169 // FIXME: Debug Value. 170 return; 171 case SP::GETPCX: 172- LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext); 173+ LowerGETPCXAndEmitMCInsts(MI); 174 return; 175 } 176 MachineBasicBlock::const_instr_iterator I = MI; 177Index: test/CodeGen/SPARC/tls.ll 178=================================================================== 179--- test/CodeGen/SPARC/tls.ll 180+++ test/CodeGen/SPARC/tls.ll 181@@ -38,8 +38,7 @@ entry: 182 183 184 ; v8abs-LABEL: test_tls_extern 185-; v8abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]] 186-; v8abs: add [[PC]], %o7, %[[GOTBASE:[goli][0-7]]] 187+; v8abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]] 188 ; v8abs: sethi %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]] 189 ; v8abs: add [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]] 190 ; v8abs: ld [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ld(extern_symbol) 191@@ -47,8 +46,7 @@ entry: 192 ; v8abs: ld [%[[R4]]] 193 194 ; v9abs-LABEL: test_tls_extern 195-; v9abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]] 196-; v9abs: add [[PC]], %o7, %[[GOTBASE:[goli][0-7]]] 197+; v9abs: or {{%[goli][0-7]}}, %l44(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]] 198 ; v9abs: sethi %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]] 199 ; v9abs: add [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]] 200 ; v9abs: ldx [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ldx(extern_symbol) 201