Home | History | Annotate | Download | only in MC
      1 //===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===//
      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 #ifndef LLVM_MC_MCEXPR_H
     11 #define LLVM_MC_MCEXPR_H
     12 
     13 #include "llvm/ADT/DenseMap.h"
     14 #include "llvm/Support/Casting.h"
     15 #include "llvm/Support/DataTypes.h"
     16 
     17 namespace llvm {
     18 class MCAsmInfo;
     19 class MCAsmLayout;
     20 class MCAssembler;
     21 class MCContext;
     22 class MCFixup;
     23 class MCSection;
     24 class MCSectionData;
     25 class MCStreamer;
     26 class MCSymbol;
     27 class MCValue;
     28 class raw_ostream;
     29 class StringRef;
     30 typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap;
     31 
     32 /// MCExpr - Base class for the full range of assembler expressions which are
     33 /// needed for parsing.
     34 class MCExpr {
     35 public:
     36   enum ExprKind {
     37     Binary,    ///< Binary expressions.
     38     Constant,  ///< Constant expressions.
     39     SymbolRef, ///< References to labels and assigned expressions.
     40     Unary,     ///< Unary expressions.
     41     Target     ///< Target specific expression.
     42   };
     43 
     44 private:
     45   ExprKind Kind;
     46 
     47   MCExpr(const MCExpr&) = delete;
     48   void operator=(const MCExpr&) = delete;
     49 
     50   bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
     51                           const MCAsmLayout *Layout,
     52                           const SectionAddrMap *Addrs) const;
     53 
     54   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
     55                           const MCAsmLayout *Layout,
     56                           const SectionAddrMap *Addrs, bool InSet) const;
     57 
     58 protected:
     59   explicit MCExpr(ExprKind Kind) : Kind(Kind) {}
     60 
     61   bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
     62                                  const MCAsmLayout *Layout,
     63                                  const MCFixup *Fixup,
     64                                  const SectionAddrMap *Addrs, bool InSet) const;
     65 
     66 public:
     67   /// @name Accessors
     68   /// @{
     69 
     70   ExprKind getKind() const { return Kind; }
     71 
     72   /// @}
     73   /// @name Utility Methods
     74   /// @{
     75 
     76   void print(raw_ostream &OS) const;
     77   void dump() const;
     78 
     79   /// @}
     80   /// @name Expression Evaluation
     81   /// @{
     82 
     83   /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
     84   ///
     85   /// @param Res - The absolute value, if evaluation succeeds.
     86   /// @param Layout - The assembler layout object to use for evaluating symbol
     87   /// values. If not given, then only non-symbolic expressions will be
     88   /// evaluated.
     89   /// @result - True on success.
     90   bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
     91                           const SectionAddrMap &Addrs) const;
     92   bool EvaluateAsAbsolute(int64_t &Res) const;
     93   bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
     94   bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
     95 
     96   bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
     97 
     98   /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
     99   /// value, i.e. an expression of the fixed form (a - b + constant).
    100   ///
    101   /// @param Res - The relocatable value, if evaluation succeeds.
    102   /// @param Layout - The assembler layout object to use for evaluating values.
    103   /// @param Fixup - The Fixup object if available.
    104   /// @result - True on success.
    105   bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
    106                              const MCFixup *Fixup) const;
    107 
    108   /// \brief Try to evaluate the expression to the form (a - b + constant) where
    109   /// neither a nor b are variables.
    110   ///
    111   /// This is a more aggressive variant of EvaluateAsRelocatable. The intended
    112   /// use is for when relocations are not available, like the .size directive.
    113   bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;
    114 
    115   /// FindAssociatedSection - Find the "associated section" for this expression,
    116   /// which is currently defined as the absolute section for constants, or
    117   /// otherwise the section associated with the first defined symbol in the
    118   /// expression.
    119   const MCSection *FindAssociatedSection() const;
    120 
    121   /// @}
    122 };
    123 
    124 inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
    125   E.print(OS);
    126   return OS;
    127 }
    128 
    129 //// MCConstantExpr - Represent a constant integer expression.
    130 class MCConstantExpr : public MCExpr {
    131   int64_t Value;
    132 
    133   explicit MCConstantExpr(int64_t Value)
    134       : MCExpr(MCExpr::Constant), Value(Value) {}
    135 
    136 public:
    137   /// @name Construction
    138   /// @{
    139 
    140   static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
    141 
    142   /// @}
    143   /// @name Accessors
    144   /// @{
    145 
    146   int64_t getValue() const { return Value; }
    147 
    148   /// @}
    149 
    150   static bool classof(const MCExpr *E) {
    151     return E->getKind() == MCExpr::Constant;
    152   }
    153 };
    154 
    155 /// MCSymbolRefExpr - Represent a reference to a symbol from inside an
    156 /// expression.
    157 ///
    158 /// A symbol reference in an expression may be a use of a label, a use of an
    159 /// assembler variable (defined constant), or constitute an implicit definition
    160 /// of the symbol as external.
    161 class MCSymbolRefExpr : public MCExpr {
    162 public:
    163   enum VariantKind {
    164     VK_None,
    165     VK_Invalid,
    166 
    167     VK_GOT,
    168     VK_GOTOFF,
    169     VK_GOTPCREL,
    170     VK_GOTTPOFF,
    171     VK_INDNTPOFF,
    172     VK_NTPOFF,
    173     VK_GOTNTPOFF,
    174     VK_PLT,
    175     VK_TLSGD,
    176     VK_TLSLD,
    177     VK_TLSLDM,
    178     VK_TPOFF,
    179     VK_DTPOFF,
    180     VK_TLVP,      // Mach-O thread local variable relocations
    181     VK_TLVPPAGE,
    182     VK_TLVPPAGEOFF,
    183     VK_PAGE,
    184     VK_PAGEOFF,
    185     VK_GOTPAGE,
    186     VK_GOTPAGEOFF,
    187     VK_SECREL,
    188     VK_SIZE,      // symbol@SIZE
    189     VK_WEAKREF,   // The link between the symbols in .weakref foo, bar
    190 
    191     VK_ARM_NONE,
    192     VK_ARM_TARGET1,
    193     VK_ARM_TARGET2,
    194     VK_ARM_PREL31,
    195     VK_ARM_SBREL,          // symbol(sbrel)
    196     VK_ARM_TLSLDO,         // symbol(tlsldo)
    197     VK_ARM_TLSCALL,        // symbol(tlscall)
    198     VK_ARM_TLSDESC,        // symbol(tlsdesc)
    199     VK_ARM_TLSDESCSEQ,
    200 
    201     VK_PPC_LO,             // symbol@l
    202     VK_PPC_HI,             // symbol@h
    203     VK_PPC_HA,             // symbol@ha
    204     VK_PPC_HIGHER,         // symbol@higher
    205     VK_PPC_HIGHERA,        // symbol@highera
    206     VK_PPC_HIGHEST,        // symbol@highest
    207     VK_PPC_HIGHESTA,       // symbol@highesta
    208     VK_PPC_GOT_LO,         // symbol@got@l
    209     VK_PPC_GOT_HI,         // symbol@got@h
    210     VK_PPC_GOT_HA,         // symbol@got@ha
    211     VK_PPC_TOCBASE,        // symbol@tocbase
    212     VK_PPC_TOC,            // symbol@toc
    213     VK_PPC_TOC_LO,         // symbol@toc@l
    214     VK_PPC_TOC_HI,         // symbol@toc@h
    215     VK_PPC_TOC_HA,         // symbol@toc@ha
    216     VK_PPC_DTPMOD,         // symbol@dtpmod
    217     VK_PPC_TPREL,          // symbol@tprel
    218     VK_PPC_TPREL_LO,       // symbol@tprel@l
    219     VK_PPC_TPREL_HI,       // symbol@tprel@h
    220     VK_PPC_TPREL_HA,       // symbol@tprel@ha
    221     VK_PPC_TPREL_HIGHER,   // symbol@tprel@higher
    222     VK_PPC_TPREL_HIGHERA,  // symbol@tprel@highera
    223     VK_PPC_TPREL_HIGHEST,  // symbol@tprel@highest
    224     VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta
    225     VK_PPC_DTPREL,         // symbol@dtprel
    226     VK_PPC_DTPREL_LO,      // symbol@dtprel@l
    227     VK_PPC_DTPREL_HI,      // symbol@dtprel@h
    228     VK_PPC_DTPREL_HA,      // symbol@dtprel@ha
    229     VK_PPC_DTPREL_HIGHER,  // symbol@dtprel@higher
    230     VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
    231     VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest
    232     VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta
    233     VK_PPC_GOT_TPREL,      // symbol@got@tprel
    234     VK_PPC_GOT_TPREL_LO,   // symbol@got@tprel@l
    235     VK_PPC_GOT_TPREL_HI,   // symbol@got@tprel@h
    236     VK_PPC_GOT_TPREL_HA,   // symbol@got@tprel@ha
    237     VK_PPC_GOT_DTPREL,     // symbol@got@dtprel
    238     VK_PPC_GOT_DTPREL_LO,  // symbol@got@dtprel@l
    239     VK_PPC_GOT_DTPREL_HI,  // symbol@got@dtprel@h
    240     VK_PPC_GOT_DTPREL_HA,  // symbol@got@dtprel@ha
    241     VK_PPC_TLS,            // symbol@tls
    242     VK_PPC_GOT_TLSGD,      // symbol@got@tlsgd
    243     VK_PPC_GOT_TLSGD_LO,   // symbol@got@tlsgd@l
    244     VK_PPC_GOT_TLSGD_HI,   // symbol@got@tlsgd@h
    245     VK_PPC_GOT_TLSGD_HA,   // symbol@got@tlsgd@ha
    246     VK_PPC_TLSGD,          // symbol@tlsgd
    247     VK_PPC_GOT_TLSLD,      // symbol@got@tlsld
    248     VK_PPC_GOT_TLSLD_LO,   // symbol@got@tlsld@l
    249     VK_PPC_GOT_TLSLD_HI,   // symbol@got@tlsld@h
    250     VK_PPC_GOT_TLSLD_HA,   // symbol@got@tlsld@ha
    251     VK_PPC_TLSLD,          // symbol@tlsld
    252     VK_PPC_LOCAL,          // symbol@local
    253 
    254     VK_Mips_GPREL,
    255     VK_Mips_GOT_CALL,
    256     VK_Mips_GOT16,
    257     VK_Mips_GOT,
    258     VK_Mips_ABS_HI,
    259     VK_Mips_ABS_LO,
    260     VK_Mips_TLSGD,
    261     VK_Mips_TLSLDM,
    262     VK_Mips_DTPREL_HI,
    263     VK_Mips_DTPREL_LO,
    264     VK_Mips_GOTTPREL,
    265     VK_Mips_TPREL_HI,
    266     VK_Mips_TPREL_LO,
    267     VK_Mips_GPOFF_HI,
    268     VK_Mips_GPOFF_LO,
    269     VK_Mips_GOT_DISP,
    270     VK_Mips_GOT_PAGE,
    271     VK_Mips_GOT_OFST,
    272     VK_Mips_HIGHER,
    273     VK_Mips_HIGHEST,
    274     VK_Mips_GOT_HI16,
    275     VK_Mips_GOT_LO16,
    276     VK_Mips_CALL_HI16,
    277     VK_Mips_CALL_LO16,
    278     VK_Mips_PCREL_HI16,
    279     VK_Mips_PCREL_LO16,
    280 
    281     VK_COFF_IMGREL32 // symbol@imgrel (image-relative)
    282   };
    283 
    284 private:
    285   /// The symbol reference modifier.
    286   const unsigned Kind : 16;
    287 
    288   /// Specifies how the variant kind should be printed.
    289   const unsigned UseParensForSymbolVariant : 1;
    290 
    291   // FIXME: Remove this bit.
    292   const unsigned HasSubsectionsViaSymbols : 1;
    293 
    294   /// The symbol being referenced.
    295   const MCSymbol *Symbol;
    296 
    297   explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
    298                            const MCAsmInfo *MAI);
    299 
    300 public:
    301   /// @name Construction
    302   /// @{
    303 
    304   static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) {
    305     return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx);
    306   }
    307 
    308   static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind,
    309                                        MCContext &Ctx);
    310   static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
    311                                        MCContext &Ctx);
    312 
    313   /// @}
    314   /// @name Accessors
    315   /// @{
    316 
    317   const MCSymbol &getSymbol() const { return *Symbol; }
    318 
    319   VariantKind getKind() const { return static_cast<VariantKind>(Kind); }
    320 
    321   void printVariantKind(raw_ostream &OS) const;
    322 
    323   bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
    324 
    325   /// @}
    326   /// @name Static Utility Functions
    327   /// @{
    328 
    329   static StringRef getVariantKindName(VariantKind Kind);
    330 
    331   static VariantKind getVariantKindForName(StringRef Name);
    332 
    333   /// @}
    334 
    335   static bool classof(const MCExpr *E) {
    336     return E->getKind() == MCExpr::SymbolRef;
    337   }
    338 };
    339 
    340 /// MCUnaryExpr - Unary assembler expressions.
    341 class MCUnaryExpr : public MCExpr {
    342 public:
    343   enum Opcode {
    344     LNot,  ///< Logical negation.
    345     Minus, ///< Unary minus.
    346     Not,   ///< Bitwise negation.
    347     Plus   ///< Unary plus.
    348   };
    349 
    350 private:
    351   Opcode Op;
    352   const MCExpr *Expr;
    353 
    354   MCUnaryExpr(Opcode Op, const MCExpr *Expr)
    355       : MCExpr(MCExpr::Unary), Op(Op), Expr(Expr) {}
    356 
    357 public:
    358   /// @name Construction
    359   /// @{
    360 
    361   static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
    362                                    MCContext &Ctx);
    363   static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) {
    364     return Create(LNot, Expr, Ctx);
    365   }
    366   static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) {
    367     return Create(Minus, Expr, Ctx);
    368   }
    369   static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) {
    370     return Create(Not, Expr, Ctx);
    371   }
    372   static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) {
    373     return Create(Plus, Expr, Ctx);
    374   }
    375 
    376   /// @}
    377   /// @name Accessors
    378   /// @{
    379 
    380   /// getOpcode - Get the kind of this unary expression.
    381   Opcode getOpcode() const { return Op; }
    382 
    383   /// getSubExpr - Get the child of this unary expression.
    384   const MCExpr *getSubExpr() const { return Expr; }
    385 
    386   /// @}
    387 
    388   static bool classof(const MCExpr *E) {
    389     return E->getKind() == MCExpr::Unary;
    390   }
    391 };
    392 
    393 /// MCBinaryExpr - Binary assembler expressions.
    394 class MCBinaryExpr : public MCExpr {
    395 public:
    396   enum Opcode {
    397     Add,  ///< Addition.
    398     And,  ///< Bitwise and.
    399     Div,  ///< Signed division.
    400     EQ,   ///< Equality comparison.
    401     GT,   ///< Signed greater than comparison (result is either 0 or some
    402           ///< target-specific non-zero value)
    403     GTE,  ///< Signed greater than or equal comparison (result is either 0 or
    404           ///< some target-specific non-zero value).
    405     LAnd, ///< Logical and.
    406     LOr,  ///< Logical or.
    407     LT,   ///< Signed less than comparison (result is either 0 or
    408           ///< some target-specific non-zero value).
    409     LTE,  ///< Signed less than or equal comparison (result is either 0 or
    410           ///< some target-specific non-zero value).
    411     Mod,  ///< Signed remainder.
    412     Mul,  ///< Multiplication.
    413     NE,   ///< Inequality comparison.
    414     Or,   ///< Bitwise or.
    415     Shl,  ///< Shift left.
    416     Shr,  ///< Shift right (arithmetic or logical, depending on target)
    417     Sub,  ///< Subtraction.
    418     Xor   ///< Bitwise exclusive or.
    419   };
    420 
    421 private:
    422   Opcode Op;
    423   const MCExpr *LHS, *RHS;
    424 
    425   MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS)
    426       : MCExpr(MCExpr::Binary), Op(Op), LHS(LHS), RHS(RHS) {}
    427 
    428 public:
    429   /// @name Construction
    430   /// @{
    431 
    432   static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
    433                                     const MCExpr *RHS, MCContext &Ctx);
    434   static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS,
    435                                        MCContext &Ctx) {
    436     return Create(Add, LHS, RHS, Ctx);
    437   }
    438   static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS,
    439                                        MCContext &Ctx) {
    440     return Create(And, LHS, RHS, Ctx);
    441   }
    442   static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS,
    443                                        MCContext &Ctx) {
    444     return Create(Div, LHS, RHS, Ctx);
    445   }
    446   static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS,
    447                                       MCContext &Ctx) {
    448     return Create(EQ, LHS, RHS, Ctx);
    449   }
    450   static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS,
    451                                       MCContext &Ctx) {
    452     return Create(GT, LHS, RHS, Ctx);
    453   }
    454   static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS,
    455                                        MCContext &Ctx) {
    456     return Create(GTE, LHS, RHS, Ctx);
    457   }
    458   static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS,
    459                                         MCContext &Ctx) {
    460     return Create(LAnd, LHS, RHS, Ctx);
    461   }
    462   static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS,
    463                                        MCContext &Ctx) {
    464     return Create(LOr, LHS, RHS, Ctx);
    465   }
    466   static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS,
    467                                       MCContext &Ctx) {
    468     return Create(LT, LHS, RHS, Ctx);
    469   }
    470   static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS,
    471                                        MCContext &Ctx) {
    472     return Create(LTE, LHS, RHS, Ctx);
    473   }
    474   static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS,
    475                                        MCContext &Ctx) {
    476     return Create(Mod, LHS, RHS, Ctx);
    477   }
    478   static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS,
    479                                        MCContext &Ctx) {
    480     return Create(Mul, LHS, RHS, Ctx);
    481   }
    482   static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS,
    483                                       MCContext &Ctx) {
    484     return Create(NE, LHS, RHS, Ctx);
    485   }
    486   static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS,
    487                                       MCContext &Ctx) {
    488     return Create(Or, LHS, RHS, Ctx);
    489   }
    490   static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS,
    491                                        MCContext &Ctx) {
    492     return Create(Shl, LHS, RHS, Ctx);
    493   }
    494   static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS,
    495                                        MCContext &Ctx) {
    496     return Create(Shr, LHS, RHS, Ctx);
    497   }
    498   static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
    499                                        MCContext &Ctx) {
    500     return Create(Sub, LHS, RHS, Ctx);
    501   }
    502   static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS,
    503                                        MCContext &Ctx) {
    504     return Create(Xor, LHS, RHS, Ctx);
    505   }
    506 
    507   /// @}
    508   /// @name Accessors
    509   /// @{
    510 
    511   /// getOpcode - Get the kind of this binary expression.
    512   Opcode getOpcode() const { return Op; }
    513 
    514   /// getLHS - Get the left-hand side expression of the binary operator.
    515   const MCExpr *getLHS() const { return LHS; }
    516 
    517   /// getRHS - Get the right-hand side expression of the binary operator.
    518   const MCExpr *getRHS() const { return RHS; }
    519 
    520   /// @}
    521 
    522   static bool classof(const MCExpr *E) {
    523     return E->getKind() == MCExpr::Binary;
    524   }
    525 };
    526 
    527 /// MCTargetExpr - This is an extension point for target-specific MCExpr
    528 /// subclasses to implement.
    529 ///
    530 /// NOTE: All subclasses are required to have trivial destructors because
    531 /// MCExprs are bump pointer allocated and not destructed.
    532 class MCTargetExpr : public MCExpr {
    533   virtual void anchor();
    534 protected:
    535   MCTargetExpr() : MCExpr(Target) {}
    536   virtual ~MCTargetExpr() {}
    537 public:
    538 
    539   virtual void PrintImpl(raw_ostream &OS) const = 0;
    540   virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
    541                                          const MCAsmLayout *Layout,
    542                                          const MCFixup *Fixup) const = 0;
    543   virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
    544   virtual const MCSection *FindAssociatedSection() const = 0;
    545 
    546   virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
    547 
    548   static bool classof(const MCExpr *E) {
    549     return E->getKind() == MCExpr::Target;
    550   }
    551 };
    552 
    553 } // end namespace llvm
    554 
    555 #endif
    556