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/MCObjectFormat.h"
18 #include "llvm/MC/MCSymbol.h"
19 #include "llvm/MC/MCValue.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include "llvm/Target/TargetAsmBackend.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();
43 if (SRE
.getKind() == MCSymbolRefExpr::VK_ARM_HI16
||
44 SRE
.getKind() == MCSymbolRefExpr::VK_ARM_LO16
)
45 OS
<< MCSymbolRefExpr::getVariantKindName(SRE
.getKind());
47 // Parenthesize names that start with $ so that they don't look like
49 if (Sym
.getName()[0] == '$')
50 OS
<< '(' << Sym
<< ')';
54 if (SRE
.getKind() == MCSymbolRefExpr::VK_ARM_PLT
)
55 OS
<< MCSymbolRefExpr::getVariantKindName(SRE
.getKind());
56 else if (SRE
.getKind() != MCSymbolRefExpr::VK_None
&&
57 SRE
.getKind() != MCSymbolRefExpr::VK_ARM_HI16
&&
58 SRE
.getKind() != MCSymbolRefExpr::VK_ARM_LO16
)
59 OS
<< '@' << MCSymbolRefExpr::getVariantKindName(SRE
.getKind());
65 const MCUnaryExpr
&UE
= cast
<MCUnaryExpr
>(*this);
66 switch (UE
.getOpcode()) {
67 default: assert(0 && "Invalid opcode!");
68 case MCUnaryExpr::LNot
: OS
<< '!'; break;
69 case MCUnaryExpr::Minus
: OS
<< '-'; break;
70 case MCUnaryExpr::Not
: OS
<< '~'; break;
71 case MCUnaryExpr::Plus
: OS
<< '+'; break;
73 OS
<< *UE
.getSubExpr();
77 case MCExpr::Binary
: {
78 const MCBinaryExpr
&BE
= cast
<MCBinaryExpr
>(*this);
80 // Only print parens around the LHS if it is non-trivial.
81 if (isa
<MCConstantExpr
>(BE
.getLHS()) || isa
<MCSymbolRefExpr
>(BE
.getLHS())) {
84 OS
<< '(' << *BE
.getLHS() << ')';
87 switch (BE
.getOpcode()) {
88 default: assert(0 && "Invalid opcode!");
89 case MCBinaryExpr::Add
:
90 // Print "X-42" instead of "X+-42".
91 if (const MCConstantExpr
*RHSC
= dyn_cast
<MCConstantExpr
>(BE
.getRHS())) {
92 if (RHSC
->getValue() < 0) {
93 OS
<< RHSC
->getValue();
100 case MCBinaryExpr::And
: OS
<< '&'; break;
101 case MCBinaryExpr::Div
: OS
<< '/'; break;
102 case MCBinaryExpr::EQ
: OS
<< "=="; break;
103 case MCBinaryExpr::GT
: OS
<< '>'; break;
104 case MCBinaryExpr::GTE
: OS
<< ">="; break;
105 case MCBinaryExpr::LAnd
: OS
<< "&&"; break;
106 case MCBinaryExpr::LOr
: OS
<< "||"; break;
107 case MCBinaryExpr::LT
: OS
<< '<'; break;
108 case MCBinaryExpr::LTE
: OS
<< "<="; break;
109 case MCBinaryExpr::Mod
: OS
<< '%'; break;
110 case MCBinaryExpr::Mul
: OS
<< '*'; break;
111 case MCBinaryExpr::NE
: OS
<< "!="; break;
112 case MCBinaryExpr::Or
: OS
<< '|'; break;
113 case MCBinaryExpr::Shl
: OS
<< "<<"; break;
114 case MCBinaryExpr::Shr
: OS
<< ">>"; break;
115 case MCBinaryExpr::Sub
: OS
<< '-'; break;
116 case MCBinaryExpr::Xor
: OS
<< '^'; break;
119 // Only print parens around the LHS if it is non-trivial.
120 if (isa
<MCConstantExpr
>(BE
.getRHS()) || isa
<MCSymbolRefExpr
>(BE
.getRHS())) {
123 OS
<< '(' << *BE
.getRHS() << ')';
129 assert(0 && "Invalid expression kind!");
132 void MCExpr::dump() const {
139 const MCBinaryExpr
*MCBinaryExpr::Create(Opcode Opc
, const MCExpr
*LHS
,
140 const MCExpr
*RHS
, MCContext
&Ctx
) {
141 return new (Ctx
) MCBinaryExpr(Opc
, LHS
, RHS
);
144 const MCUnaryExpr
*MCUnaryExpr::Create(Opcode Opc
, const MCExpr
*Expr
,
146 return new (Ctx
) MCUnaryExpr(Opc
, Expr
);
149 const MCConstantExpr
*MCConstantExpr::Create(int64_t Value
, MCContext
&Ctx
) {
150 return new (Ctx
) MCConstantExpr(Value
);
155 const MCSymbolRefExpr
*MCSymbolRefExpr::Create(const MCSymbol
*Sym
,
158 return new (Ctx
) MCSymbolRefExpr(Sym
, Kind
);
161 const MCSymbolRefExpr
*MCSymbolRefExpr::Create(StringRef Name
, VariantKind Kind
,
163 return Create(Ctx
.GetOrCreateSymbol(Name
), Kind
, Ctx
);
166 StringRef
MCSymbolRefExpr::getVariantKindName(VariantKind Kind
) {
169 case VK_Invalid
: return "<<invalid>>";
170 case VK_None
: return "<<none>>";
172 case VK_GOT
: return "GOT";
173 case VK_GOTOFF
: return "GOTOFF";
174 case VK_GOTPCREL
: return "GOTPCREL";
175 case VK_GOTTPOFF
: return "GOTTPOFF";
176 case VK_INDNTPOFF
: return "INDNTPOFF";
177 case VK_NTPOFF
: return "NTPOFF";
178 case VK_GOTNTPOFF
: return "GOTNTPOFF";
179 case VK_PLT
: return "PLT";
180 case VK_TLSGD
: return "TLSGD";
181 case VK_TLSLD
: return "TLSLD";
182 case VK_TLSLDM
: return "TLSLDM";
183 case VK_TPOFF
: return "TPOFF";
184 case VK_DTPOFF
: return "DTPOFF";
185 case VK_ARM_HI16
: return ":upper16:";
186 case VK_ARM_LO16
: return ":lower16:";
187 case VK_ARM_PLT
: return "(PLT)";
188 case VK_TLVP
: return "TLVP";
192 MCSymbolRefExpr::VariantKind
193 MCSymbolRefExpr::getVariantKindForName(StringRef Name
) {
194 return StringSwitch
<VariantKind
>(Name
)
196 .Case("GOTOFF", VK_GOTOFF
)
197 .Case("GOTPCREL", VK_GOTPCREL
)
198 .Case("GOTTPOFF", VK_GOTTPOFF
)
199 .Case("INDNTPOFF", VK_INDNTPOFF
)
200 .Case("NTPOFF", VK_NTPOFF
)
201 .Case("GOTNTPOFF", VK_GOTNTPOFF
)
203 .Case("TLSGD", VK_TLSGD
)
204 .Case("TLSLD", VK_TLSLD
)
205 .Case("TLSLDM", VK_TLSLDM
)
206 .Case("TPOFF", VK_TPOFF
)
207 .Case("DTPOFF", VK_DTPOFF
)
208 .Case("TLVP", VK_TLVP
)
209 .Default(VK_Invalid
);
214 void MCTargetExpr::Anchor() {}
218 bool MCExpr::EvaluateAsAbsolute(int64_t &Res
, const MCAsmLayout
*Layout
) const {
221 // Fast path constants.
222 if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(this)) {
223 Res
= CE
->getValue();
227 if (!EvaluateAsRelocatable(Value
, Layout
) || !Value
.isAbsolute()) {
228 // EvaluateAsAbsolute is defined to return the "current value" of
229 // the expression if we are given a Layout object, even in cases
230 // when the value is not fixed.
232 Res
= Value
.getConstant();
233 if (Value
.getSymA()) {
234 Res
+= Layout
->getSymbolAddress(
235 &Layout
->getAssembler().getSymbolData(Value
.getSymA()->getSymbol()));
237 if (Value
.getSymB()) {
238 Res
-= Layout
->getSymbolAddress(
239 &Layout
->getAssembler().getSymbolData(Value
.getSymB()->getSymbol()));
245 Res
= Value
.getConstant();
249 static bool EvaluateSymbolicAdd(const MCAsmLayout
*Layout
, bool InSet
,
250 const MCValue
&LHS
,const MCSymbolRefExpr
*RHS_A
,
251 const MCSymbolRefExpr
*RHS_B
, int64_t RHS_Cst
,
253 // We can't add or subtract two symbols.
254 if ((LHS
.getSymA() && RHS_A
) ||
255 (LHS
.getSymB() && RHS_B
))
258 const MCSymbolRefExpr
*A
= LHS
.getSymA() ? LHS
.getSymA() : RHS_A
;
259 const MCSymbolRefExpr
*B
= LHS
.getSymB() ? LHS
.getSymB() : RHS_B
;
261 // If we have a negated symbol, then we must have also have a non-negated
262 // symbol in order to encode the expression. We can do this check later to
263 // permit expressions which eventually fold to a representable form -- such
264 // as (a + (0 - b)) -- if necessary.
269 // Absolutize symbol differences between defined symbols when we have a
270 // layout object and the target requests it.
272 if (Layout
&& A
&& B
) {
273 const MCSymbol
&SA
= A
->getSymbol();
274 const MCSymbol
&SB
= B
->getSymbol();
275 const MCObjectFormat
&F
=
276 Layout
->getAssembler().getBackend().getObjectFormat();
277 if (SA
.isDefined() && SB
.isDefined() && F
.isAbsolute(InSet
, SA
, SB
)) {
278 const MCAssembler
&Asm
= Layout
->getAssembler();
279 MCSymbolData
&AD
= Asm
.getSymbolData(A
->getSymbol());
280 MCSymbolData
&BD
= Asm
.getSymbolData(B
->getSymbol());
281 Res
= MCValue::get(+ Layout
->getSymbolAddress(&AD
)
282 - Layout
->getSymbolAddress(&BD
)
290 Res
= MCValue::get(A
, B
, LHS
.getConstant() + RHS_Cst
);
294 bool MCExpr::EvaluateAsRelocatable(MCValue
&Res
,
295 const MCAsmLayout
*Layout
) const {
296 return EvaluateAsRelocatableImpl(Res
, Layout
, false);
299 bool MCExpr::EvaluateAsRelocatableImpl(MCValue
&Res
,
300 const MCAsmLayout
*Layout
,
302 ++stats::MCExprEvaluate
;
306 return cast
<MCTargetExpr
>(this)->EvaluateAsRelocatableImpl(Res
, Layout
);
309 Res
= MCValue::get(cast
<MCConstantExpr
>(this)->getValue());
313 const MCSymbolRefExpr
*SRE
= cast
<MCSymbolRefExpr
>(this);
314 const MCSymbol
&Sym
= SRE
->getSymbol();
316 // Evaluate recursively if this is a variable.
317 if (Sym
.isVariable() && SRE
->getKind() == MCSymbolRefExpr::VK_None
)
318 return Sym
.getVariableValue()->EvaluateAsRelocatableImpl(Res
, Layout
,
321 Res
= MCValue::get(SRE
, 0, 0);
326 const MCUnaryExpr
*AUE
= cast
<MCUnaryExpr
>(this);
329 if (!AUE
->getSubExpr()->EvaluateAsRelocatableImpl(Value
, Layout
, InSet
))
332 switch (AUE
->getOpcode()) {
333 case MCUnaryExpr::LNot
:
334 if (!Value
.isAbsolute())
336 Res
= MCValue::get(!Value
.getConstant());
338 case MCUnaryExpr::Minus
:
339 /// -(a - b + const) ==> (b - a - const)
340 if (Value
.getSymA() && !Value
.getSymB())
342 Res
= MCValue::get(Value
.getSymB(), Value
.getSymA(),
343 -Value
.getConstant());
345 case MCUnaryExpr::Not
:
346 if (!Value
.isAbsolute())
348 Res
= MCValue::get(~Value
.getConstant());
350 case MCUnaryExpr::Plus
:
359 const MCBinaryExpr
*ABE
= cast
<MCBinaryExpr
>(this);
360 MCValue LHSValue
, RHSValue
;
362 if (!ABE
->getLHS()->EvaluateAsRelocatableImpl(LHSValue
, Layout
, InSet
) ||
363 !ABE
->getRHS()->EvaluateAsRelocatableImpl(RHSValue
, Layout
, InSet
))
366 // We only support a few operations on non-constant expressions, handle
368 if (!LHSValue
.isAbsolute() || !RHSValue
.isAbsolute()) {
369 switch (ABE
->getOpcode()) {
372 case MCBinaryExpr::Sub
:
373 // Negate RHS and add.
374 return EvaluateSymbolicAdd(Layout
, InSet
, LHSValue
,
375 RHSValue
.getSymB(), RHSValue
.getSymA(),
376 -RHSValue
.getConstant(),
379 case MCBinaryExpr::Add
:
380 return EvaluateSymbolicAdd(Layout
, InSet
, LHSValue
,
381 RHSValue
.getSymA(), RHSValue
.getSymB(),
382 RHSValue
.getConstant(),
387 // FIXME: We need target hooks for the evaluation. It may be limited in
388 // width, and gas defines the result of comparisons and right shifts
389 // differently from Apple as.
390 int64_t LHS
= LHSValue
.getConstant(), RHS
= RHSValue
.getConstant();
392 switch (ABE
->getOpcode()) {
393 case MCBinaryExpr::Add
: Result
= LHS
+ RHS
; break;
394 case MCBinaryExpr::And
: Result
= LHS
& RHS
; break;
395 case MCBinaryExpr::Div
: Result
= LHS
/ RHS
; break;
396 case MCBinaryExpr::EQ
: Result
= LHS
== RHS
; break;
397 case MCBinaryExpr::GT
: Result
= LHS
> RHS
; break;
398 case MCBinaryExpr::GTE
: Result
= LHS
>= RHS
; break;
399 case MCBinaryExpr::LAnd
: Result
= LHS
&& RHS
; break;
400 case MCBinaryExpr::LOr
: Result
= LHS
|| RHS
; break;
401 case MCBinaryExpr::LT
: Result
= LHS
< RHS
; break;
402 case MCBinaryExpr::LTE
: Result
= LHS
<= RHS
; break;
403 case MCBinaryExpr::Mod
: Result
= LHS
% RHS
; break;
404 case MCBinaryExpr::Mul
: Result
= LHS
* RHS
; break;
405 case MCBinaryExpr::NE
: Result
= LHS
!= RHS
; break;
406 case MCBinaryExpr::Or
: Result
= LHS
| RHS
; break;
407 case MCBinaryExpr::Shl
: Result
= LHS
<< RHS
; break;
408 case MCBinaryExpr::Shr
: Result
= LHS
>> RHS
; break;
409 case MCBinaryExpr::Sub
: Result
= LHS
- RHS
; break;
410 case MCBinaryExpr::Xor
: Result
= LHS
^ RHS
; break;
413 Res
= MCValue::get(Result
);
418 assert(0 && "Invalid assembly expression kind!");