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