1
//===- MCExpr.cpp - Assembly Level Expression Implementation --------------===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
#define DEBUG_TYPE "mcexpr"
11
#include "llvm/MC/MCExpr.h"
12
#include "llvm/ADT/Statistic.h"
13
#include "llvm/ADT/StringSwitch.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/Debug.h"
21
#include "llvm/Support/ErrorHandling.h"
22
#include "llvm/Support/raw_ostream.h"
27
STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations");
31
void MCExpr::print(raw_ostream &OS) const {
34
return cast<MCTargetExpr>(this)->PrintImpl(OS);
35
case MCExpr::Constant:
36
OS << cast<MCConstantExpr>(*this).getValue();
39
case MCExpr::SymbolRef: {
40
const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*this);
41
const MCSymbol &Sym = SRE.getSymbol();
42
// Parenthesize names that start with $ so that they don't look like
44
bool UseParens = Sym.getName()[0] == '$';
46
if (SRE.getKind() == MCSymbolRefExpr::VK_PPC_DARWIN_HA16 ||
47
SRE.getKind() == MCSymbolRefExpr::VK_PPC_DARWIN_LO16) {
48
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
53
OS << '(' << Sym << ')';
57
if (SRE.getKind() == MCSymbolRefExpr::VK_ARM_PLT ||
58
SRE.getKind() == MCSymbolRefExpr::VK_ARM_TLSGD ||
59
SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOT ||
60
SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTOFF ||
61
SRE.getKind() == MCSymbolRefExpr::VK_ARM_TPOFF ||
62
SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF ||
63
SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET1)
64
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
65
else if (SRE.getKind() != MCSymbolRefExpr::VK_None &&
66
SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_HA16 &&
67
SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_LO16)
68
OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
74
const MCUnaryExpr &UE = cast<MCUnaryExpr>(*this);
75
switch (UE.getOpcode()) {
76
case MCUnaryExpr::LNot: OS << '!'; break;
77
case MCUnaryExpr::Minus: OS << '-'; break;
78
case MCUnaryExpr::Not: OS << '~'; break;
79
case MCUnaryExpr::Plus: OS << '+'; break;
81
OS << *UE.getSubExpr();
85
case MCExpr::Binary: {
86
const MCBinaryExpr &BE = cast<MCBinaryExpr>(*this);
88
// Only print parens around the LHS if it is non-trivial.
89
if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) {
92
OS << '(' << *BE.getLHS() << ')';
95
switch (BE.getOpcode()) {
96
case MCBinaryExpr::Add:
97
// Print "X-42" instead of "X+-42".
98
if (const MCConstantExpr *RHSC = dyn_cast<MCConstantExpr>(BE.getRHS())) {
99
if (RHSC->getValue() < 0) {
100
OS << RHSC->getValue();
107
case MCBinaryExpr::And: OS << '&'; break;
108
case MCBinaryExpr::Div: OS << '/'; break;
109
case MCBinaryExpr::EQ: OS << "=="; break;
110
case MCBinaryExpr::GT: OS << '>'; break;
111
case MCBinaryExpr::GTE: OS << ">="; break;
112
case MCBinaryExpr::LAnd: OS << "&&"; break;
113
case MCBinaryExpr::LOr: OS << "||"; break;
114
case MCBinaryExpr::LT: OS << '<'; break;
115
case MCBinaryExpr::LTE: OS << "<="; break;
116
case MCBinaryExpr::Mod: OS << '%'; break;
117
case MCBinaryExpr::Mul: OS << '*'; break;
118
case MCBinaryExpr::NE: OS << "!="; break;
119
case MCBinaryExpr::Or: OS << '|'; break;
120
case MCBinaryExpr::Shl: OS << "<<"; break;
121
case MCBinaryExpr::Shr: OS << ">>"; break;
122
case MCBinaryExpr::Sub: OS << '-'; break;
123
case MCBinaryExpr::Xor: OS << '^'; break;
126
// Only print parens around the LHS if it is non-trivial.
127
if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) {
130
OS << '(' << *BE.getRHS() << ')';
136
llvm_unreachable("Invalid expression kind!");
139
void MCExpr::dump() const {
146
const MCBinaryExpr *MCBinaryExpr::Create(Opcode Opc, const MCExpr *LHS,
147
const MCExpr *RHS, MCContext &Ctx) {
148
return new (Ctx) MCBinaryExpr(Opc, LHS, RHS);
151
const MCUnaryExpr *MCUnaryExpr::Create(Opcode Opc, const MCExpr *Expr,
153
return new (Ctx) MCUnaryExpr(Opc, Expr);
156
const MCConstantExpr *MCConstantExpr::Create(int64_t Value, MCContext &Ctx) {
157
return new (Ctx) MCConstantExpr(Value);
162
const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym,
165
return new (Ctx) MCSymbolRefExpr(Sym, Kind);
168
const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind,
170
return Create(Ctx.GetOrCreateSymbol(Name), Kind, Ctx);
173
StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
175
case VK_Invalid: return "<<invalid>>";
176
case VK_None: return "<<none>>";
178
case VK_GOT: return "GOT";
179
case VK_GOTOFF: return "GOTOFF";
180
case VK_GOTPCREL: return "GOTPCREL";
181
case VK_GOTTPOFF: return "GOTTPOFF";
182
case VK_INDNTPOFF: return "INDNTPOFF";
183
case VK_NTPOFF: return "NTPOFF";
184
case VK_GOTNTPOFF: return "GOTNTPOFF";
185
case VK_PLT: return "PLT";
186
case VK_TLSGD: return "TLSGD";
187
case VK_TLSLD: return "TLSLD";
188
case VK_TLSLDM: return "TLSLDM";
189
case VK_TPOFF: return "TPOFF";
190
case VK_DTPOFF: return "DTPOFF";
191
case VK_TLVP: return "TLVP";
192
case VK_SECREL: return "SECREL";
193
case VK_ARM_PLT: return "(PLT)";
194
case VK_ARM_GOT: return "(GOT)";
195
case VK_ARM_GOTOFF: return "(GOTOFF)";
196
case VK_ARM_TPOFF: return "(tpoff)";
197
case VK_ARM_GOTTPOFF: return "(gottpoff)";
198
case VK_ARM_TLSGD: return "(tlsgd)";
199
case VK_ARM_TARGET1: return "(target1)";
200
case VK_PPC_TOC: return "toc";
201
case VK_PPC_DARWIN_HA16: return "ha16";
202
case VK_PPC_DARWIN_LO16: return "lo16";
203
case VK_PPC_GAS_HA16: return "ha";
204
case VK_PPC_GAS_LO16: return "l";
205
case VK_Mips_GPREL: return "GPREL";
206
case VK_Mips_GOT_CALL: return "GOT_CALL";
207
case VK_Mips_GOT16: return "GOT16";
208
case VK_Mips_GOT: return "GOT";
209
case VK_Mips_ABS_HI: return "ABS_HI";
210
case VK_Mips_ABS_LO: return "ABS_LO";
211
case VK_Mips_TLSGD: return "TLSGD";
212
case VK_Mips_TLSLDM: return "TLSLDM";
213
case VK_Mips_DTPREL_HI: return "DTPREL_HI";
214
case VK_Mips_DTPREL_LO: return "DTPREL_LO";
215
case VK_Mips_GOTTPREL: return "GOTTPREL";
216
case VK_Mips_TPREL_HI: return "TPREL_HI";
217
case VK_Mips_TPREL_LO: return "TPREL_LO";
218
case VK_Mips_GPOFF_HI: return "GPOFF_HI";
219
case VK_Mips_GPOFF_LO: return "GPOFF_LO";
220
case VK_Mips_GOT_DISP: return "GOT_DISP";
221
case VK_Mips_GOT_PAGE: return "GOT_PAGE";
222
case VK_Mips_GOT_OFST: return "GOT_OFST";
224
llvm_unreachable("Invalid variant kind");
227
MCSymbolRefExpr::VariantKind
228
MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
229
return StringSwitch<VariantKind>(Name)
232
.Case("GOTOFF", VK_GOTOFF)
233
.Case("gotoff", VK_GOTOFF)
234
.Case("GOTPCREL", VK_GOTPCREL)
235
.Case("gotpcrel", VK_GOTPCREL)
236
.Case("GOTTPOFF", VK_GOTTPOFF)
237
.Case("gottpoff", VK_GOTTPOFF)
238
.Case("INDNTPOFF", VK_INDNTPOFF)
239
.Case("indntpoff", VK_INDNTPOFF)
240
.Case("NTPOFF", VK_NTPOFF)
241
.Case("ntpoff", VK_NTPOFF)
242
.Case("GOTNTPOFF", VK_GOTNTPOFF)
243
.Case("gotntpoff", VK_GOTNTPOFF)
246
.Case("TLSGD", VK_TLSGD)
247
.Case("tlsgd", VK_TLSGD)
248
.Case("TLSLD", VK_TLSLD)
249
.Case("tlsld", VK_TLSLD)
250
.Case("TLSLDM", VK_TLSLDM)
251
.Case("tlsldm", VK_TLSLDM)
252
.Case("TPOFF", VK_TPOFF)
253
.Case("tpoff", VK_TPOFF)
254
.Case("DTPOFF", VK_DTPOFF)
255
.Case("dtpoff", VK_DTPOFF)
256
.Case("TLVP", VK_TLVP)
257
.Case("tlvp", VK_TLVP)
258
.Default(VK_Invalid);
263
void MCTargetExpr::Anchor() {}
267
bool MCExpr::EvaluateAsAbsolute(int64_t &Res) const {
268
return EvaluateAsAbsolute(Res, 0, 0, 0);
271
bool MCExpr::EvaluateAsAbsolute(int64_t &Res,
272
const MCAsmLayout &Layout) const {
273
return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, 0);
276
bool MCExpr::EvaluateAsAbsolute(int64_t &Res,
277
const MCAsmLayout &Layout,
278
const SectionAddrMap &Addrs) const {
279
return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, &Addrs);
282
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const {
283
return EvaluateAsAbsolute(Res, &Asm, 0, 0);
286
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
287
const MCAsmLayout *Layout,
288
const SectionAddrMap *Addrs) const {
291
// Fast path constants.
292
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(this)) {
293
Res = CE->getValue();
297
// FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us
298
// absolutize differences across sections and that is what the MachO writer
301
EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs);
303
// Record the current value.
304
Res = Value.getConstant();
306
return IsRelocatable && Value.isAbsolute();
309
/// \brief Helper method for \see EvaluateSymbolAdd().
310
static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
311
const MCAsmLayout *Layout,
312
const SectionAddrMap *Addrs,
314
const MCSymbolRefExpr *&A,
315
const MCSymbolRefExpr *&B,
320
const MCSymbol &SA = A->getSymbol();
321
const MCSymbol &SB = B->getSymbol();
323
if (SA.isUndefined() || SB.isUndefined())
326
if (!Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
329
MCSymbolData &AD = Asm->getSymbolData(SA);
330
MCSymbolData &BD = Asm->getSymbolData(SB);
332
if (AD.getFragment() == BD.getFragment()) {
333
Addend += (AD.getOffset() - BD.getOffset());
335
// Pointers to Thumb symbols need to have their low-bit set to allow
337
if (Asm->isThumbFunc(&SA))
340
// Clear the symbol expr pointers to indicate we have folded these
349
const MCSectionData &SecA = *AD.getFragment()->getParent();
350
const MCSectionData &SecB = *BD.getFragment()->getParent();
352
if ((&SecA != &SecB) && !Addrs)
356
Addend += (Layout->getSymbolOffset(&Asm->getSymbolData(A->getSymbol())) -
357
Layout->getSymbolOffset(&Asm->getSymbolData(B->getSymbol())));
358
if (Addrs && (&SecA != &SecB))
359
Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB));
361
// Pointers to Thumb symbols need to have their low-bit set to allow
363
if (Asm->isThumbFunc(&SA))
366
// Clear the symbol expr pointers to indicate we have folded these
371
/// \brief Evaluate the result of an add between (conceptually) two MCValues.
373
/// This routine conceptually attempts to construct an MCValue:
374
/// Result = (Result_A - Result_B + Result_Cst)
375
/// from two MCValue's LHS and RHS where
376
/// Result = LHS + RHS
378
/// Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
380
/// This routine attempts to aggresively fold the operands such that the result
381
/// is representable in an MCValue, but may not always succeed.
383
/// \returns True on success, false if the result is not representable in an
386
/// NOTE: It is really important to have both the Asm and Layout arguments.
387
/// They might look redundant, but this function can be used before layout
388
/// is done (see the object streamer for example) and having the Asm argument
389
/// lets us avoid relaxations early.
390
static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
391
const MCAsmLayout *Layout,
392
const SectionAddrMap *Addrs,
394
const MCValue &LHS,const MCSymbolRefExpr *RHS_A,
395
const MCSymbolRefExpr *RHS_B, int64_t RHS_Cst,
397
// FIXME: This routine (and other evaluation parts) are *incredibly* sloppy
398
// about dealing with modifiers. This will ultimately bite us, one day.
399
const MCSymbolRefExpr *LHS_A = LHS.getSymA();
400
const MCSymbolRefExpr *LHS_B = LHS.getSymB();
401
int64_t LHS_Cst = LHS.getConstant();
403
// Fold the result constant immediately.
404
int64_t Result_Cst = LHS_Cst + RHS_Cst;
406
assert((!Layout || Asm) &&
407
"Must have an assembler object if layout is given!");
409
// If we have a layout, we can fold resolved differences.
411
// First, fold out any differences which are fully resolved. By
412
// reassociating terms in
413
// Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
414
// we have the four possible differences:
419
// Since we are attempting to be as aggressive as possible about folding, we
420
// attempt to evaluate each possible alternative.
421
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, LHS_B,
423
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, RHS_B,
425
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, LHS_B,
427
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, RHS_B,
431
// We can't represent the addition or subtraction of two symbols.
432
if ((LHS_A && RHS_A) || (LHS_B && RHS_B))
435
// At this point, we have at most one additive symbol and one subtractive
436
// symbol -- find them.
437
const MCSymbolRefExpr *A = LHS_A ? LHS_A : RHS_A;
438
const MCSymbolRefExpr *B = LHS_B ? LHS_B : RHS_B;
440
// If we have a negated symbol, then we must have also have a non-negated
441
// symbol in order to encode the expression.
445
Res = MCValue::get(A, B, Result_Cst);
449
bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
450
const MCAsmLayout &Layout) const {
451
return EvaluateAsRelocatableImpl(Res, &Layout.getAssembler(), &Layout,
455
bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
456
const MCAssembler *Asm,
457
const MCAsmLayout *Layout,
458
const SectionAddrMap *Addrs,
460
++stats::MCExprEvaluate;
464
return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res, Layout);
467
Res = MCValue::get(cast<MCConstantExpr>(this)->getValue());
471
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
472
const MCSymbol &Sym = SRE->getSymbol();
474
// Evaluate recursively if this is a variable.
475
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
476
bool Ret = Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Asm,
480
// If we failed to simplify this to a constant, let the target
482
if (Ret && !Res.getSymA() && !Res.getSymB())
486
Res = MCValue::get(SRE, 0, 0);
491
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
494
if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout,
498
switch (AUE->getOpcode()) {
499
case MCUnaryExpr::LNot:
500
if (!Value.isAbsolute())
502
Res = MCValue::get(!Value.getConstant());
504
case MCUnaryExpr::Minus:
505
/// -(a - b + const) ==> (b - a - const)
506
if (Value.getSymA() && !Value.getSymB())
508
Res = MCValue::get(Value.getSymB(), Value.getSymA(),
509
-Value.getConstant());
511
case MCUnaryExpr::Not:
512
if (!Value.isAbsolute())
514
Res = MCValue::get(~Value.getConstant());
516
case MCUnaryExpr::Plus:
525
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
526
MCValue LHSValue, RHSValue;
528
if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout,
530
!ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout,
534
// We only support a few operations on non-constant expressions, handle
536
if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) {
537
switch (ABE->getOpcode()) {
540
case MCBinaryExpr::Sub:
541
// Negate RHS and add.
542
return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
543
RHSValue.getSymB(), RHSValue.getSymA(),
544
-RHSValue.getConstant(),
547
case MCBinaryExpr::Add:
548
return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
549
RHSValue.getSymA(), RHSValue.getSymB(),
550
RHSValue.getConstant(),
555
// FIXME: We need target hooks for the evaluation. It may be limited in
556
// width, and gas defines the result of comparisons and right shifts
557
// differently from Apple as.
558
int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant();
560
switch (ABE->getOpcode()) {
561
case MCBinaryExpr::Add: Result = LHS + RHS; break;
562
case MCBinaryExpr::And: Result = LHS & RHS; break;
563
case MCBinaryExpr::Div: Result = LHS / RHS; break;
564
case MCBinaryExpr::EQ: Result = LHS == RHS; break;
565
case MCBinaryExpr::GT: Result = LHS > RHS; break;
566
case MCBinaryExpr::GTE: Result = LHS >= RHS; break;
567
case MCBinaryExpr::LAnd: Result = LHS && RHS; break;
568
case MCBinaryExpr::LOr: Result = LHS || RHS; break;
569
case MCBinaryExpr::LT: Result = LHS < RHS; break;
570
case MCBinaryExpr::LTE: Result = LHS <= RHS; break;
571
case MCBinaryExpr::Mod: Result = LHS % RHS; break;
572
case MCBinaryExpr::Mul: Result = LHS * RHS; break;
573
case MCBinaryExpr::NE: Result = LHS != RHS; break;
574
case MCBinaryExpr::Or: Result = LHS | RHS; break;
575
case MCBinaryExpr::Shl: Result = LHS << RHS; break;
576
case MCBinaryExpr::Shr: Result = LHS >> RHS; break;
577
case MCBinaryExpr::Sub: Result = LHS - RHS; break;
578
case MCBinaryExpr::Xor: Result = LHS ^ RHS; break;
581
Res = MCValue::get(Result);
586
llvm_unreachable("Invalid assembly expression kind!");
589
const MCSection *MCExpr::FindAssociatedSection() const {
592
// We never look through target specific expressions.
593
return cast<MCTargetExpr>(this)->FindAssociatedSection();
596
return MCSymbol::AbsolutePseudoSection;
599
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
600
const MCSymbol &Sym = SRE->getSymbol();
603
return &Sym.getSection();
609
return cast<MCUnaryExpr>(this)->getSubExpr()->FindAssociatedSection();
612
const MCBinaryExpr *BE = cast<MCBinaryExpr>(this);
613
const MCSection *LHS_S = BE->getLHS()->FindAssociatedSection();
614
const MCSection *RHS_S = BE->getRHS()->FindAssociatedSection();
616
// If either section is absolute, return the other.
617
if (LHS_S == MCSymbol::AbsolutePseudoSection)
619
if (RHS_S == MCSymbol::AbsolutePseudoSection)
622
// Otherwise, return the first non-null section.
623
return LHS_S ? LHS_S : RHS_S;
627
llvm_unreachable("Invalid assembly expression kind!");