File: | lib/MC/MCExpr.cpp |
Warning: | line 775, column 43 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- MCExpr.cpp - Assembly Level Expression Implementation --------------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | ||||
10 | #include "llvm/MC/MCExpr.h" | |||
11 | #include "llvm/ADT/Statistic.h" | |||
12 | #include "llvm/ADT/StringSwitch.h" | |||
13 | #include "llvm/MC/MCAsmInfo.h" | |||
14 | #include "llvm/MC/MCAsmLayout.h" | |||
15 | #include "llvm/MC/MCAssembler.h" | |||
16 | #include "llvm/MC/MCContext.h" | |||
17 | #include "llvm/MC/MCObjectWriter.h" | |||
18 | #include "llvm/MC/MCSymbol.h" | |||
19 | #include "llvm/MC/MCValue.h" | |||
20 | #include "llvm/Support/Casting.h" | |||
21 | #include "llvm/Support/Compiler.h" | |||
22 | #include "llvm/Support/Debug.h" | |||
23 | #include "llvm/Support/ErrorHandling.h" | |||
24 | #include "llvm/Support/raw_ostream.h" | |||
25 | #include <cassert> | |||
26 | #include <cstdint> | |||
27 | ||||
28 | using namespace llvm; | |||
29 | ||||
30 | #define DEBUG_TYPE"mcexpr" "mcexpr" | |||
31 | ||||
32 | namespace { | |||
33 | namespace stats { | |||
34 | ||||
35 | STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations")static llvm::Statistic MCExprEvaluate = {"mcexpr", "MCExprEvaluate" , "Number of MCExpr evaluations", {0}, {false}}; | |||
36 | ||||
37 | } // end namespace stats | |||
38 | } // end anonymous namespace | |||
39 | ||||
40 | void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const { | |||
41 | switch (getKind()) { | |||
42 | case MCExpr::Target: | |||
43 | return cast<MCTargetExpr>(this)->printImpl(OS, MAI); | |||
44 | case MCExpr::Constant: | |||
45 | OS << cast<MCConstantExpr>(*this).getValue(); | |||
46 | return; | |||
47 | ||||
48 | case MCExpr::SymbolRef: { | |||
49 | const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*this); | |||
50 | const MCSymbol &Sym = SRE.getSymbol(); | |||
51 | // Parenthesize names that start with $ so that they don't look like | |||
52 | // absolute names. | |||
53 | bool UseParens = | |||
54 | !InParens && !Sym.getName().empty() && Sym.getName()[0] == '$'; | |||
55 | if (UseParens) { | |||
56 | OS << '('; | |||
57 | Sym.print(OS, MAI); | |||
58 | OS << ')'; | |||
59 | } else | |||
60 | Sym.print(OS, MAI); | |||
61 | ||||
62 | if (SRE.getKind() != MCSymbolRefExpr::VK_None) | |||
63 | SRE.printVariantKind(OS); | |||
64 | ||||
65 | return; | |||
66 | } | |||
67 | ||||
68 | case MCExpr::Unary: { | |||
69 | const MCUnaryExpr &UE = cast<MCUnaryExpr>(*this); | |||
70 | switch (UE.getOpcode()) { | |||
71 | case MCUnaryExpr::LNot: OS << '!'; break; | |||
72 | case MCUnaryExpr::Minus: OS << '-'; break; | |||
73 | case MCUnaryExpr::Not: OS << '~'; break; | |||
74 | case MCUnaryExpr::Plus: OS << '+'; break; | |||
75 | } | |||
76 | UE.getSubExpr()->print(OS, MAI); | |||
77 | return; | |||
78 | } | |||
79 | ||||
80 | case MCExpr::Binary: { | |||
81 | const MCBinaryExpr &BE = cast<MCBinaryExpr>(*this); | |||
82 | ||||
83 | // Only print parens around the LHS if it is non-trivial. | |||
84 | if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) { | |||
85 | BE.getLHS()->print(OS, MAI); | |||
86 | } else { | |||
87 | OS << '('; | |||
88 | BE.getLHS()->print(OS, MAI); | |||
89 | OS << ')'; | |||
90 | } | |||
91 | ||||
92 | switch (BE.getOpcode()) { | |||
93 | case MCBinaryExpr::Add: | |||
94 | // Print "X-42" instead of "X+-42". | |||
95 | if (const MCConstantExpr *RHSC = dyn_cast<MCConstantExpr>(BE.getRHS())) { | |||
96 | if (RHSC->getValue() < 0) { | |||
97 | OS << RHSC->getValue(); | |||
98 | return; | |||
99 | } | |||
100 | } | |||
101 | ||||
102 | OS << '+'; | |||
103 | break; | |||
104 | case MCBinaryExpr::AShr: OS << ">>"; break; | |||
105 | case MCBinaryExpr::And: OS << '&'; break; | |||
106 | case MCBinaryExpr::Div: OS << '/'; break; | |||
107 | case MCBinaryExpr::EQ: OS << "=="; break; | |||
108 | case MCBinaryExpr::GT: OS << '>'; break; | |||
109 | case MCBinaryExpr::GTE: OS << ">="; break; | |||
110 | case MCBinaryExpr::LAnd: OS << "&&"; break; | |||
111 | case MCBinaryExpr::LOr: OS << "||"; break; | |||
112 | case MCBinaryExpr::LShr: OS << ">>"; break; | |||
113 | case MCBinaryExpr::LT: OS << '<'; break; | |||
114 | case MCBinaryExpr::LTE: OS << "<="; break; | |||
115 | case MCBinaryExpr::Mod: OS << '%'; break; | |||
116 | case MCBinaryExpr::Mul: OS << '*'; break; | |||
117 | case MCBinaryExpr::NE: OS << "!="; break; | |||
118 | case MCBinaryExpr::Or: OS << '|'; break; | |||
119 | case MCBinaryExpr::Shl: OS << "<<"; break; | |||
120 | case MCBinaryExpr::Sub: OS << '-'; break; | |||
121 | case MCBinaryExpr::Xor: OS << '^'; break; | |||
122 | } | |||
123 | ||||
124 | // Only print parens around the LHS if it is non-trivial. | |||
125 | if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) { | |||
126 | BE.getRHS()->print(OS, MAI); | |||
127 | } else { | |||
128 | OS << '('; | |||
129 | BE.getRHS()->print(OS, MAI); | |||
130 | OS << ')'; | |||
131 | } | |||
132 | return; | |||
133 | } | |||
134 | } | |||
135 | ||||
136 | llvm_unreachable("Invalid expression kind!")::llvm::llvm_unreachable_internal("Invalid expression kind!", "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp" , 136); | |||
137 | } | |||
138 | ||||
139 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | |||
140 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void MCExpr::dump() const { | |||
141 | dbgs() << *this; | |||
142 | dbgs() << '\n'; | |||
143 | } | |||
144 | #endif | |||
145 | ||||
146 | /* *** */ | |||
147 | ||||
148 | const MCBinaryExpr *MCBinaryExpr::create(Opcode Opc, const MCExpr *LHS, | |||
149 | const MCExpr *RHS, MCContext &Ctx, | |||
150 | SMLoc Loc) { | |||
151 | return new (Ctx) MCBinaryExpr(Opc, LHS, RHS, Loc); | |||
152 | } | |||
153 | ||||
154 | const MCUnaryExpr *MCUnaryExpr::create(Opcode Opc, const MCExpr *Expr, | |||
155 | MCContext &Ctx, SMLoc Loc) { | |||
156 | return new (Ctx) MCUnaryExpr(Opc, Expr, Loc); | |||
157 | } | |||
158 | ||||
159 | const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx) { | |||
160 | return new (Ctx) MCConstantExpr(Value); | |||
161 | } | |||
162 | ||||
163 | /* *** */ | |||
164 | ||||
165 | MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, | |||
166 | const MCAsmInfo *MAI, SMLoc Loc) | |||
167 | : MCExpr(MCExpr::SymbolRef, Loc), Kind(Kind), | |||
168 | UseParensForSymbolVariant(MAI->useParensForSymbolVariant()), | |||
169 | HasSubsectionsViaSymbols(MAI->hasSubsectionsViaSymbols()), | |||
170 | Symbol(Symbol) { | |||
171 | assert(Symbol)(static_cast <bool> (Symbol) ? void (0) : __assert_fail ("Symbol", "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp" , 171, __extension__ __PRETTY_FUNCTION__)); | |||
172 | } | |||
173 | ||||
174 | const MCSymbolRefExpr *MCSymbolRefExpr::create(const MCSymbol *Sym, | |||
175 | VariantKind Kind, | |||
176 | MCContext &Ctx, SMLoc Loc) { | |||
177 | return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo(), Loc); | |||
178 | } | |||
179 | ||||
180 | const MCSymbolRefExpr *MCSymbolRefExpr::create(StringRef Name, VariantKind Kind, | |||
181 | MCContext &Ctx) { | |||
182 | return create(Ctx.getOrCreateSymbol(Name), Kind, Ctx); | |||
183 | } | |||
184 | ||||
185 | StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { | |||
186 | switch (Kind) { | |||
187 | case VK_Invalid: return "<<invalid>>"; | |||
188 | case VK_None: return "<<none>>"; | |||
189 | ||||
190 | case VK_DTPOFF: return "DTPOFF"; | |||
191 | case VK_DTPREL: return "DTPREL"; | |||
192 | case VK_GOT: return "GOT"; | |||
193 | case VK_GOTOFF: return "GOTOFF"; | |||
194 | case VK_GOTREL: return "GOTREL"; | |||
195 | case VK_GOTPCREL: return "GOTPCREL"; | |||
196 | case VK_GOTTPOFF: return "GOTTPOFF"; | |||
197 | case VK_INDNTPOFF: return "INDNTPOFF"; | |||
198 | case VK_NTPOFF: return "NTPOFF"; | |||
199 | case VK_GOTNTPOFF: return "GOTNTPOFF"; | |||
200 | case VK_PLT: return "PLT"; | |||
201 | case VK_TLSGD: return "TLSGD"; | |||
202 | case VK_TLSLD: return "TLSLD"; | |||
203 | case VK_TLSLDM: return "TLSLDM"; | |||
204 | case VK_TPOFF: return "TPOFF"; | |||
205 | case VK_TPREL: return "TPREL"; | |||
206 | case VK_TLSCALL: return "tlscall"; | |||
207 | case VK_TLSDESC: return "tlsdesc"; | |||
208 | case VK_TLVP: return "TLVP"; | |||
209 | case VK_TLVPPAGE: return "TLVPPAGE"; | |||
210 | case VK_TLVPPAGEOFF: return "TLVPPAGEOFF"; | |||
211 | case VK_PAGE: return "PAGE"; | |||
212 | case VK_PAGEOFF: return "PAGEOFF"; | |||
213 | case VK_GOTPAGE: return "GOTPAGE"; | |||
214 | case VK_GOTPAGEOFF: return "GOTPAGEOFF"; | |||
215 | case VK_SECREL: return "SECREL32"; | |||
216 | case VK_SIZE: return "SIZE"; | |||
217 | case VK_WEAKREF: return "WEAKREF"; | |||
218 | case VK_X86_ABS8: return "ABS8"; | |||
219 | case VK_ARM_NONE: return "none"; | |||
220 | case VK_ARM_GOT_PREL: return "GOT_PREL"; | |||
221 | case VK_ARM_TARGET1: return "target1"; | |||
222 | case VK_ARM_TARGET2: return "target2"; | |||
223 | case VK_ARM_PREL31: return "prel31"; | |||
224 | case VK_ARM_SBREL: return "sbrel"; | |||
225 | case VK_ARM_TLSLDO: return "tlsldo"; | |||
226 | case VK_ARM_TLSDESCSEQ: return "tlsdescseq"; | |||
227 | case VK_AVR_NONE: return "none"; | |||
228 | case VK_AVR_LO8: return "lo8"; | |||
229 | case VK_AVR_HI8: return "hi8"; | |||
230 | case VK_AVR_HLO8: return "hlo8"; | |||
231 | case VK_AVR_DIFF8: return "diff8"; | |||
232 | case VK_AVR_DIFF16: return "diff16"; | |||
233 | case VK_AVR_DIFF32: return "diff32"; | |||
234 | case VK_PPC_LO: return "l"; | |||
235 | case VK_PPC_HI: return "h"; | |||
236 | case VK_PPC_HA: return "ha"; | |||
237 | case VK_PPC_HIGHER: return "higher"; | |||
238 | case VK_PPC_HIGHERA: return "highera"; | |||
239 | case VK_PPC_HIGHEST: return "highest"; | |||
240 | case VK_PPC_HIGHESTA: return "highesta"; | |||
241 | case VK_PPC_GOT_LO: return "got@l"; | |||
242 | case VK_PPC_GOT_HI: return "got@h"; | |||
243 | case VK_PPC_GOT_HA: return "got@ha"; | |||
244 | case VK_PPC_TOCBASE: return "tocbase"; | |||
245 | case VK_PPC_TOC: return "toc"; | |||
246 | case VK_PPC_TOC_LO: return "toc@l"; | |||
247 | case VK_PPC_TOC_HI: return "toc@h"; | |||
248 | case VK_PPC_TOC_HA: return "toc@ha"; | |||
249 | case VK_PPC_DTPMOD: return "dtpmod"; | |||
250 | case VK_PPC_TPREL_LO: return "tprel@l"; | |||
251 | case VK_PPC_TPREL_HI: return "tprel@h"; | |||
252 | case VK_PPC_TPREL_HA: return "tprel@ha"; | |||
253 | case VK_PPC_TPREL_HIGHER: return "tprel@higher"; | |||
254 | case VK_PPC_TPREL_HIGHERA: return "tprel@highera"; | |||
255 | case VK_PPC_TPREL_HIGHEST: return "tprel@highest"; | |||
256 | case VK_PPC_TPREL_HIGHESTA: return "tprel@highesta"; | |||
257 | case VK_PPC_DTPREL_LO: return "dtprel@l"; | |||
258 | case VK_PPC_DTPREL_HI: return "dtprel@h"; | |||
259 | case VK_PPC_DTPREL_HA: return "dtprel@ha"; | |||
260 | case VK_PPC_DTPREL_HIGHER: return "dtprel@higher"; | |||
261 | case VK_PPC_DTPREL_HIGHERA: return "dtprel@highera"; | |||
262 | case VK_PPC_DTPREL_HIGHEST: return "dtprel@highest"; | |||
263 | case VK_PPC_DTPREL_HIGHESTA: return "dtprel@highesta"; | |||
264 | case VK_PPC_GOT_TPREL: return "got@tprel"; | |||
265 | case VK_PPC_GOT_TPREL_LO: return "got@tprel@l"; | |||
266 | case VK_PPC_GOT_TPREL_HI: return "got@tprel@h"; | |||
267 | case VK_PPC_GOT_TPREL_HA: return "got@tprel@ha"; | |||
268 | case VK_PPC_GOT_DTPREL: return "got@dtprel"; | |||
269 | case VK_PPC_GOT_DTPREL_LO: return "got@dtprel@l"; | |||
270 | case VK_PPC_GOT_DTPREL_HI: return "got@dtprel@h"; | |||
271 | case VK_PPC_GOT_DTPREL_HA: return "got@dtprel@ha"; | |||
272 | case VK_PPC_TLS: return "tls"; | |||
273 | case VK_PPC_GOT_TLSGD: return "got@tlsgd"; | |||
274 | case VK_PPC_GOT_TLSGD_LO: return "got@tlsgd@l"; | |||
275 | case VK_PPC_GOT_TLSGD_HI: return "got@tlsgd@h"; | |||
276 | case VK_PPC_GOT_TLSGD_HA: return "got@tlsgd@ha"; | |||
277 | case VK_PPC_TLSGD: return "tlsgd"; | |||
278 | case VK_PPC_GOT_TLSLD: return "got@tlsld"; | |||
279 | case VK_PPC_GOT_TLSLD_LO: return "got@tlsld@l"; | |||
280 | case VK_PPC_GOT_TLSLD_HI: return "got@tlsld@h"; | |||
281 | case VK_PPC_GOT_TLSLD_HA: return "got@tlsld@ha"; | |||
282 | case VK_PPC_TLSLD: return "tlsld"; | |||
283 | case VK_PPC_LOCAL: return "local"; | |||
284 | case VK_COFF_IMGREL32: return "IMGREL"; | |||
285 | case VK_Hexagon_PCREL: return "PCREL"; | |||
286 | case VK_Hexagon_LO16: return "LO16"; | |||
287 | case VK_Hexagon_HI16: return "HI16"; | |||
288 | case VK_Hexagon_GPREL: return "GPREL"; | |||
289 | case VK_Hexagon_GD_GOT: return "GDGOT"; | |||
290 | case VK_Hexagon_LD_GOT: return "LDGOT"; | |||
291 | case VK_Hexagon_GD_PLT: return "GDPLT"; | |||
292 | case VK_Hexagon_LD_PLT: return "LDPLT"; | |||
293 | case VK_Hexagon_IE: return "IE"; | |||
294 | case VK_Hexagon_IE_GOT: return "IEGOT"; | |||
295 | case VK_WebAssembly_FUNCTION: return "FUNCTION"; | |||
296 | case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX"; | |||
297 | case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo"; | |||
298 | case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi"; | |||
299 | case VK_AMDGPU_REL32_LO: return "rel32@lo"; | |||
300 | case VK_AMDGPU_REL32_HI: return "rel32@hi"; | |||
301 | } | |||
302 | llvm_unreachable("Invalid variant kind")::llvm::llvm_unreachable_internal("Invalid variant kind", "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp" , 302); | |||
303 | } | |||
304 | ||||
305 | MCSymbolRefExpr::VariantKind | |||
306 | MCSymbolRefExpr::getVariantKindForName(StringRef Name) { | |||
307 | return StringSwitch<VariantKind>(Name.lower()) | |||
308 | .Case("dtprel", VK_DTPREL) | |||
309 | .Case("dtpoff", VK_DTPOFF) | |||
310 | .Case("got", VK_GOT) | |||
311 | .Case("gotoff", VK_GOTOFF) | |||
312 | .Case("gotrel", VK_GOTREL) | |||
313 | .Case("gotpcrel", VK_GOTPCREL) | |||
314 | .Case("gottpoff", VK_GOTTPOFF) | |||
315 | .Case("indntpoff", VK_INDNTPOFF) | |||
316 | .Case("ntpoff", VK_NTPOFF) | |||
317 | .Case("gotntpoff", VK_GOTNTPOFF) | |||
318 | .Case("plt", VK_PLT) | |||
319 | .Case("tlscall", VK_TLSCALL) | |||
320 | .Case("tlsdesc", VK_TLSDESC) | |||
321 | .Case("tlsgd", VK_TLSGD) | |||
322 | .Case("tlsld", VK_TLSLD) | |||
323 | .Case("tlsldm", VK_TLSLDM) | |||
324 | .Case("tpoff", VK_TPOFF) | |||
325 | .Case("tprel", VK_TPREL) | |||
326 | .Case("tlvp", VK_TLVP) | |||
327 | .Case("tlvppage", VK_TLVPPAGE) | |||
328 | .Case("tlvppageoff", VK_TLVPPAGEOFF) | |||
329 | .Case("page", VK_PAGE) | |||
330 | .Case("pageoff", VK_PAGEOFF) | |||
331 | .Case("gotpage", VK_GOTPAGE) | |||
332 | .Case("gotpageoff", VK_GOTPAGEOFF) | |||
333 | .Case("imgrel", VK_COFF_IMGREL32) | |||
334 | .Case("secrel32", VK_SECREL) | |||
335 | .Case("size", VK_SIZE) | |||
336 | .Case("abs8", VK_X86_ABS8) | |||
337 | .Case("l", VK_PPC_LO) | |||
338 | .Case("h", VK_PPC_HI) | |||
339 | .Case("ha", VK_PPC_HA) | |||
340 | .Case("higher", VK_PPC_HIGHER) | |||
341 | .Case("highera", VK_PPC_HIGHERA) | |||
342 | .Case("highest", VK_PPC_HIGHEST) | |||
343 | .Case("highesta", VK_PPC_HIGHESTA) | |||
344 | .Case("got@l", VK_PPC_GOT_LO) | |||
345 | .Case("got@h", VK_PPC_GOT_HI) | |||
346 | .Case("got@ha", VK_PPC_GOT_HA) | |||
347 | .Case("local", VK_PPC_LOCAL) | |||
348 | .Case("tocbase", VK_PPC_TOCBASE) | |||
349 | .Case("toc", VK_PPC_TOC) | |||
350 | .Case("toc@l", VK_PPC_TOC_LO) | |||
351 | .Case("toc@h", VK_PPC_TOC_HI) | |||
352 | .Case("toc@ha", VK_PPC_TOC_HA) | |||
353 | .Case("tls", VK_PPC_TLS) | |||
354 | .Case("dtpmod", VK_PPC_DTPMOD) | |||
355 | .Case("tprel@l", VK_PPC_TPREL_LO) | |||
356 | .Case("tprel@h", VK_PPC_TPREL_HI) | |||
357 | .Case("tprel@ha", VK_PPC_TPREL_HA) | |||
358 | .Case("tprel@higher", VK_PPC_TPREL_HIGHER) | |||
359 | .Case("tprel@highera", VK_PPC_TPREL_HIGHERA) | |||
360 | .Case("tprel@highest", VK_PPC_TPREL_HIGHEST) | |||
361 | .Case("tprel@highesta", VK_PPC_TPREL_HIGHESTA) | |||
362 | .Case("dtprel@l", VK_PPC_DTPREL_LO) | |||
363 | .Case("dtprel@h", VK_PPC_DTPREL_HI) | |||
364 | .Case("dtprel@ha", VK_PPC_DTPREL_HA) | |||
365 | .Case("dtprel@higher", VK_PPC_DTPREL_HIGHER) | |||
366 | .Case("dtprel@highera", VK_PPC_DTPREL_HIGHERA) | |||
367 | .Case("dtprel@highest", VK_PPC_DTPREL_HIGHEST) | |||
368 | .Case("dtprel@highesta", VK_PPC_DTPREL_HIGHESTA) | |||
369 | .Case("got@tprel", VK_PPC_GOT_TPREL) | |||
370 | .Case("got@tprel@l", VK_PPC_GOT_TPREL_LO) | |||
371 | .Case("got@tprel@h", VK_PPC_GOT_TPREL_HI) | |||
372 | .Case("got@tprel@ha", VK_PPC_GOT_TPREL_HA) | |||
373 | .Case("got@dtprel", VK_PPC_GOT_DTPREL) | |||
374 | .Case("got@dtprel@l", VK_PPC_GOT_DTPREL_LO) | |||
375 | .Case("got@dtprel@h", VK_PPC_GOT_DTPREL_HI) | |||
376 | .Case("got@dtprel@ha", VK_PPC_GOT_DTPREL_HA) | |||
377 | .Case("got@tlsgd", VK_PPC_GOT_TLSGD) | |||
378 | .Case("got@tlsgd@l", VK_PPC_GOT_TLSGD_LO) | |||
379 | .Case("got@tlsgd@h", VK_PPC_GOT_TLSGD_HI) | |||
380 | .Case("got@tlsgd@ha", VK_PPC_GOT_TLSGD_HA) | |||
381 | .Case("got@tlsld", VK_PPC_GOT_TLSLD) | |||
382 | .Case("got@tlsld@l", VK_PPC_GOT_TLSLD_LO) | |||
383 | .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI) | |||
384 | .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA) | |||
385 | .Case("gdgot", VK_Hexagon_GD_GOT) | |||
386 | .Case("gdplt", VK_Hexagon_GD_PLT) | |||
387 | .Case("iegot", VK_Hexagon_IE_GOT) | |||
388 | .Case("ie", VK_Hexagon_IE) | |||
389 | .Case("ldgot", VK_Hexagon_LD_GOT) | |||
390 | .Case("ldplt", VK_Hexagon_LD_PLT) | |||
391 | .Case("pcrel", VK_Hexagon_PCREL) | |||
392 | .Case("none", VK_ARM_NONE) | |||
393 | .Case("got_prel", VK_ARM_GOT_PREL) | |||
394 | .Case("target1", VK_ARM_TARGET1) | |||
395 | .Case("target2", VK_ARM_TARGET2) | |||
396 | .Case("prel31", VK_ARM_PREL31) | |||
397 | .Case("sbrel", VK_ARM_SBREL) | |||
398 | .Case("tlsldo", VK_ARM_TLSLDO) | |||
399 | .Case("lo8", VK_AVR_LO8) | |||
400 | .Case("hi8", VK_AVR_HI8) | |||
401 | .Case("hlo8", VK_AVR_HLO8) | |||
402 | .Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO) | |||
403 | .Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI) | |||
404 | .Case("rel32@lo", VK_AMDGPU_REL32_LO) | |||
405 | .Case("rel32@hi", VK_AMDGPU_REL32_HI) | |||
406 | .Default(VK_Invalid); | |||
407 | } | |||
408 | ||||
409 | void MCSymbolRefExpr::printVariantKind(raw_ostream &OS) const { | |||
410 | if (UseParensForSymbolVariant) | |||
411 | OS << '(' << MCSymbolRefExpr::getVariantKindName(getKind()) << ')'; | |||
412 | else | |||
413 | OS << '@' << MCSymbolRefExpr::getVariantKindName(getKind()); | |||
414 | } | |||
415 | ||||
416 | /* *** */ | |||
417 | ||||
418 | void MCTargetExpr::anchor() {} | |||
419 | ||||
420 | /* *** */ | |||
421 | ||||
422 | bool MCExpr::evaluateAsAbsolute(int64_t &Res) const { | |||
423 | return evaluateAsAbsolute(Res, nullptr, nullptr, nullptr); | |||
424 | } | |||
425 | ||||
426 | bool MCExpr::evaluateAsAbsolute(int64_t &Res, | |||
427 | const MCAsmLayout &Layout) const { | |||
428 | return evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr); | |||
429 | } | |||
430 | ||||
431 | bool MCExpr::evaluateAsAbsolute(int64_t &Res, | |||
432 | const MCAsmLayout &Layout, | |||
433 | const SectionAddrMap &Addrs) const { | |||
434 | return evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, &Addrs); | |||
435 | } | |||
436 | ||||
437 | bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const { | |||
438 | return evaluateAsAbsolute(Res, &Asm, nullptr, nullptr); | |||
439 | } | |||
440 | ||||
441 | bool MCExpr::evaluateKnownAbsolute(int64_t &Res, | |||
442 | const MCAsmLayout &Layout) const { | |||
443 | return evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr, | |||
444 | true); | |||
445 | } | |||
446 | ||||
447 | bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, | |||
448 | const MCAsmLayout *Layout, | |||
449 | const SectionAddrMap *Addrs) const { | |||
450 | // FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us | |||
451 | // absolutize differences across sections and that is what the MachO writer | |||
452 | // uses Addrs for. | |||
453 | return evaluateAsAbsolute(Res, Asm, Layout, Addrs, Addrs); | |||
454 | } | |||
455 | ||||
456 | bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, | |||
457 | const MCAsmLayout *Layout, | |||
458 | const SectionAddrMap *Addrs, bool InSet) const { | |||
459 | MCValue Value; | |||
460 | ||||
461 | // Fast path constants. | |||
462 | if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(this)) { | |||
463 | Res = CE->getValue(); | |||
464 | return true; | |||
465 | } | |||
466 | ||||
467 | bool IsRelocatable = | |||
468 | evaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet); | |||
469 | ||||
470 | // Record the current value. | |||
471 | Res = Value.getConstant(); | |||
472 | ||||
473 | return IsRelocatable && Value.isAbsolute(); | |||
474 | } | |||
475 | ||||
476 | /// \brief Helper method for \see EvaluateSymbolAdd(). | |||
477 | static void AttemptToFoldSymbolOffsetDifference( | |||
478 | const MCAssembler *Asm, const MCAsmLayout *Layout, | |||
479 | const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A, | |||
480 | const MCSymbolRefExpr *&B, int64_t &Addend) { | |||
481 | if (!A || !B) | |||
482 | return; | |||
483 | ||||
484 | const MCSymbol &SA = A->getSymbol(); | |||
485 | const MCSymbol &SB = B->getSymbol(); | |||
486 | ||||
487 | if (SA.isUndefined() || SB.isUndefined()) | |||
488 | return; | |||
489 | ||||
490 | if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet)) | |||
491 | return; | |||
492 | ||||
493 | if (SA.getFragment() == SB.getFragment() && !SA.isVariable() && | |||
494 | !SB.isVariable()) { | |||
495 | Addend += (SA.getOffset() - SB.getOffset()); | |||
496 | ||||
497 | // Pointers to Thumb symbols need to have their low-bit set to allow | |||
498 | // for interworking. | |||
499 | if (Asm->isThumbFunc(&SA)) | |||
500 | Addend |= 1; | |||
501 | ||||
502 | // Clear the symbol expr pointers to indicate we have folded these | |||
503 | // operands. | |||
504 | A = B = nullptr; | |||
505 | return; | |||
506 | } | |||
507 | ||||
508 | if (!Layout) | |||
509 | return; | |||
510 | ||||
511 | const MCSection &SecA = *SA.getFragment()->getParent(); | |||
512 | const MCSection &SecB = *SB.getFragment()->getParent(); | |||
513 | ||||
514 | if ((&SecA != &SecB) && !Addrs) | |||
515 | return; | |||
516 | ||||
517 | // Eagerly evaluate. | |||
518 | Addend += Layout->getSymbolOffset(A->getSymbol()) - | |||
519 | Layout->getSymbolOffset(B->getSymbol()); | |||
520 | if (Addrs && (&SecA != &SecB)) | |||
521 | Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB)); | |||
522 | ||||
523 | // Pointers to Thumb symbols need to have their low-bit set to allow | |||
524 | // for interworking. | |||
525 | if (Asm->isThumbFunc(&SA)) | |||
526 | Addend |= 1; | |||
527 | ||||
528 | // Clear the symbol expr pointers to indicate we have folded these | |||
529 | // operands. | |||
530 | A = B = nullptr; | |||
531 | } | |||
532 | ||||
533 | /// \brief Evaluate the result of an add between (conceptually) two MCValues. | |||
534 | /// | |||
535 | /// This routine conceptually attempts to construct an MCValue: | |||
536 | /// Result = (Result_A - Result_B + Result_Cst) | |||
537 | /// from two MCValue's LHS and RHS where | |||
538 | /// Result = LHS + RHS | |||
539 | /// and | |||
540 | /// Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst). | |||
541 | /// | |||
542 | /// This routine attempts to aggresively fold the operands such that the result | |||
543 | /// is representable in an MCValue, but may not always succeed. | |||
544 | /// | |||
545 | /// \returns True on success, false if the result is not representable in an | |||
546 | /// MCValue. | |||
547 | ||||
548 | /// NOTE: It is really important to have both the Asm and Layout arguments. | |||
549 | /// They might look redundant, but this function can be used before layout | |||
550 | /// is done (see the object streamer for example) and having the Asm argument | |||
551 | /// lets us avoid relaxations early. | |||
552 | static bool | |||
553 | EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout, | |||
554 | const SectionAddrMap *Addrs, bool InSet, const MCValue &LHS, | |||
555 | const MCSymbolRefExpr *RHS_A, const MCSymbolRefExpr *RHS_B, | |||
556 | int64_t RHS_Cst, MCValue &Res) { | |||
557 | // FIXME: This routine (and other evaluation parts) are *incredibly* sloppy | |||
558 | // about dealing with modifiers. This will ultimately bite us, one day. | |||
559 | const MCSymbolRefExpr *LHS_A = LHS.getSymA(); | |||
560 | const MCSymbolRefExpr *LHS_B = LHS.getSymB(); | |||
561 | int64_t LHS_Cst = LHS.getConstant(); | |||
562 | ||||
563 | // Fold the result constant immediately. | |||
564 | int64_t Result_Cst = LHS_Cst + RHS_Cst; | |||
565 | ||||
566 | assert((!Layout || Asm) &&(static_cast <bool> ((!Layout || Asm) && "Must have an assembler object if layout is given!" ) ? void (0) : __assert_fail ("(!Layout || Asm) && \"Must have an assembler object if layout is given!\"" , "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp" , 567, __extension__ __PRETTY_FUNCTION__)) | |||
567 | "Must have an assembler object if layout is given!")(static_cast <bool> ((!Layout || Asm) && "Must have an assembler object if layout is given!" ) ? void (0) : __assert_fail ("(!Layout || Asm) && \"Must have an assembler object if layout is given!\"" , "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp" , 567, __extension__ __PRETTY_FUNCTION__)); | |||
568 | ||||
569 | // If we have a layout, we can fold resolved differences. | |||
570 | if (Asm) { | |||
571 | // First, fold out any differences which are fully resolved. By | |||
572 | // reassociating terms in | |||
573 | // Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst). | |||
574 | // we have the four possible differences: | |||
575 | // (LHS_A - LHS_B), | |||
576 | // (LHS_A - RHS_B), | |||
577 | // (RHS_A - LHS_B), | |||
578 | // (RHS_A - RHS_B). | |||
579 | // Since we are attempting to be as aggressive as possible about folding, we | |||
580 | // attempt to evaluate each possible alternative. | |||
581 | AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, LHS_B, | |||
582 | Result_Cst); | |||
583 | AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, RHS_B, | |||
584 | Result_Cst); | |||
585 | AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, LHS_B, | |||
586 | Result_Cst); | |||
587 | AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, RHS_B, | |||
588 | Result_Cst); | |||
589 | } | |||
590 | ||||
591 | // We can't represent the addition or subtraction of two symbols. | |||
592 | if ((LHS_A && RHS_A) || (LHS_B && RHS_B)) | |||
593 | return false; | |||
594 | ||||
595 | // At this point, we have at most one additive symbol and one subtractive | |||
596 | // symbol -- find them. | |||
597 | const MCSymbolRefExpr *A = LHS_A ? LHS_A : RHS_A; | |||
598 | const MCSymbolRefExpr *B = LHS_B ? LHS_B : RHS_B; | |||
599 | ||||
600 | Res = MCValue::get(A, B, Result_Cst); | |||
601 | return true; | |||
602 | } | |||
603 | ||||
604 | bool MCExpr::evaluateAsRelocatable(MCValue &Res, | |||
605 | const MCAsmLayout *Layout, | |||
606 | const MCFixup *Fixup) const { | |||
607 | MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; | |||
608 | return evaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr, | |||
609 | false); | |||
610 | } | |||
611 | ||||
612 | bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const { | |||
613 | MCAssembler *Assembler = &Layout.getAssembler(); | |||
614 | return evaluateAsRelocatableImpl(Res, Assembler, &Layout, nullptr, nullptr, | |||
| ||||
615 | true); | |||
616 | } | |||
617 | ||||
618 | static bool canExpand(const MCSymbol &Sym, bool InSet) { | |||
619 | const MCExpr *Expr = Sym.getVariableValue(); | |||
620 | const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr); | |||
621 | if (Inner) { | |||
622 | if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) | |||
623 | return false; | |||
624 | } | |||
625 | ||||
626 | if (InSet) | |||
627 | return true; | |||
628 | return !Sym.isInSection(); | |||
629 | } | |||
630 | ||||
631 | bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, | |||
632 | const MCAsmLayout *Layout, | |||
633 | const MCFixup *Fixup, | |||
634 | const SectionAddrMap *Addrs, | |||
635 | bool InSet) const { | |||
636 | ++stats::MCExprEvaluate; | |||
637 | ||||
638 | switch (getKind()) { | |||
639 | case Target: | |||
640 | return cast<MCTargetExpr>(this)->evaluateAsRelocatableImpl(Res, Layout, | |||
641 | Fixup); | |||
642 | ||||
643 | case Constant: | |||
644 | Res = MCValue::get(cast<MCConstantExpr>(this)->getValue()); | |||
645 | return true; | |||
646 | ||||
647 | case SymbolRef: { | |||
648 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this); | |||
649 | const MCSymbol &Sym = SRE->getSymbol(); | |||
650 | ||||
651 | // Evaluate recursively if this is a variable. | |||
652 | if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None && | |||
653 | canExpand(Sym, InSet)) { | |||
654 | bool IsMachO = SRE->hasSubsectionsViaSymbols(); | |||
655 | if (Sym.getVariableValue()->evaluateAsRelocatableImpl( | |||
656 | Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) { | |||
657 | if (!IsMachO) | |||
658 | return true; | |||
659 | ||||
660 | const MCSymbolRefExpr *A = Res.getSymA(); | |||
661 | const MCSymbolRefExpr *B = Res.getSymB(); | |||
662 | // FIXME: This is small hack. Given | |||
663 | // a = b + 4 | |||
664 | // .long a | |||
665 | // the OS X assembler will completely drop the 4. We should probably | |||
666 | // include it in the relocation or produce an error if that is not | |||
667 | // possible. | |||
668 | // Allow constant expressions. | |||
669 | if (!A && !B) | |||
670 | return true; | |||
671 | // Allows aliases with zero offset. | |||
672 | if (Res.getConstant() == 0 && (!A || !B)) | |||
673 | return true; | |||
674 | } | |||
675 | } | |||
676 | ||||
677 | Res = MCValue::get(SRE, nullptr, 0); | |||
678 | return true; | |||
679 | } | |||
680 | ||||
681 | case Unary: { | |||
682 | const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this); | |||
683 | MCValue Value; | |||
684 | ||||
685 | if (!AUE->getSubExpr()->evaluateAsRelocatableImpl(Value, Asm, Layout, Fixup, | |||
686 | Addrs, InSet)) | |||
687 | return false; | |||
688 | ||||
689 | switch (AUE->getOpcode()) { | |||
690 | case MCUnaryExpr::LNot: | |||
691 | if (!Value.isAbsolute()) | |||
692 | return false; | |||
693 | Res = MCValue::get(!Value.getConstant()); | |||
694 | break; | |||
695 | case MCUnaryExpr::Minus: | |||
696 | /// -(a - b + const) ==> (b - a - const) | |||
697 | if (Value.getSymA() && !Value.getSymB()) | |||
698 | return false; | |||
699 | ||||
700 | // The cast avoids undefined behavior if the constant is INT64_MIN. | |||
701 | Res = MCValue::get(Value.getSymB(), Value.getSymA(), | |||
702 | -(uint64_t)Value.getConstant()); | |||
703 | break; | |||
704 | case MCUnaryExpr::Not: | |||
705 | if (!Value.isAbsolute()) | |||
706 | return false; | |||
707 | Res = MCValue::get(~Value.getConstant()); | |||
708 | break; | |||
709 | case MCUnaryExpr::Plus: | |||
710 | Res = Value; | |||
711 | break; | |||
712 | } | |||
713 | ||||
714 | return true; | |||
715 | } | |||
716 | ||||
717 | case Binary: { | |||
718 | const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this); | |||
719 | MCValue LHSValue, RHSValue; | |||
720 | ||||
721 | if (!ABE->getLHS()->evaluateAsRelocatableImpl(LHSValue, Asm, Layout, Fixup, | |||
722 | Addrs, InSet) || | |||
723 | !ABE->getRHS()->evaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup, | |||
724 | Addrs, InSet)) | |||
725 | return false; | |||
726 | ||||
727 | // We only support a few operations on non-constant expressions, handle | |||
728 | // those first. | |||
729 | if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) { | |||
730 | switch (ABE->getOpcode()) { | |||
731 | default: | |||
732 | return false; | |||
733 | case MCBinaryExpr::Sub: | |||
734 | // Negate RHS and add. | |||
735 | // The cast avoids undefined behavior if the constant is INT64_MIN. | |||
736 | return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue, | |||
737 | RHSValue.getSymB(), RHSValue.getSymA(), | |||
738 | -(uint64_t)RHSValue.getConstant(), Res); | |||
739 | ||||
740 | case MCBinaryExpr::Add: | |||
741 | return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue, | |||
742 | RHSValue.getSymA(), RHSValue.getSymB(), | |||
743 | RHSValue.getConstant(), Res); | |||
744 | } | |||
745 | } | |||
746 | ||||
747 | // FIXME: We need target hooks for the evaluation. It may be limited in | |||
748 | // width, and gas defines the result of comparisons differently from | |||
749 | // Apple as. | |||
750 | int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant(); | |||
751 | int64_t Result = 0; | |||
752 | switch (ABE->getOpcode()) { | |||
753 | case MCBinaryExpr::AShr: Result = LHS >> RHS; break; | |||
754 | case MCBinaryExpr::Add: Result = LHS + RHS; break; | |||
755 | case MCBinaryExpr::And: Result = LHS & RHS; break; | |||
756 | case MCBinaryExpr::Div: | |||
757 | // Handle division by zero. gas just emits a warning and keeps going, | |||
758 | // we try to be stricter. | |||
759 | // FIXME: Currently the caller of this function has no way to understand | |||
760 | // we're bailing out because of 'division by zero'. Therefore, it will | |||
761 | // emit a 'expected relocatable expression' error. It would be nice to | |||
762 | // change this code to emit a better diagnostic. | |||
763 | if (RHS == 0) | |||
764 | return false; | |||
765 | Result = LHS / RHS; | |||
766 | break; | |||
767 | case MCBinaryExpr::EQ: Result = LHS == RHS; break; | |||
768 | case MCBinaryExpr::GT: Result = LHS > RHS; break; | |||
769 | case MCBinaryExpr::GTE: Result = LHS >= RHS; break; | |||
770 | case MCBinaryExpr::LAnd: Result = LHS && RHS; break; | |||
771 | case MCBinaryExpr::LOr: Result = LHS || RHS; break; | |||
772 | case MCBinaryExpr::LShr: Result = uint64_t(LHS) >> uint64_t(RHS); break; | |||
773 | case MCBinaryExpr::LT: Result = LHS < RHS; break; | |||
774 | case MCBinaryExpr::LTE: Result = LHS <= RHS; break; | |||
775 | case MCBinaryExpr::Mod: Result = LHS % RHS; break; | |||
| ||||
776 | case MCBinaryExpr::Mul: Result = LHS * RHS; break; | |||
777 | case MCBinaryExpr::NE: Result = LHS != RHS; break; | |||
778 | case MCBinaryExpr::Or: Result = LHS | RHS; break; | |||
779 | case MCBinaryExpr::Shl: Result = uint64_t(LHS) << uint64_t(RHS); break; | |||
780 | case MCBinaryExpr::Sub: Result = LHS - RHS; break; | |||
781 | case MCBinaryExpr::Xor: Result = LHS ^ RHS; break; | |||
782 | } | |||
783 | ||||
784 | Res = MCValue::get(Result); | |||
785 | return true; | |||
786 | } | |||
787 | } | |||
788 | ||||
789 | llvm_unreachable("Invalid assembly expression kind!")::llvm::llvm_unreachable_internal("Invalid assembly expression kind!" , "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp" , 789); | |||
790 | } | |||
791 | ||||
792 | MCFragment *MCExpr::findAssociatedFragment() const { | |||
793 | switch (getKind()) { | |||
794 | case Target: | |||
795 | // We never look through target specific expressions. | |||
796 | return cast<MCTargetExpr>(this)->findAssociatedFragment(); | |||
797 | ||||
798 | case Constant: | |||
799 | return MCSymbol::AbsolutePseudoFragment; | |||
800 | ||||
801 | case SymbolRef: { | |||
802 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this); | |||
803 | const MCSymbol &Sym = SRE->getSymbol(); | |||
804 | return Sym.getFragment(); | |||
805 | } | |||
806 | ||||
807 | case Unary: | |||
808 | return cast<MCUnaryExpr>(this)->getSubExpr()->findAssociatedFragment(); | |||
809 | ||||
810 | case Binary: { | |||
811 | const MCBinaryExpr *BE = cast<MCBinaryExpr>(this); | |||
812 | MCFragment *LHS_F = BE->getLHS()->findAssociatedFragment(); | |||
813 | MCFragment *RHS_F = BE->getRHS()->findAssociatedFragment(); | |||
814 | ||||
815 | // If either is absolute, return the other. | |||
816 | if (LHS_F == MCSymbol::AbsolutePseudoFragment) | |||
817 | return RHS_F; | |||
818 | if (RHS_F == MCSymbol::AbsolutePseudoFragment) | |||
819 | return LHS_F; | |||
820 | ||||
821 | // Not always correct, but probably the best we can do without more context. | |||
822 | if (BE->getOpcode() == MCBinaryExpr::Sub) | |||
823 | return MCSymbol::AbsolutePseudoFragment; | |||
824 | ||||
825 | // Otherwise, return the first non-null fragment. | |||
826 | return LHS_F ? LHS_F : RHS_F; | |||
827 | } | |||
828 | } | |||
829 | ||||
830 | llvm_unreachable("Invalid assembly expression kind!")::llvm::llvm_unreachable_internal("Invalid assembly expression kind!" , "/build/llvm-toolchain-snapshot-7~svn325118/lib/MC/MCExpr.cpp" , 830); | |||
831 | } |
1 | //===-- llvm/MC/MCValue.h - MCValue class -----------------------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | // |
10 | // This file contains the declaration of the MCValue class. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_MC_MCVALUE_H |
15 | #define LLVM_MC_MCVALUE_H |
16 | |
17 | #include "llvm/MC/MCExpr.h" |
18 | #include "llvm/MC/MCSymbol.h" |
19 | #include "llvm/Support/DataTypes.h" |
20 | #include <cassert> |
21 | |
22 | namespace llvm { |
23 | class MCAsmInfo; |
24 | class raw_ostream; |
25 | |
26 | /// \brief This represents an "assembler immediate". |
27 | /// |
28 | /// In its most general form, this can hold ":Kind:(SymbolA - SymbolB + |
29 | /// imm64)". Not all targets supports relocations of this general form, but we |
30 | /// need to represent this anyway. |
31 | /// |
32 | /// In general both SymbolA and SymbolB will also have a modifier |
33 | /// analogous to the top-level Kind. Current targets are not expected |
34 | /// to make use of both though. The choice comes down to whether |
35 | /// relocation modifiers apply to the closest symbol or the whole |
36 | /// expression. |
37 | /// |
38 | /// Note that this class must remain a simple POD value class, because we need |
39 | /// it to live in unions etc. |
40 | class MCValue { |
41 | const MCSymbolRefExpr *SymA = nullptr, *SymB = nullptr; |
42 | int64_t Cst = 0; |
43 | uint32_t RefKind = 0; |
44 | |
45 | public: |
46 | MCValue() = default; |
47 | int64_t getConstant() const { return Cst; } |
48 | const MCSymbolRefExpr *getSymA() const { return SymA; } |
49 | const MCSymbolRefExpr *getSymB() const { return SymB; } |
50 | uint32_t getRefKind() const { return RefKind; } |
51 | |
52 | /// \brief Is this an absolute (as opposed to relocatable) value. |
53 | bool isAbsolute() const { return !SymA && !SymB; } |
54 | |
55 | /// \brief Print the value to the stream \p OS. |
56 | void print(raw_ostream &OS) const; |
57 | |
58 | /// \brief Print the value to stderr. |
59 | void dump() const; |
60 | |
61 | MCSymbolRefExpr::VariantKind getAccessVariant() const; |
62 | |
63 | static MCValue get(const MCSymbolRefExpr *SymA, |
64 | const MCSymbolRefExpr *SymB = nullptr, |
65 | int64_t Val = 0, uint32_t RefKind = 0) { |
66 | MCValue R; |
67 | R.Cst = Val; |
68 | R.SymA = SymA; |
69 | R.SymB = SymB; |
70 | R.RefKind = RefKind; |
71 | return R; |
72 | } |
73 | |
74 | static MCValue get(int64_t Val) { |
75 | MCValue R; |
76 | R.Cst = Val; |
77 | R.SymA = nullptr; |
78 | R.SymB = nullptr; |
79 | R.RefKind = 0; |
80 | return R; |
81 | } |
82 | |
83 | }; |
84 | |
85 | } // end namespace llvm |
86 | |
87 | #endif |
1 | //===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | // |
10 | // This file defines the 'Statistic' class, which is designed to be an easy way |
11 | // to expose various metrics from passes. These statistics are printed at the |
12 | // end of a run (from llvm_shutdown), when the -stats command line option is |
13 | // passed on the command line. |
14 | // |
15 | // This is useful for reporting information like the number of instructions |
16 | // simplified, optimized or removed by various transformations, like this: |
17 | // |
18 | // static Statistic NumInstsKilled("gcse", "Number of instructions killed"); |
19 | // |
20 | // Later, in the code: ++NumInstsKilled; |
21 | // |
22 | // NOTE: Statistics *must* be declared as global variables. |
23 | // |
24 | //===----------------------------------------------------------------------===// |
25 | |
26 | #ifndef LLVM_ADT_STATISTIC_H |
27 | #define LLVM_ADT_STATISTIC_H |
28 | |
29 | #include "llvm/Support/Compiler.h" |
30 | #include <atomic> |
31 | #include <memory> |
32 | |
33 | namespace llvm { |
34 | |
35 | class raw_ostream; |
36 | class raw_fd_ostream; |
37 | |
38 | class Statistic { |
39 | public: |
40 | const char *DebugType; |
41 | const char *Name; |
42 | const char *Desc; |
43 | std::atomic<unsigned> Value; |
44 | std::atomic<bool> Initialized; |
45 | |
46 | unsigned getValue() const { return Value.load(std::memory_order_relaxed); } |
47 | const char *getDebugType() const { return DebugType; } |
48 | const char *getName() const { return Name; } |
49 | const char *getDesc() const { return Desc; } |
50 | |
51 | /// construct - This should only be called for non-global statistics. |
52 | void construct(const char *debugtype, const char *name, const char *desc) { |
53 | DebugType = debugtype; |
54 | Name = name; |
55 | Desc = desc; |
56 | Value = 0; |
57 | Initialized = false; |
58 | } |
59 | |
60 | // Allow use of this class as the value itself. |
61 | operator unsigned() const { return getValue(); } |
62 | |
63 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) |
64 | const Statistic &operator=(unsigned Val) { |
65 | Value.store(Val, std::memory_order_relaxed); |
66 | return init(); |
67 | } |
68 | |
69 | const Statistic &operator++() { |
70 | Value.fetch_add(1, std::memory_order_relaxed); |
71 | return init(); |
72 | } |
73 | |
74 | unsigned operator++(int) { |
75 | init(); |
76 | return Value.fetch_add(1, std::memory_order_relaxed); |
77 | } |
78 | |
79 | const Statistic &operator--() { |
80 | Value.fetch_sub(1, std::memory_order_relaxed); |
81 | return init(); |
82 | } |
83 | |
84 | unsigned operator--(int) { |
85 | init(); |
86 | return Value.fetch_sub(1, std::memory_order_relaxed); |
87 | } |
88 | |
89 | const Statistic &operator+=(unsigned V) { |
90 | if (V == 0) |
91 | return *this; |
92 | Value.fetch_add(V, std::memory_order_relaxed); |
93 | return init(); |
94 | } |
95 | |
96 | const Statistic &operator-=(unsigned V) { |
97 | if (V == 0) |
98 | return *this; |
99 | Value.fetch_sub(V, std::memory_order_relaxed); |
100 | return init(); |
101 | } |
102 | |
103 | void updateMax(unsigned V) { |
104 | unsigned PrevMax = Value.load(std::memory_order_relaxed); |
105 | // Keep trying to update max until we succeed or another thread produces |
106 | // a bigger max than us. |
107 | while (V > PrevMax && !Value.compare_exchange_weak( |
108 | PrevMax, V, std::memory_order_relaxed)) { |
109 | } |
110 | init(); |
111 | } |
112 | |
113 | #else // Statistics are disabled in release builds. |
114 | |
115 | const Statistic &operator=(unsigned Val) { |
116 | return *this; |
117 | } |
118 | |
119 | const Statistic &operator++() { |
120 | return *this; |
121 | } |
122 | |
123 | unsigned operator++(int) { |
124 | return 0; |
125 | } |
126 | |
127 | const Statistic &operator--() { |
128 | return *this; |
129 | } |
130 | |
131 | unsigned operator--(int) { |
132 | return 0; |
133 | } |
134 | |
135 | const Statistic &operator+=(const unsigned &V) { |
136 | return *this; |
137 | } |
138 | |
139 | const Statistic &operator-=(const unsigned &V) { |
140 | return *this; |
141 | } |
142 | |
143 | void updateMax(unsigned V) {} |
144 | |
145 | #endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) |
146 | |
147 | protected: |
148 | Statistic &init() { |
149 | if (!Initialized.load(std::memory_order_acquire)) |
150 | RegisterStatistic(); |
151 | return *this; |
152 | } |
153 | |
154 | void RegisterStatistic(); |
155 | }; |
156 | |
157 | // STATISTIC - A macro to make definition of statistics really simple. This |
158 | // automatically passes the DEBUG_TYPE of the file into the statistic. |
159 | #define STATISTIC(VARNAME, DESC)static llvm::Statistic VARNAME = {"mcexpr", "VARNAME", DESC, { 0}, {false}} \ |
160 | static llvm::Statistic VARNAME = {DEBUG_TYPE"mcexpr", #VARNAME, DESC, {0}, {false}} |
161 | |
162 | /// \brief Enable the collection and printing of statistics. |
163 | void EnableStatistics(bool PrintOnExit = true); |
164 | |
165 | /// \brief Check if statistics are enabled. |
166 | bool AreStatisticsEnabled(); |
167 | |
168 | /// \brief Return a file stream to print our output on. |
169 | std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile(); |
170 | |
171 | /// \brief Print statistics to the file returned by CreateInfoOutputFile(). |
172 | void PrintStatistics(); |
173 | |
174 | /// \brief Print statistics to the given output stream. |
175 | void PrintStatistics(raw_ostream &OS); |
176 | |
177 | /// Print statistics in JSON format. This does include all global timers (\see |
178 | /// Timer, TimerGroup). Note that the timers are cleared after printing and will |
179 | /// not be printed in human readable form or in a second call of |
180 | /// PrintStatisticsJSON(). |
181 | void PrintStatisticsJSON(raw_ostream &OS); |
182 | |
183 | } // end namespace llvm |
184 | |
185 | #endif // LLVM_ADT_STATISTIC_H |