llvm.org GIT mirror llvm / 6220c8f
[Sparc] Do not add PC to _GLOBAL_OFFSET_TABLE_ address to access GOT in absolute code. Fixes PR#18521 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199775 91177308-0d34-0410-b5e6-96231b3b80d8 Venkatraman Govindaraju 6 years ago
2 changed file(s) with 104 addition(s) and 42 deletion(s). Raw diff Collapse all Expand all
6565 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
6666 unsigned AsmVariant, const char *ExtraCode,
6767 raw_ostream &O);
68
69 void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI);
70
6871 };
6972 } // end of anonymous namespace
7073
74 static MCOperand createSparcMCOperand(SparcMCExpr::VariantKind Kind,
75 MCSymbol *Sym, MCContext &OutContext) {
76 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Sym,
77 OutContext);
78 const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, OutContext);
79 return MCOperand::CreateExpr(expr);
80
81 }
7182 static MCOperand createPCXCallOP(MCSymbol *Label,
72 MCContext &OutContext)
73 {
74 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
75 OutContext);
76 const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
77 MCSym, OutContext);
78 return MCOperand::CreateExpr(expr);
83 MCContext &OutContext) {
84 return createSparcMCOperand(SparcMCExpr::VK_Sparc_None, Label, OutContext);
7985 }
8086
8187 static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
115121 OutStreamer.EmitInstruction(SETHIInst);
116122 }
117123
118 static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
119 MCOperand &Imm, MCOperand &RD)
120 {
121 MCInst ORInst;
122 ORInst.setOpcode(SP::ORri);
123 ORInst.addOperand(RD);
124 ORInst.addOperand(RS1);
125 ORInst.addOperand(Imm);
126 OutStreamer.EmitInstruction(ORInst);
124 static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode,
125 MCOperand &RS1, MCOperand &Src2, MCOperand &RD)
126 {
127 MCInst Inst;
128 Inst.setOpcode(Opcode);
129 Inst.addOperand(RD);
130 Inst.addOperand(RS1);
131 Inst.addOperand(Src2);
132 OutStreamer.EmitInstruction(Inst);
133 }
134
135 static void EmitOR(MCStreamer &OutStreamer,
136 MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
137 EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD);
127138 }
128139
129140 static void EmitADD(MCStreamer &OutStreamer,
130 MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
131 {
132 MCInst ADDInst;
133 ADDInst.setOpcode(SP::ADDrr);
134 ADDInst.addOperand(RD);
135 ADDInst.addOperand(RS1);
136 ADDInst.addOperand(RS2);
137 OutStreamer.EmitInstruction(ADDInst);
138 }
139
140 static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
141 MCStreamer &OutStreamer,
142 MCContext &OutContext)
143 {
141 MCOperand &RS1, MCOperand &RS2, MCOperand &RD) {
142 EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD);
143 }
144
145 static void EmitSHL(MCStreamer &OutStreamer,
146 MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
147 EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD);
148 }
149
150
151 static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym,
152 SparcMCExpr::VariantKind HiKind,
153 SparcMCExpr::VariantKind LoKind,
154 MCOperand &RD,
155 MCContext &OutContext) {
156
157 MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext);
158 MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext);
159 EmitSETHI(OutStreamer, hi, RD);
160 EmitOR(OutStreamer, RD, lo, RD);
161 }
162
163 void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI)
164 {
165 MCSymbol *GOTLabel =
166 OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
167
144168 const MachineOperand &MO = MI->getOperand(0);
169 assert(MO.getReg() != SP::O7 &&
170 "%o7 is assigned as destination for getpcx!");
171
172 MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
173
174
175 if (TM.getRelocationModel() != Reloc::PIC_) {
176 // Just load the address of GOT to MCRegOP.
177 switch(TM.getCodeModel()) {
178 default:
179 llvm_unreachable("Unsupported absolute code model");
180 case CodeModel::Small:
181 EmitHiLo(OutStreamer, GOTLabel,
182 SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO,
183 MCRegOP, OutContext);
184 break;
185 case CodeModel::Medium: {
186 EmitHiLo(OutStreamer, GOTLabel,
187 SparcMCExpr::VK_Sparc_H44, SparcMCExpr::VK_Sparc_M44,
188 MCRegOP, OutContext);
189 MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(12,
190 OutContext));
191 EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
192 MCOperand lo = createSparcMCOperand(SparcMCExpr::VK_Sparc_L44,
193 GOTLabel, OutContext);
194 EmitOR(OutStreamer, MCRegOP, lo, MCRegOP);
195 break;
196 }
197 case CodeModel::Large: {
198 EmitHiLo(OutStreamer, GOTLabel,
199 SparcMCExpr::VK_Sparc_HH, SparcMCExpr::VK_Sparc_HM,
200 MCRegOP, OutContext);
201 MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(32,
202 OutContext));
203 EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
204 // Use register %o7 to load the lower 32 bits.
205 MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
206 EmitHiLo(OutStreamer, GOTLabel,
207 SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO,
208 RegO7, OutContext);
209 EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
210 }
211 }
212 return;
213 }
214
145215 MCSymbol *StartLabel = OutContext.CreateTempSymbol();
146216 MCSymbol *EndLabel = OutContext.CreateTempSymbol();
147217 MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
148 MCSymbol *GOTLabel =
149 OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
150
151 assert(MO.getReg() != SP::O7 &&
152 "%o7 is assigned as destination for getpcx!");
153
154 MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
218
155219 MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
156220
157221 // :
187251 // FIXME: Debug Value.
188252 return;
189253 case SP::GETPCX:
190 LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
254 LowerGETPCXAndEmitMCInsts(MI);
191255 return;
192256 }
193257 MachineBasicBlock::const_instr_iterator I = MI;
3737
3838
3939 ; v8abs-LABEL: test_tls_extern
40 ; v8abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]]
41 ; v8abs: add [[PC]], %o7, %[[GOTBASE:[goli][0-7]]]
40 ; v8abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]]
4241 ; v8abs: sethi %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]]
4342 ; v8abs: add [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]]
4443 ; v8abs: ld [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ld(extern_symbol)
4645 ; v8abs: ld [%[[R4]]]
4746
4847 ; v9abs-LABEL: test_tls_extern
49 ; v9abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]]
50 ; v9abs: add [[PC]], %o7, %[[GOTBASE:[goli][0-7]]]
48 ; v9abs: or {{%[goli][0-7]}}, %l44(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]]
5149 ; v9abs: sethi %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]]
5250 ; v9abs: add [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]]
5351 ; v9abs: ldx [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ldx(extern_symbol)