12#include "llvm/Config/llvm-config.h"
31#define DEBUG_TYPE "mcexpr"
36STATISTIC(MCExprEvaluate,
"Number of MCExpr evaluations");
44 return cast<MCTargetExpr>(
this)->printImpl(
OS, MAI);
46 auto Value = cast<MCConstantExpr>(*this).getValue();
47 auto PrintInHex = cast<MCConstantExpr>(*this).useHexFormat();
48 auto SizeInBytes = cast<MCConstantExpr>(*this).getSizeInBytes();
49 if (Value < 0 && MAI && !MAI->supportsSignedData())
52 switch (SizeInBytes) {
79 !
Sym.getName().empty() &&
Sym.getName()[0] ==
'$';
118 if (isa<MCConstantExpr>(BE.
getLHS()) || isa<MCSymbolRefExpr>(BE.
getLHS())) {
130 if (RHSC->getValue() < 0) {
131 OS << RHSC->getValue();
160 if (isa<MCConstantExpr>(BE.
getRHS()) || isa<MCSymbolRefExpr>(BE.
getRHS())) {
174#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
196 unsigned SizeInBytes) {
202MCSymbolRefExpr::MCSymbolRefExpr(
const MCSymbol *Symbol, VariantKind Kind,
205 encodeSubclassData(Kind, MAI->hasSubsectionsViaSymbols())),
224 case VK_None:
return "<<none>>";
228 case VK_GOT:
return "GOT";
238 case VK_PLT:
return "PLT";
337 return "got@tlsgd@pcrel";
339 return "got@tlsld@pcrel";
341 return "got@tprel@pcrel";
532void MCTargetExpr::anchor() {}
536bool MCExpr::evaluateAsAbsolute(int64_t &Res)
const {
537 return evaluateAsAbsolute(Res,
nullptr,
nullptr,
nullptr,
false);
540bool MCExpr::evaluateAsAbsolute(int64_t &Res,
542 return evaluateAsAbsolute(Res, &Layout.
getAssembler(), &Layout,
nullptr,
false);
545bool MCExpr::evaluateAsAbsolute(int64_t &Res,
550 return evaluateAsAbsolute(Res, &Layout.
getAssembler(), &Layout, &Addrs,
true);
553bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler &Asm)
const {
554 return evaluateAsAbsolute(Res, &Asm,
nullptr,
nullptr,
false);
557bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler *Asm)
const {
558 return evaluateAsAbsolute(Res, Asm,
nullptr,
nullptr,
false);
563 return evaluateAsAbsolute(Res, &Layout.
getAssembler(), &Layout,
nullptr,
567bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler *Asm,
574 Res = CE->getValue();
582 Res =
Value.getConstant();
584 return IsRelocatable &&
Value.isAbsolute();
601 if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm,
A,
B, InSet))
604 auto FinalizeFolding = [&]() {
607 if (Asm->isThumbFunc(&SA))
612 if (Asm->getBackend().isMicroMips(&SA))
627 return FinalizeFolding();
633 if ((&SecA != &SecB) && !Addrs)
645 if (Addrs && (&SecA != &SecB))
646 Addend += (Addrs->
lookup(&SecA) - Addrs->
lookup(&SecB));
665 for (
auto FI = FB->
getIterator(), FE = SecA.
end(); FI != FE; ++FI) {
667 Addend += Displacement;
668 return FinalizeFolding();
673 Displacement += cast<MCDataFragment>(FI)->getContents().size();
701 int64_t RHS_Cst,
MCValue &Res) {
706 int64_t LHS_Cst =
LHS.getConstant();
709 int64_t Result_Cst = LHS_Cst + RHS_Cst;
711 assert((!Layout || Asm) &&
712 "Must have an assembler object if layout is given!");
737 if ((LHS_A && RHS_A) || (LHS_B && RHS_B))
764 const MCExpr *Expr =
Sym.getVariableValue();
765 const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
773 return !
Sym.isInSection();
781 ++stats::MCExprEvaluate;
785 return cast<MCTargetExpr>(
this)->evaluateAsRelocatableImpl(Res, Layout,
789 Res =
MCValue::get(cast<MCConstantExpr>(
this)->getValue());
795 const auto Kind = SRE->
getKind();
801 if (
Sym.getVariableValue()->evaluateAsRelocatableImpl(
802 Res, Asm, Layout,
Fixup, Addrs, InSet || IsMachO)) {
816 Kind, Asm->getContext()),
853 if (!
Value.isAbsolute())
867 if (!
Value.isAbsolute())
992 return cast<MCTargetExpr>(
this)->findAssociatedFragment();
1000 return Sym.getFragment();
1004 return cast<MCUnaryExpr>(
this)->getSubExpr()->findAssociatedFragment();
1022 return LHS_F ? LHS_F : RHS_F;
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static bool canExpand(const MCSymbol &Sym, bool InSet)
static bool EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout, const SectionAddrMap *Addrs, bool InSet, const MCValue &LHS, const MCSymbolRefExpr *RHS_A, const MCSymbolRefExpr *RHS_B, int64_t RHS_Cst, MCValue &Res)
Evaluate the result of an add between (conceptually) two MCValues.
static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, const MCAsmLayout *Layout, const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A, const MCSymbolRefExpr *&B, int64_t &Addend)
Helper method for.
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
This class is intended to be used as a base class for asm properties and features specific to the tar...
bool useParensForSymbolVariant() const
bool useParensForDollarSignNames() const
Encapsulates the layout of an assembly file at a particular point in time.
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
bool canGetFragmentOffset(const MCFragment *F) const
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ AShr
Arithmetic shift right.
@ LShr
Logical shift right.
@ GTE
Signed greater than or equal comparison (result is either 0 or some target-specific non-zero value).
@ GT
Signed greater than comparison (result is either 0 or some target-specific non-zero value)
@ Xor
Bitwise exclusive or.
@ LT
Signed less than comparison (result is either 0 or some target-specific non-zero value).
@ LTE
Signed less than or equal comparison (result is either 0 or some target-specific non-zero value).
@ NE
Inequality comparison.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCAsmInfo * getAsmInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, const SectionAddrMap *Addrs, bool InSet) const
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
MCFragment * findAssociatedFragment() const
Find the "associated section" for this expression, which is currently defined as the absolute section...
bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const
Try to evaluate the expression to the form (a - b + constant) where neither a nor b are variables.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
FragmentType getKind() const
MCSection * getParent() const
unsigned getSubsectionNumber() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static StringRef getVariantKindName(VariantKind Kind)
static VariantKind getVariantKindForName(StringRef Name)
@ VK_AMDGPU_GOTPCREL32_LO
@ VK_AMDGPU_GOTPCREL32_HI
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
bool hasSubsectionsViaSymbols() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVariable() const
isVariable - Check if this is a variable symbol.
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
static MCFragment * AbsolutePseudoFragment
uint64_t getOffset() const
MCFragment * getFragment(bool SetUsed=true) const
This is an extension point for target-specific MCExpr subclasses to implement.
Unary assembler expressions.
Opcode getOpcode() const
Get the kind of this unary expression.
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getSubExpr() const
Get the child of this unary expression.
This represents an "assembler immediate".
int64_t getConstant() const
uint32_t getRefKind() const
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)
const MCSymbolRefExpr * getSymB() const
const MCSymbolRefExpr * getSymA() const
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
Represents a location in source code.
StringRef - Represent a constant reference to a string, i.e.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
static Twine utohexstr(const uint64_t &Val)
LLVM Value Representation.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.