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";
341 return "got@tlsgd@pcrel";
343 return "got@tlsld@pcrel";
345 return "got@tprel@pcrel";
538void MCTargetExpr::anchor() {}
542bool MCExpr::evaluateAsAbsolute(int64_t &Res)
const {
543 return evaluateAsAbsolute(Res,
nullptr,
nullptr,
nullptr,
false);
546bool MCExpr::evaluateAsAbsolute(int64_t &Res,
548 return evaluateAsAbsolute(Res, &Layout.
getAssembler(), &Layout,
nullptr,
false);
551bool MCExpr::evaluateAsAbsolute(int64_t &Res,
556 return evaluateAsAbsolute(Res, &Layout.
getAssembler(), &Layout, &Addrs,
true);
559bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler &Asm)
const {
560 return evaluateAsAbsolute(Res, &Asm,
nullptr,
nullptr,
false);
563bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler *Asm)
const {
564 return evaluateAsAbsolute(Res, Asm,
nullptr,
nullptr,
false);
569 return evaluateAsAbsolute(Res, &Layout.
getAssembler(), &Layout,
nullptr,
573bool MCExpr::evaluateAsAbsolute(int64_t &Res,
const MCAssembler *Asm,
580 Res = CE->getValue();
588 Res =
Value.getConstant();
590 return IsRelocatable &&
Value.isAbsolute();
607 if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm,
A,
B, InSet))
610 auto FinalizeFolding = [&]() {
613 if (Asm->isThumbFunc(&SA))
625 if ((&SecA != &SecB) && !Addrs)
635 !Asm->getContext().getTargetTriple().isRISCV())) {
640 return FinalizeFolding();
650 if (Addrs && (&SecA != &SecB))
651 Addend += (Addrs->
lookup(&SecA) - Addrs->
lookup(&SecB));
671 }
else if (!isa<MCDummyFragment>(FA)) {
673 [&](
auto &
I) { return &I == FB; }) != SecA.
end();
684 [[maybe_unused]]
bool Found =
false;
689 bool BBeforeRelax =
false, AAfterRelax =
false;
690 for (
auto FI = FB->
getIterator(), FE = SecA.
end(); FI != FE; ++FI) {
691 auto DF = dyn_cast<MCDataFragment>(FI);
692 if (
DF &&
DF->isLinkerRelaxable()) {
693 if (&*FI != FB || SBOffset !=
DF->getContents().size())
695 if (&*FI != FA || SAOffset ==
DF->getContents().size())
697 if (BBeforeRelax && AAfterRelax)
707 Displacement +=
DF->getContents().size();
708 }
else if (
auto *FF = dyn_cast<MCFillFragment>(FI);
709 FF && FF->getNumValues().evaluateAsAbsolute(Num)) {
710 Displacement += Num * FF->getValueSize();
718 assert(Found || isa<MCDummyFragment>(FA));
719 Addend +=
Reverse ? -Displacement : Displacement;
752 int64_t LHS_Cst =
LHS.getConstant();
756 int64_t RHS_Cst =
RHS.getConstant();
758 if (
LHS.getRefKind() !=
RHS.getRefKind())
762 int64_t Result_Cst = LHS_Cst + RHS_Cst;
764 assert((!Layout || Asm) &&
765 "Must have an assembler object if layout is given!");
790 if ((LHS_A && RHS_A) || (LHS_B && RHS_B))
817 if (
Sym.isWeakExternal())
820 const MCExpr *Expr =
Sym.getVariableValue();
821 const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
829 return !
Sym.isInSection();
837 ++stats::MCExprEvaluate;
841 return cast<MCTargetExpr>(
this)->evaluateAsRelocatableImpl(Res, Layout,
845 Res =
MCValue::get(cast<MCConstantExpr>(
this)->getValue());
851 const auto Kind = SRE->
getKind();
857 if (
Sym.getVariableValue()->evaluateAsRelocatableImpl(
858 Res, Asm, Layout,
Fixup, Addrs, InSet || IsMachO)) {
872 Kind, Asm->getContext()),
909 if (!
Value.isAbsolute())
923 if (!
Value.isAbsolute())
970 Asm, Layout, Addrs, InSet, LHSValue,
978 Asm, Layout, Addrs, InSet, LHSValue,
1053 return cast<MCTargetExpr>(
this)->findAssociatedFragment();
1061 return Sym.getFragment();
1065 return cast<MCUnaryExpr>(
this)->getSubExpr()->findAssociatedFragment();
1083 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 MCAsmLayout *Layout, const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A, const MCSymbolRefExpr *&B, int64_t &Addend)
Helper method for.
static bool EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout, 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
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)...
MCSection * getParent() const
unsigned getSubsectionNumber() 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.
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.