File indexing completed on 2026-05-10 08:44:13
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_MC_MCEXPR_H
0010 #define LLVM_MC_MCEXPR_H
0011
0012 #include "llvm/ADT/DenseMap.h"
0013 #include "llvm/Support/SMLoc.h"
0014 #include <cstdint>
0015
0016 namespace llvm {
0017
0018 class MCAsmInfo;
0019 class MCAssembler;
0020 class MCContext;
0021 class MCFixup;
0022 class MCFragment;
0023 class MCSection;
0024 class MCStreamer;
0025 class MCSymbol;
0026 class MCValue;
0027 class raw_ostream;
0028 class StringRef;
0029
0030 using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
0031
0032
0033
0034 class MCExpr {
0035 public:
0036 enum ExprKind : uint8_t {
0037 Binary,
0038 Constant,
0039 SymbolRef,
0040 Unary,
0041 Target
0042 };
0043
0044 private:
0045 static const unsigned NumSubclassDataBits = 24;
0046 static_assert(
0047 NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)),
0048 "ExprKind and SubclassData together should take up one word");
0049
0050 ExprKind Kind;
0051
0052 unsigned SubclassData : NumSubclassDataBits;
0053 SMLoc Loc;
0054
0055 bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
0056 const SectionAddrMap *Addrs, bool InSet) const;
0057
0058 protected:
0059 explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0)
0060 : Kind(Kind), SubclassData(SubclassData), Loc(Loc) {
0061 assert(SubclassData < (1 << NumSubclassDataBits) &&
0062 "Subclass data too large");
0063 }
0064
0065 bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
0066 const MCFixup *Fixup,
0067 const SectionAddrMap *Addrs, bool InSet) const;
0068
0069 unsigned getSubclassData() const { return SubclassData; }
0070
0071 public:
0072 MCExpr(const MCExpr &) = delete;
0073 MCExpr &operator=(const MCExpr &) = delete;
0074
0075
0076
0077
0078 ExprKind getKind() const { return Kind; }
0079 SMLoc getLoc() const { return Loc; }
0080
0081
0082
0083
0084
0085 void print(raw_ostream &OS, const MCAsmInfo *MAI,
0086 bool InParens = false) const;
0087 void dump() const;
0088
0089
0090
0091 bool isSymbolUsedInExpression(const MCSymbol *Sym) const;
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm,
0102 const SectionAddrMap &Addrs) const;
0103 bool evaluateAsAbsolute(int64_t &Res) const;
0104 bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
0105 bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const;
0106
0107
0108
0109
0110 bool evaluateKnownAbsolute(int64_t &Res, const MCAssembler &Asm) const;
0111
0112
0113
0114
0115
0116
0117
0118
0119 bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm,
0120 const MCFixup *Fixup) const;
0121
0122
0123
0124
0125
0126
0127 bool evaluateAsValue(MCValue &Res, const MCAssembler &Asm) const;
0128
0129
0130
0131
0132
0133 MCFragment *findAssociatedFragment() const;
0134
0135
0136 };
0137
0138 inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
0139 E.print(OS, nullptr);
0140 return OS;
0141 }
0142
0143
0144 class MCConstantExpr : public MCExpr {
0145 int64_t Value;
0146
0147
0148 static const unsigned SizeInBytesBits = 8;
0149 static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1;
0150 static const unsigned PrintInHexBit = 1 << SizeInBytesBits;
0151
0152 static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) {
0153 assert(SizeInBytes <= sizeof(int64_t) && "Excessive size");
0154 return SizeInBytes | (PrintInHex ? PrintInHexBit : 0);
0155 }
0156
0157 MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes)
0158 : MCExpr(MCExpr::Constant, SMLoc(),
0159 encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {}
0160
0161 public:
0162
0163
0164
0165 static const MCConstantExpr *create(int64_t Value, MCContext &Ctx,
0166 bool PrintInHex = false,
0167 unsigned SizeInBytes = 0);
0168
0169
0170
0171
0172
0173 int64_t getValue() const { return Value; }
0174 unsigned getSizeInBytes() const {
0175 return getSubclassData() & SizeInBytesMask;
0176 }
0177
0178 bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; }
0179
0180
0181
0182 static bool classof(const MCExpr *E) {
0183 return E->getKind() == MCExpr::Constant;
0184 }
0185 };
0186
0187
0188
0189
0190
0191
0192 class MCSymbolRefExpr : public MCExpr {
0193 public:
0194 enum VariantKind : uint16_t {
0195 VK_None,
0196 VK_Invalid,
0197
0198 VK_GOT,
0199 VK_GOTENT,
0200 VK_GOTOFF,
0201 VK_GOTREL,
0202 VK_PCREL,
0203 VK_GOTPCREL,
0204 VK_GOTPCREL_NORELAX,
0205 VK_GOTTPOFF,
0206 VK_INDNTPOFF,
0207 VK_NTPOFF,
0208 VK_GOTNTPOFF,
0209 VK_PLT,
0210 VK_TLSGD,
0211 VK_TLSLD,
0212 VK_TLSLDM,
0213 VK_TPOFF,
0214 VK_DTPOFF,
0215 VK_TLSCALL,
0216 VK_TLSDESC,
0217 VK_TLVP,
0218 VK_TLVPPAGE,
0219 VK_TLVPPAGEOFF,
0220 VK_PAGE,
0221 VK_PAGEOFF,
0222 VK_GOTPAGE,
0223 VK_GOTPAGEOFF,
0224 VK_SECREL,
0225 VK_SIZE,
0226 VK_WEAKREF,
0227 VK_FUNCDESC,
0228 VK_GOTFUNCDESC,
0229 VK_GOTOFFFUNCDESC,
0230 VK_TLSGD_FDPIC,
0231 VK_TLSLDM_FDPIC,
0232 VK_GOTTPOFF_FDPIC,
0233
0234 VK_X86_ABS8,
0235 VK_X86_PLTOFF,
0236
0237 VK_ARM_NONE,
0238 VK_ARM_GOT_PREL,
0239 VK_ARM_TARGET1,
0240 VK_ARM_TARGET2,
0241 VK_ARM_PREL31,
0242 VK_ARM_SBREL,
0243 VK_ARM_TLSLDO,
0244 VK_ARM_TLSDESCSEQ,
0245
0246 VK_AVR_NONE,
0247 VK_AVR_LO8,
0248 VK_AVR_HI8,
0249 VK_AVR_HLO8,
0250 VK_AVR_DIFF8,
0251 VK_AVR_DIFF16,
0252 VK_AVR_DIFF32,
0253 VK_AVR_PM,
0254
0255 VK_PPC_LO,
0256 VK_PPC_HI,
0257 VK_PPC_HA,
0258 VK_PPC_HIGH,
0259 VK_PPC_HIGHA,
0260 VK_PPC_HIGHER,
0261 VK_PPC_HIGHERA,
0262 VK_PPC_HIGHEST,
0263 VK_PPC_HIGHESTA,
0264 VK_PPC_GOT_LO,
0265 VK_PPC_GOT_HI,
0266 VK_PPC_GOT_HA,
0267 VK_PPC_TOCBASE,
0268 VK_PPC_TOC,
0269 VK_PPC_TOC_LO,
0270 VK_PPC_TOC_HI,
0271 VK_PPC_TOC_HA,
0272 VK_PPC_U,
0273 VK_PPC_L,
0274 VK_PPC_DTPMOD,
0275 VK_PPC_TPREL_LO,
0276 VK_PPC_TPREL_HI,
0277 VK_PPC_TPREL_HA,
0278 VK_PPC_TPREL_HIGH,
0279 VK_PPC_TPREL_HIGHA,
0280 VK_PPC_TPREL_HIGHER,
0281 VK_PPC_TPREL_HIGHERA,
0282 VK_PPC_TPREL_HIGHEST,
0283 VK_PPC_TPREL_HIGHESTA,
0284 VK_PPC_DTPREL_LO,
0285 VK_PPC_DTPREL_HI,
0286 VK_PPC_DTPREL_HA,
0287 VK_PPC_DTPREL_HIGH,
0288 VK_PPC_DTPREL_HIGHA,
0289 VK_PPC_DTPREL_HIGHER,
0290 VK_PPC_DTPREL_HIGHERA,
0291 VK_PPC_DTPREL_HIGHEST,
0292 VK_PPC_DTPREL_HIGHESTA,
0293 VK_PPC_GOT_TPREL,
0294 VK_PPC_GOT_TPREL_LO,
0295 VK_PPC_GOT_TPREL_HI,
0296 VK_PPC_GOT_TPREL_HA,
0297 VK_PPC_GOT_DTPREL,
0298 VK_PPC_GOT_DTPREL_LO,
0299 VK_PPC_GOT_DTPREL_HI,
0300 VK_PPC_GOT_DTPREL_HA,
0301 VK_PPC_TLS,
0302 VK_PPC_GOT_TLSGD,
0303 VK_PPC_GOT_TLSGD_LO,
0304 VK_PPC_GOT_TLSGD_HI,
0305 VK_PPC_GOT_TLSGD_HA,
0306 VK_PPC_TLSGD,
0307 VK_PPC_AIX_TLSGD,
0308 VK_PPC_AIX_TLSGDM,
0309 VK_PPC_AIX_TLSIE,
0310 VK_PPC_AIX_TLSLE,
0311 VK_PPC_AIX_TLSLD,
0312 VK_PPC_AIX_TLSML,
0313 VK_PPC_GOT_TLSLD,
0314 VK_PPC_GOT_TLSLD_LO,
0315 VK_PPC_GOT_TLSLD_HI,
0316 VK_PPC_GOT_TLSLD_HA,
0317 VK_PPC_GOT_PCREL,
0318 VK_PPC_GOT_TLSGD_PCREL,
0319 VK_PPC_GOT_TLSLD_PCREL,
0320 VK_PPC_GOT_TPREL_PCREL,
0321 VK_PPC_TLS_PCREL,
0322 VK_PPC_TLSLD,
0323 VK_PPC_LOCAL,
0324 VK_PPC_NOTOC,
0325 VK_PPC_PCREL_OPT,
0326
0327 VK_COFF_IMGREL32,
0328
0329 VK_Hexagon_LO16,
0330 VK_Hexagon_HI16,
0331 VK_Hexagon_GPREL,
0332 VK_Hexagon_GD_GOT,
0333 VK_Hexagon_LD_GOT,
0334 VK_Hexagon_GD_PLT,
0335 VK_Hexagon_LD_PLT,
0336 VK_Hexagon_IE,
0337 VK_Hexagon_IE_GOT,
0338
0339 VK_WASM_TYPEINDEX,
0340 VK_WASM_TLSREL,
0341 VK_WASM_MBREL,
0342 VK_WASM_TBREL,
0343 VK_WASM_GOT_TLS,
0344 VK_WASM_FUNCINDEX,
0345
0346 VK_AMDGPU_GOTPCREL32_LO,
0347 VK_AMDGPU_GOTPCREL32_HI,
0348 VK_AMDGPU_REL32_LO,
0349 VK_AMDGPU_REL32_HI,
0350 VK_AMDGPU_REL64,
0351 VK_AMDGPU_ABS32_LO,
0352 VK_AMDGPU_ABS32_HI,
0353
0354 VK_VE_HI32,
0355 VK_VE_LO32,
0356 VK_VE_PC_HI32,
0357 VK_VE_PC_LO32,
0358 VK_VE_GOT_HI32,
0359 VK_VE_GOT_LO32,
0360 VK_VE_GOTOFF_HI32,
0361 VK_VE_GOTOFF_LO32,
0362 VK_VE_PLT_HI32,
0363 VK_VE_PLT_LO32,
0364 VK_VE_TLS_GD_HI32,
0365 VK_VE_TLS_GD_LO32,
0366 VK_VE_TPOFF_HI32,
0367 VK_VE_TPOFF_LO32,
0368
0369 VK_TPREL,
0370 VK_DTPREL
0371 };
0372
0373 private:
0374
0375 const MCSymbol *Symbol;
0376
0377
0378
0379 static const unsigned VariantKindBits = 16;
0380 static const unsigned VariantKindMask = (1 << VariantKindBits) - 1;
0381
0382
0383 static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits;
0384
0385 static unsigned encodeSubclassData(VariantKind Kind,
0386 bool HasSubsectionsViaSymbols) {
0387 return (unsigned)Kind |
0388 (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0);
0389 }
0390
0391 explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
0392 const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
0393
0394 public:
0395
0396
0397
0398 static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) {
0399 return MCSymbolRefExpr::create(Symbol, VK_None, Ctx);
0400 }
0401
0402 static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind,
0403 MCContext &Ctx, SMLoc Loc = SMLoc());
0404 static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind,
0405 MCContext &Ctx);
0406
0407
0408
0409
0410
0411 const MCSymbol &getSymbol() const { return *Symbol; }
0412
0413 VariantKind getKind() const {
0414 return (VariantKind)(getSubclassData() & VariantKindMask);
0415 }
0416
0417 bool hasSubsectionsViaSymbols() const {
0418 return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0;
0419 }
0420
0421
0422
0423
0424
0425 static StringRef getVariantKindName(VariantKind Kind);
0426
0427 static VariantKind getVariantKindForName(StringRef Name);
0428
0429
0430
0431 static bool classof(const MCExpr *E) {
0432 return E->getKind() == MCExpr::SymbolRef;
0433 }
0434 };
0435
0436
0437 class MCUnaryExpr : public MCExpr {
0438 public:
0439 enum Opcode {
0440 LNot,
0441 Minus,
0442 Not,
0443 Plus
0444 };
0445
0446 private:
0447 const MCExpr *Expr;
0448
0449 MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
0450 : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}
0451
0452 public:
0453
0454
0455
0456 static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr,
0457 MCContext &Ctx, SMLoc Loc = SMLoc());
0458
0459 static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
0460 return create(LNot, Expr, Ctx, Loc);
0461 }
0462
0463 static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
0464 return create(Minus, Expr, Ctx, Loc);
0465 }
0466
0467 static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
0468 return create(Not, Expr, Ctx, Loc);
0469 }
0470
0471 static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
0472 return create(Plus, Expr, Ctx, Loc);
0473 }
0474
0475
0476
0477
0478
0479
0480 Opcode getOpcode() const { return (Opcode)getSubclassData(); }
0481
0482
0483 const MCExpr *getSubExpr() const { return Expr; }
0484
0485
0486
0487 static bool classof(const MCExpr *E) {
0488 return E->getKind() == MCExpr::Unary;
0489 }
0490 };
0491
0492
0493 class MCBinaryExpr : public MCExpr {
0494 public:
0495 enum Opcode {
0496 Add,
0497 And,
0498 Div,
0499 EQ,
0500 GT,
0501
0502 GTE,
0503
0504 LAnd,
0505 LOr,
0506 LT,
0507
0508 LTE,
0509
0510 Mod,
0511 Mul,
0512 NE,
0513 Or,
0514 OrNot,
0515 Shl,
0516 AShr,
0517 LShr,
0518 Sub,
0519 Xor
0520 };
0521
0522 private:
0523 const MCExpr *LHS, *RHS;
0524
0525 MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
0526 SMLoc Loc = SMLoc())
0527 : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}
0528
0529 public:
0530
0531
0532
0533 static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS,
0534 const MCExpr *RHS, MCContext &Ctx,
0535 SMLoc Loc = SMLoc());
0536
0537 static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS,
0538 MCContext &Ctx) {
0539 return create(Add, LHS, RHS, Ctx);
0540 }
0541
0542 static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS,
0543 MCContext &Ctx) {
0544 return create(And, LHS, RHS, Ctx);
0545 }
0546
0547 static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS,
0548 MCContext &Ctx) {
0549 return create(Div, LHS, RHS, Ctx);
0550 }
0551
0552 static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS,
0553 MCContext &Ctx) {
0554 return create(EQ, LHS, RHS, Ctx);
0555 }
0556
0557 static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS,
0558 MCContext &Ctx) {
0559 return create(GT, LHS, RHS, Ctx);
0560 }
0561
0562 static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS,
0563 MCContext &Ctx) {
0564 return create(GTE, LHS, RHS, Ctx);
0565 }
0566
0567 static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS,
0568 MCContext &Ctx) {
0569 return create(LAnd, LHS, RHS, Ctx);
0570 }
0571
0572 static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS,
0573 MCContext &Ctx) {
0574 return create(LOr, LHS, RHS, Ctx);
0575 }
0576
0577 static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS,
0578 MCContext &Ctx) {
0579 return create(LT, LHS, RHS, Ctx);
0580 }
0581
0582 static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS,
0583 MCContext &Ctx) {
0584 return create(LTE, LHS, RHS, Ctx);
0585 }
0586
0587 static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS,
0588 MCContext &Ctx) {
0589 return create(Mod, LHS, RHS, Ctx);
0590 }
0591
0592 static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS,
0593 MCContext &Ctx) {
0594 return create(Mul, LHS, RHS, Ctx);
0595 }
0596
0597 static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS,
0598 MCContext &Ctx) {
0599 return create(NE, LHS, RHS, Ctx);
0600 }
0601
0602 static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS,
0603 MCContext &Ctx) {
0604 return create(Or, LHS, RHS, Ctx);
0605 }
0606
0607 static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS,
0608 MCContext &Ctx) {
0609 return create(Shl, LHS, RHS, Ctx);
0610 }
0611
0612 static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS,
0613 MCContext &Ctx) {
0614 return create(AShr, LHS, RHS, Ctx);
0615 }
0616
0617 static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS,
0618 MCContext &Ctx) {
0619 return create(LShr, LHS, RHS, Ctx);
0620 }
0621
0622 static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS,
0623 MCContext &Ctx) {
0624 return create(Sub, LHS, RHS, Ctx);
0625 }
0626
0627 static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS,
0628 MCContext &Ctx) {
0629 return create(Xor, LHS, RHS, Ctx);
0630 }
0631
0632
0633
0634
0635
0636
0637 Opcode getOpcode() const { return (Opcode)getSubclassData(); }
0638
0639
0640 const MCExpr *getLHS() const { return LHS; }
0641
0642
0643 const MCExpr *getRHS() const { return RHS; }
0644
0645
0646
0647 static bool classof(const MCExpr *E) {
0648 return E->getKind() == MCExpr::Binary;
0649 }
0650 };
0651
0652
0653
0654
0655
0656
0657 class MCTargetExpr : public MCExpr {
0658 virtual void anchor();
0659
0660 protected:
0661 MCTargetExpr() : MCExpr(Target, SMLoc()) {}
0662 virtual ~MCTargetExpr() = default;
0663
0664 public:
0665 virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
0666 virtual bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
0667 const MCFixup *Fixup) const = 0;
0668
0669 virtual bool isEqualTo(const MCExpr *x) const { return false; }
0670 virtual bool isSymbolUsedInExpression(const MCSymbol *Sym) const {
0671 return false;
0672 }
0673
0674
0675 virtual bool inlineAssignedExpr() const { return false; }
0676 virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
0677 virtual MCFragment *findAssociatedFragment() const = 0;
0678
0679 virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
0680
0681 static bool classof(const MCExpr *E) {
0682 return E->getKind() == MCExpr::Target;
0683 }
0684 };
0685
0686 }
0687
0688 #endif