12#include "llvm/Config/llvm-config.h"
30#define DEBUG_TYPE "mcexpr"
35STATISTIC(MCExprEvaluate,
"Number of MCExpr evaluations");
43 return cast<MCTargetExpr>(
this)->printImpl(
OS, MAI);
45 auto Value = cast<MCConstantExpr>(*this).getValue();
46 auto PrintInHex = cast<MCConstantExpr>(*this).useHexFormat();
47 auto SizeInBytes = cast<MCConstantExpr>(*this).getSizeInBytes();
48 if (Value < 0 && MAI && !MAI->supportsSignedData())
51 switch (SizeInBytes) {
78 Sym.getName().starts_with(
'$');
117 if (isa<MCConstantExpr>(BE.
getLHS()) || isa<MCSymbolRefExpr>(BE.
getLHS())) {
129 if (RHSC->getValue() < 0) {
130 OS << RHSC->getValue();
159 if (isa<MCConstantExpr>(BE.
getRHS()) || isa<MCSymbolRefExpr>(BE.
getRHS())) {
173#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
195 unsigned SizeInBytes) {
201MCSymbolRefExpr::MCSymbolRefExpr(
const MCSymbol *Symbol, VariantKind Kind,
204 encodeSubclassData(Kind, MAI->hasSubsectionsViaSymbols())),
224 case VK_None:
return "<<none>>";
228 case VK_GOT:
return "GOT";
239 case VK_PLT:
return "PLT";
351 return "got@tlsgd@pcrel";
353 return "got@tlsld@pcrel";
355 return "got@tprel@pcrel";
542void MCTargetExpr::anchor() {}
546bool MCExpr::evaluateAsAbsolute(int64_t &Res)
const {
547 return evaluateAsAbsolute(Res,
nullptr,
nullptr,
false);
550bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler &Asm,
554 return evaluateAsAbsolute(Res, &Asm, &Addrs,
true);
557bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler &Asm)
const {
558 return evaluateAsAbsolute(Res, &Asm,
nullptr,
false);
561bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler *Asm)
const {
562 return evaluateAsAbsolute(Res, Asm,
nullptr,
false);
566 return evaluateAsAbsolute(Res, &Asm,
nullptr,
true);
569bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler *Asm,
575 Res = CE->getValue();
583 Res =
Value.getConstant();
585 return IsRelocatable &&
Value.isAbsolute();
601 if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm,
A,
B, InSet))
604 auto FinalizeFolding = [&]() {
607 if (Asm->isThumbFunc(&SA))
619 if ((&SecA != &SecB) && !Addrs)
628 bool Layout = Asm->hasLayout();
630 !Asm->getBackend().allowLinkerRelaxation())) {
635 return FinalizeFolding();
639 Addend += Asm->getSymbolOffset(
A->getSymbol()) -
640 Asm->getSymbolOffset(
B->getSymbol());
641 if (Addrs && (&SecA != &SecB))
642 Addend += (Addrs->
lookup(&SecA) - Addrs->
lookup(&SecB));
676 bool BBeforeRelax =
false, AAfterRelax =
false;
677 for (
auto FI = FB; FI; FI = FI->
getNext()) {
678 auto DF = dyn_cast<MCDataFragment>(FI);
679 if (
DF &&
DF->isLinkerRelaxable()) {
680 if (&*FI != FB || SBOffset !=
DF->getContents().size())
682 if (&*FI != FA || SAOffset ==
DF->getContents().size())
684 if (BBeforeRelax && AAfterRelax)
690 Addend +=
Reverse ? -Displacement : Displacement;
698 Displacement +=
DF->getContents().size();
699 }
else if (
auto *AF = dyn_cast<MCAlignFragment>(FI);
700 AF && Layout && AF->hasEmitNops() &&
701 !Asm->getBackend().shouldInsertExtraNopBytesForCodeAlign(
703 Displacement += Asm->computeFragmentSize(*AF);
704 }
else if (
auto *FF = dyn_cast<MCFillFragment>(FI);
705 FF && FF->getNumValues().evaluateAsAbsolute(Num)) {
706 Displacement += Num * FF->getValueSize();
741 int64_t LHS_Cst =
LHS.getConstant();
745 int64_t RHS_Cst =
RHS.getConstant();
747 if (
LHS.getRefKind() !=
RHS.getRefKind())
751 int64_t Result_Cst = LHS_Cst + RHS_Cst;
776 if ((LHS_A && RHS_A) || (LHS_B && RHS_B))
798 if (
Sym.isWeakExternal())
801 const MCExpr *Expr =
Sym.getVariableValue();
802 const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
810 return !
Sym.isInSection();
817 ++stats::MCExprEvaluate;
820 return cast<MCTargetExpr>(
this)->evaluateAsRelocatableImpl(Res, Asm,
Fixup);
823 Res =
MCValue::get(cast<MCConstantExpr>(
this)->getValue());
829 const auto Kind = SRE->
getKind();
830 bool Layout = Asm && Asm->hasLayout();
836 if (
Sym.getVariableValue()->evaluateAsRelocatableImpl(
837 Res, Asm,
Fixup, Addrs, InSet || IsMachO)) {
851 Kind, Asm->getContext()),
888 if (!
Value.isAbsolute())
902 if (!
Value.isAbsolute())
950 Asm, Addrs, InSet, LHSValue,
958 Asm, Addrs, InSet, LHSValue,
1033 return cast<MCTargetExpr>(
this)->findAssociatedFragment();
1041 return Sym.getFragment();
1045 return cast<MCUnaryExpr>(
this)->getSubExpr()->findAssociatedFragment();
1063 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 RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static bool canExpand(const MCSymbol &Sym, bool InSet)
static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A, const MCSymbolRefExpr *&B, int64_t &Addend)
Helper method for.
static bool evaluateSymbolicAdd(const MCAssembler *Asm, const SectionAddrMap *Addrs, bool InSet, const MCValue &LHS, const MCValue &RHS, MCValue &Res)
Evaluate the result of an add between (conceptually) two MCValues.
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...
This class represents an Operation in the Expression.
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
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.
bool evaluateAsValue(MCValue &Res, const MCAssembler &Asm) const
Try to evaluate the expression to the form (a - b + constant) where neither a nor b are variables.
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup, const SectionAddrMap *Addrs, bool InSet) const
@ 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 MCAssembler &Asm) const
Aggressive variant of evaluateAsRelocatable when relocations are unavailable (e.g.
bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
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...
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
unsigned getLayoutOrder() const
MCSection * getParent() const
MCFragment * getNext() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
bool hasInstructions() const
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.
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.