MCExpr.cpp revision b4d1721eff7b43577e5f2e53f885973fb6c43683
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#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" 23using namespace llvm; 24 25namespace { 26namespace stats { 27STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations"); 28} 29} 30 31void MCExpr::print(raw_ostream &OS) const { 32 switch (getKind()) { 33 case MCExpr::Target: 34 return cast<MCTargetExpr>(this)->PrintImpl(OS); 35 case MCExpr::Constant: 36 OS << cast<MCConstantExpr>(*this).getValue(); 37 return; 38 39 case MCExpr::SymbolRef: { 40 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*this); 41 const MCSymbol &Sym = SRE.getSymbol(); 42 43 if (SRE.getKind() == MCSymbolRefExpr::VK_ARM_HI16 || 44 SRE.getKind() == MCSymbolRefExpr::VK_ARM_LO16) 45 OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); 46 47 // Parenthesize names that start with $ so that they don't look like 48 // absolute names. 49 if (Sym.getName()[0] == '$') 50 OS << '(' << Sym << ')'; 51 else 52 OS << Sym; 53 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()); 60 61 return; 62 } 63 64 case MCExpr::Unary: { 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; 72 } 73 OS << *UE.getSubExpr(); 74 return; 75 } 76 77 case MCExpr::Binary: { 78 const MCBinaryExpr &BE = cast<MCBinaryExpr>(*this); 79 80 // Only print parens around the LHS if it is non-trivial. 81 if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) { 82 OS << *BE.getLHS(); 83 } else { 84 OS << '(' << *BE.getLHS() << ')'; 85 } 86 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(); 94 return; 95 } 96 } 97 98 OS << '+'; 99 break; 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; 117 } 118 119 // Only print parens around the LHS if it is non-trivial. 120 if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) { 121 OS << *BE.getRHS(); 122 } else { 123 OS << '(' << *BE.getRHS() << ')'; 124 } 125 return; 126 } 127 } 128 129 assert(0 && "Invalid expression kind!"); 130} 131 132void MCExpr::dump() const { 133 print(dbgs()); 134 dbgs() << '\n'; 135} 136 137/* *** */ 138 139const MCBinaryExpr *MCBinaryExpr::Create(Opcode Opc, const MCExpr *LHS, 140 const MCExpr *RHS, MCContext &Ctx) { 141 return new (Ctx) MCBinaryExpr(Opc, LHS, RHS); 142} 143 144const MCUnaryExpr *MCUnaryExpr::Create(Opcode Opc, const MCExpr *Expr, 145 MCContext &Ctx) { 146 return new (Ctx) MCUnaryExpr(Opc, Expr); 147} 148 149const MCConstantExpr *MCConstantExpr::Create(int64_t Value, MCContext &Ctx) { 150 return new (Ctx) MCConstantExpr(Value); 151} 152 153/* *** */ 154 155const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym, 156 VariantKind Kind, 157 MCContext &Ctx) { 158 return new (Ctx) MCSymbolRefExpr(Sym, Kind); 159} 160 161const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind, 162 MCContext &Ctx) { 163 return Create(Ctx.GetOrCreateSymbol(Name), Kind, Ctx); 164} 165 166StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { 167 switch (Kind) { 168 default: 169 case VK_Invalid: return "<<invalid>>"; 170 case VK_None: return "<<none>>"; 171 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"; 189 } 190} 191 192MCSymbolRefExpr::VariantKind 193MCSymbolRefExpr::getVariantKindForName(StringRef Name) { 194 return StringSwitch<VariantKind>(Name) 195 .Case("GOT", VK_GOT) 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) 202 .Case("PLT", VK_PLT) 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); 210} 211 212/* *** */ 213 214void MCTargetExpr::Anchor() {} 215 216/* *** */ 217 218bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout) const { 219 MCValue Value; 220 221 // Fast path constants. 222 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(this)) { 223 Res = CE->getValue(); 224 return true; 225 } 226 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. 231 if (Layout) { 232 Res = Value.getConstant(); 233 if (Value.getSymA()) { 234 Res += Layout->getSymbolAddress( 235 &Layout->getAssembler().getSymbolData(Value.getSymA()->getSymbol())); 236 } 237 if (Value.getSymB()) { 238 Res -= Layout->getSymbolAddress( 239 &Layout->getAssembler().getSymbolData(Value.getSymB()->getSymbol())); 240 } 241 } 242 return false; 243 } 244 245 Res = Value.getConstant(); 246 return true; 247} 248 249static bool EvaluateSymbolicAdd(const MCAsmLayout *Layout, bool InSet, 250 const MCValue &LHS,const MCSymbolRefExpr *RHS_A, 251 const MCSymbolRefExpr *RHS_B, int64_t RHS_Cst, 252 MCValue &Res) { 253 // We can't add or subtract two symbols. 254 if ((LHS.getSymA() && RHS_A) || 255 (LHS.getSymB() && RHS_B)) 256 return false; 257 258 const MCSymbolRefExpr *A = LHS.getSymA() ? LHS.getSymA() : RHS_A; 259 const MCSymbolRefExpr *B = LHS.getSymB() ? LHS.getSymB() : RHS_B; 260 if (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. 265 if (!A) 266 return false; 267 } 268 269 // Absolutize symbol differences between defined symbols when we have a 270 // layout object and the target requests it. 271 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) 283 + LHS.getConstant() 284 + RHS_Cst); 285 return true; 286 } 287 } 288 289 290 Res = MCValue::get(A, B, LHS.getConstant() + RHS_Cst); 291 return true; 292} 293 294bool MCExpr::EvaluateAsRelocatable(MCValue &Res, 295 const MCAsmLayout *Layout) const { 296 return EvaluateAsRelocatableImpl(Res, Layout, false); 297} 298 299bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 300 const MCAsmLayout *Layout, 301 bool InSet) const { 302 ++stats::MCExprEvaluate; 303 304 switch (getKind()) { 305 case Target: 306 return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res, Layout); 307 308 case Constant: 309 Res = MCValue::get(cast<MCConstantExpr>(this)->getValue()); 310 return true; 311 312 case SymbolRef: { 313 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this); 314 const MCSymbol &Sym = SRE->getSymbol(); 315 316 // Evaluate recursively if this is a variable. 317 if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) 318 return Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Layout, 319 true); 320 321 Res = MCValue::get(SRE, 0, 0); 322 return true; 323 } 324 325 case Unary: { 326 const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this); 327 MCValue Value; 328 329 if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Layout, InSet)) 330 return false; 331 332 switch (AUE->getOpcode()) { 333 case MCUnaryExpr::LNot: 334 if (!Value.isAbsolute()) 335 return false; 336 Res = MCValue::get(!Value.getConstant()); 337 break; 338 case MCUnaryExpr::Minus: 339 /// -(a - b + const) ==> (b - a - const) 340 if (Value.getSymA() && !Value.getSymB()) 341 return false; 342 Res = MCValue::get(Value.getSymB(), Value.getSymA(), 343 -Value.getConstant()); 344 break; 345 case MCUnaryExpr::Not: 346 if (!Value.isAbsolute()) 347 return false; 348 Res = MCValue::get(~Value.getConstant()); 349 break; 350 case MCUnaryExpr::Plus: 351 Res = Value; 352 break; 353 } 354 355 return true; 356 } 357 358 case Binary: { 359 const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this); 360 MCValue LHSValue, RHSValue; 361 362 if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Layout, InSet) || 363 !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Layout, InSet)) 364 return false; 365 366 // We only support a few operations on non-constant expressions, handle 367 // those first. 368 if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) { 369 switch (ABE->getOpcode()) { 370 default: 371 return false; 372 case MCBinaryExpr::Sub: 373 // Negate RHS and add. 374 return EvaluateSymbolicAdd(Layout, InSet, LHSValue, 375 RHSValue.getSymB(), RHSValue.getSymA(), 376 -RHSValue.getConstant(), 377 Res); 378 379 case MCBinaryExpr::Add: 380 return EvaluateSymbolicAdd(Layout, InSet, LHSValue, 381 RHSValue.getSymA(), RHSValue.getSymB(), 382 RHSValue.getConstant(), 383 Res); 384 } 385 } 386 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(); 391 int64_t Result = 0; 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; 411 } 412 413 Res = MCValue::get(Result); 414 return true; 415 } 416 } 417 418 assert(0 && "Invalid assembly expression kind!"); 419 return false; 420} 421