1 Pull in r199775 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [Sparc] Do not add PC to _GLOBAL_OFFSET_TABLE_ address to access GOT in absolute code.
6 Introduced here: http://svn.freebsd.org/changeset/base/262261
8 Index: 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,
17 + void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI);
20 } // end of anonymous namespace
22 -static MCOperand createPCXCallOP(MCSymbol *Label,
23 - MCContext &OutContext)
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,
30 - const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
32 + const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, OutContext);
33 return MCOperand::CreateExpr(expr);
36 +static MCOperand createPCXCallOP(MCSymbol *Label,
37 + MCContext &OutContext) {
38 + return createSparcMCOperand(SparcMCExpr::VK_Sparc_None, Label, OutContext);
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);
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)
53 - ORInst.setOpcode(SP::ORri);
54 - ORInst.addOperand(RD);
55 - ORInst.addOperand(RS1);
56 - ORInst.addOperand(Imm);
57 - OutStreamer.EmitInstruction(ORInst);
59 + Inst.setOpcode(Opcode);
60 + Inst.addOperand(RD);
61 + Inst.addOperand(RS1);
62 + Inst.addOperand(Src2);
63 + OutStreamer.EmitInstruction(Inst);
66 +static void EmitOR(MCStreamer &OutStreamer,
67 + MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
68 + EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD);
71 static void EmitADD(MCStreamer &OutStreamer,
72 - MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
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);
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);
93 +static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym,
94 + SparcMCExpr::VariantKind HiKind,
95 + SparcMCExpr::VariantKind LoKind,
97 + MCContext &OutContext) {
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);
105 +void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI)
107 - const MachineOperand &MO = MI->getOperand(0);
108 - MCSymbol *StartLabel = OutContext.CreateTempSymbol();
109 - MCSymbol *EndLabel = OutContext.CreateTempSymbol();
110 - MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
112 OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
114 + const MachineOperand &MO = MI->getOperand(0);
115 assert(MO.getReg() != SP::O7 &&
116 "%o7 is assigned as destination for getpcx!");
118 MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
121 + if (TM.getRelocationModel() != Reloc::PIC_) {
122 + // Just load the address of GOT to MCRegOP.
123 + switch(TM.getCodeModel()) {
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);
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,
137 + EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
138 + MCOperand lo = createSparcMCOperand(SparcMCExpr::VK_Sparc_L44,
139 + GOTLabel, OutContext);
140 + EmitOR(OutStreamer, MCRegOP, lo, MCRegOP);
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,
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);
161 + MCSymbol *StartLabel = OutContext.CreateTempSymbol();
162 + MCSymbol *EndLabel = OutContext.CreateTempSymbol();
163 + MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
165 MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
168 @@ -187,7 +251,7 @@ void SparcAsmPrinter::EmitInstruction(const Machin
169 // FIXME: Debug Value.
172 - LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
173 + LowerGETPCXAndEmitMCInsts(MI);
176 MachineBasicBlock::const_instr_iterator I = MI;
177 Index: test/CodeGen/SPARC/tls.ll
178 ===================================================================
179 --- test/CodeGen/SPARC/tls.ll
180 +++ test/CodeGen/SPARC/tls.ll
181 @@ -38,8 +38,7 @@ entry:
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]]]
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)