Try to resolve symbol differences early, and if successful create a plain
[oota-llvm.git] / include / llvm / MC / MCExpr.h
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/Support/Casting.h"
14 #include "llvm/Support/DataTypes.h"
15
16 namespace llvm {
17 class MCAsmInfo;
18 class MCAsmLayout;
19 class MCAssembler;
20 class MCContext;
21 class MCSymbol;
22 class MCValue;
23 class raw_ostream;
24 class StringRef;
25
26 /// MCExpr - Base class for the full range of assembler expressions which are
27 /// needed for parsing.
28 class MCExpr {
29 public:
30   enum ExprKind {
31     Binary,    ///< Binary expressions.
32     Constant,  ///< Constant expressions.
33     SymbolRef, ///< References to labels and assigned expressions.
34     Unary,     ///< Unary expressions.
35     Target     ///< Target specific expression.
36   };
37
38 private:
39   ExprKind Kind;
40
41   MCExpr(const MCExpr&); // DO NOT IMPLEMENT
42   void operator=(const MCExpr&); // DO NOT IMPLEMENT
43
44 protected:
45   explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {}
46
47   bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
48                                  const MCAsmLayout *Layout,
49                                  bool InSet) const;
50 public:
51   /// @name Accessors
52   /// @{
53
54   ExprKind getKind() const { return Kind; }
55
56   /// @}
57   /// @name Utility Methods
58   /// @{
59
60   void print(raw_ostream &OS) const;
61   void dump() const;
62
63   /// @}
64   /// @name Expression Evaluation
65   /// @{
66
67   /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
68   ///
69   /// @param Res - The absolute value, if evaluation succeeds.
70   /// @param Layout - The assembler layout object to use for evaluating symbol
71   /// values. If not given, then only non-symbolic expressions will be
72   /// evaluated.
73   /// @result - True on success.
74   bool EvaluateAsAbsolute(int64_t &Res) const;
75   bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const;
76   bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout) const;
77   bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
78                           const MCAsmLayout *Layout) const;
79
80   /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
81   /// value, i.e. an expression of the fixed form (a - b + constant).
82   ///
83   /// @param Res - The relocatable value, if evaluation succeeds.
84   /// @param Layout - The assembler layout object to use for evaluating values.
85   /// @result - True on success.
86   bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout = 0) const;
87
88   /// @}
89
90   static bool classof(const MCExpr *) { return true; }
91 };
92
93 inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
94   E.print(OS);
95   return OS;
96 }
97
98 //// MCConstantExpr - Represent a constant integer expression.
99 class MCConstantExpr : public MCExpr {
100   int64_t Value;
101
102   explicit MCConstantExpr(int64_t _Value)
103     : MCExpr(MCExpr::Constant), Value(_Value) {}
104
105 public:
106   /// @name Construction
107   /// @{
108
109   static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
110
111   /// @}
112   /// @name Accessors
113   /// @{
114
115   int64_t getValue() const { return Value; }
116
117   /// @}
118
119   static bool classof(const MCExpr *E) {
120     return E->getKind() == MCExpr::Constant;
121   }
122   static bool classof(const MCConstantExpr *) { return true; }
123 };
124
125 /// MCSymbolRefExpr - Represent a reference to a symbol from inside an
126 /// expression.
127 ///
128 /// A symbol reference in an expression may be a use of a label, a use of an
129 /// assembler variable (defined constant), or constitute an implicit definition
130 /// of the symbol as external.
131 class MCSymbolRefExpr : public MCExpr {
132 public:
133   enum VariantKind {
134     VK_None,
135     VK_Invalid,
136
137     VK_GOT,
138     VK_GOTOFF,
139     VK_GOTPCREL,
140     VK_GOTTPOFF,
141     VK_INDNTPOFF,
142     VK_NTPOFF,
143     VK_GOTNTPOFF,
144     VK_PLT,
145     VK_TLSGD,
146     VK_TLSLD,
147     VK_TLSLDM,
148     VK_TPOFF,
149     VK_DTPOFF,
150     VK_TLVP,      // Mach-O thread local variable relocation
151     VK_ARM_HI16,  // The R_ARM_MOVT_ABS relocation (:upper16: in the .s file)
152     VK_ARM_LO16,  // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the .w file)
153     // FIXME: We'd really like to use the generic Kinds listed above for these.
154     VK_ARM_PLT,   // ARM-style PLT references. i.e., (PLT) instead of @PLT
155     VK_ARM_TLSGD, //   ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF
156     VK_ARM_GOT,
157     VK_ARM_GOTOFF,
158     VK_ARM_TPOFF,
159     VK_ARM_GOTTPOFF,
160     
161     VK_PPC_TOC,
162     VK_PPC_HA16,  // ha16(symbol)
163     VK_PPC_LO16   // lo16(symbol)
164   };
165
166 private:
167   /// The symbol being referenced.
168   const MCSymbol *Symbol;
169
170   /// The symbol reference modifier.
171   const VariantKind Kind;
172
173   explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind)
174     : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {}
175
176 public:
177   /// @name Construction
178   /// @{
179
180   static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) {
181     return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx);
182   }
183
184   static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind,
185                                        MCContext &Ctx);
186   static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
187                                        MCContext &Ctx);
188   
189   /// @}
190   /// @name Accessors
191   /// @{
192
193   const MCSymbol &getSymbol() const { return *Symbol; }
194
195   VariantKind getKind() const { return Kind; }
196
197   /// @}
198   /// @name Static Utility Functions
199   /// @{
200
201   static StringRef getVariantKindName(VariantKind Kind);
202
203   static VariantKind getVariantKindForName(StringRef Name);
204
205   /// @}
206
207   static bool classof(const MCExpr *E) {
208     return E->getKind() == MCExpr::SymbolRef;
209   }
210   static bool classof(const MCSymbolRefExpr *) { return true; }
211 };
212
213 /// MCUnaryExpr - Unary assembler expressions.
214 class MCUnaryExpr : public MCExpr {
215 public:
216   enum Opcode {
217     LNot,  ///< Logical negation.
218     Minus, ///< Unary minus.
219     Not,   ///< Bitwise negation.
220     Plus   ///< Unary plus.
221   };
222
223 private:
224   Opcode Op;
225   const MCExpr *Expr;
226
227   MCUnaryExpr(Opcode _Op, const MCExpr *_Expr)
228     : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {}
229
230 public:
231   /// @name Construction
232   /// @{
233
234   static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
235                                    MCContext &Ctx);
236   static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) {
237     return Create(LNot, Expr, Ctx);
238   }
239   static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) {
240     return Create(Minus, Expr, Ctx);
241   }
242   static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) {
243     return Create(Not, Expr, Ctx);
244   }
245   static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) {
246     return Create(Plus, Expr, Ctx);
247   }
248
249   /// @}
250   /// @name Accessors
251   /// @{
252
253   /// getOpcode - Get the kind of this unary expression.
254   Opcode getOpcode() const { return Op; }
255
256   /// getSubExpr - Get the child of this unary expression.
257   const MCExpr *getSubExpr() const { return Expr; }
258
259   /// @}
260
261   static bool classof(const MCExpr *E) {
262     return E->getKind() == MCExpr::Unary;
263   }
264   static bool classof(const MCUnaryExpr *) { return true; }
265 };
266
267 /// MCBinaryExpr - Binary assembler expressions.
268 class MCBinaryExpr : public MCExpr {
269 public:
270   enum Opcode {
271     Add,  ///< Addition.
272     And,  ///< Bitwise and.
273     Div,  ///< Signed division.
274     EQ,   ///< Equality comparison.
275     GT,   ///< Signed greater than comparison (result is either 0 or some
276           ///< target-specific non-zero value)
277     GTE,  ///< Signed greater than or equal comparison (result is either 0 or
278           ///< some target-specific non-zero value).
279     LAnd, ///< Logical and.
280     LOr,  ///< Logical or.
281     LT,   ///< Signed less than comparison (result is either 0 or
282           ///< some target-specific non-zero value).
283     LTE,  ///< Signed less than or equal comparison (result is either 0 or
284           ///< some target-specific non-zero value).
285     Mod,  ///< Signed remainder.
286     Mul,  ///< Multiplication.
287     NE,   ///< Inequality comparison.
288     Or,   ///< Bitwise or.
289     Shl,  ///< Shift left.
290     Shr,  ///< Shift right (arithmetic or logical, depending on target)
291     Sub,  ///< Subtraction.
292     Xor   ///< Bitwise exclusive or.
293   };
294
295 private:
296   Opcode Op;
297   const MCExpr *LHS, *RHS;
298
299   MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS)
300     : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {}
301
302 public:
303   /// @name Construction
304   /// @{
305
306   static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
307                                     const MCExpr *RHS, MCContext &Ctx);
308   static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS,
309                                        MCContext &Ctx) {
310     return Create(Add, LHS, RHS, Ctx);
311   }
312   static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS,
313                                        MCContext &Ctx) {
314     return Create(And, LHS, RHS, Ctx);
315   }
316   static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS,
317                                        MCContext &Ctx) {
318     return Create(Div, LHS, RHS, Ctx);
319   }
320   static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS,
321                                       MCContext &Ctx) {
322     return Create(EQ, LHS, RHS, Ctx);
323   }
324   static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS,
325                                       MCContext &Ctx) {
326     return Create(GT, LHS, RHS, Ctx);
327   }
328   static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS,
329                                        MCContext &Ctx) {
330     return Create(GTE, LHS, RHS, Ctx);
331   }
332   static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS,
333                                         MCContext &Ctx) {
334     return Create(LAnd, LHS, RHS, Ctx);
335   }
336   static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS,
337                                        MCContext &Ctx) {
338     return Create(LOr, LHS, RHS, Ctx);
339   }
340   static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS,
341                                       MCContext &Ctx) {
342     return Create(LT, LHS, RHS, Ctx);
343   }
344   static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS,
345                                        MCContext &Ctx) {
346     return Create(LTE, LHS, RHS, Ctx);
347   }
348   static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS,
349                                        MCContext &Ctx) {
350     return Create(Mod, LHS, RHS, Ctx);
351   }
352   static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS,
353                                        MCContext &Ctx) {
354     return Create(Mul, LHS, RHS, Ctx);
355   }
356   static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS,
357                                       MCContext &Ctx) {
358     return Create(NE, LHS, RHS, Ctx);
359   }
360   static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS,
361                                       MCContext &Ctx) {
362     return Create(Or, LHS, RHS, Ctx);
363   }
364   static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS,
365                                        MCContext &Ctx) {
366     return Create(Shl, LHS, RHS, Ctx);
367   }
368   static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS,
369                                        MCContext &Ctx) {
370     return Create(Shr, LHS, RHS, Ctx);
371   }
372   static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
373                                        MCContext &Ctx) {
374     return Create(Sub, LHS, RHS, Ctx);
375   }
376   static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS,
377                                        MCContext &Ctx) {
378     return Create(Xor, LHS, RHS, Ctx);
379   }
380
381   /// @}
382   /// @name Accessors
383   /// @{
384
385   /// getOpcode - Get the kind of this binary expression.
386   Opcode getOpcode() const { return Op; }
387
388   /// getLHS - Get the left-hand side expression of the binary operator.
389   const MCExpr *getLHS() const { return LHS; }
390
391   /// getRHS - Get the right-hand side expression of the binary operator.
392   const MCExpr *getRHS() const { return RHS; }
393
394   /// @}
395
396   static bool classof(const MCExpr *E) {
397     return E->getKind() == MCExpr::Binary;
398   }
399   static bool classof(const MCBinaryExpr *) { return true; }
400 };
401
402 /// MCTargetExpr - This is an extension point for target-specific MCExpr
403 /// subclasses to implement.
404 ///
405 /// NOTE: All subclasses are required to have trivial destructors because
406 /// MCExprs are bump pointer allocated and not destructed.
407 class MCTargetExpr : public MCExpr {
408   virtual void Anchor();
409 protected:
410   MCTargetExpr() : MCExpr(Target) {}
411   virtual ~MCTargetExpr() {}
412 public:
413
414   virtual void PrintImpl(raw_ostream &OS) const = 0;
415   virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
416                                          const MCAsmLayout *Layout) const = 0;
417
418
419   static bool classof(const MCExpr *E) {
420     return E->getKind() == MCExpr::Target;
421   }
422   static bool classof(const MCTargetExpr *) { return true; }
423 };
424
425 } // end namespace llvm
426
427 #endif