Operator.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
1//===- Operator.h ---------------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#ifndef MCLD_SCRIPT_OPERATOR_INTERFACE_H
10#define MCLD_SCRIPT_OPERATOR_INTERFACE_H
11#ifdef ENABLE_UNITTEST
12#include <gtest.h>
13#endif
14
15#include <mcld/Script/ExprToken.h>
16#include <llvm/Support/DataTypes.h>
17
18namespace mcld
19{
20
21class Operand;
22class IntOperand;
23class Module;
24class TargetLDBackend;
25
26/** \class Operator
27 *  \brief This class defines the interfaces to an operator token.
28 */
29
30class Operator : public ExprToken
31{
32public:
33  enum Arity {
34    NULLARY,
35    UNARY,
36    BINARY,
37    TERNARY
38  };
39
40  enum Type {
41    /* arithmetic operator */
42    UNARY_PLUS  = 0,
43    UNARY_MINUS = 1,
44    LOGICAL_NOT = 2,
45    BITWISE_NOT = 3,
46    MUL         = 4,
47    DIV         = 5,
48    MOD         = 6,
49    ADD         = 7,
50    SUB         = 8,
51    LSHIFT      = 9,
52    RSHIFT      = 10,
53    LT          = 11,
54    LE          = 12,
55    GT          = 13,
56    GE          = 14,
57    EQ          = 15,
58    NE          = 16,
59    BITWISE_AND = 17,
60    BITWISE_XOR = 18,
61    BITWISE_OR  = 19,
62    LOGICAL_AND = 20,
63    LOGICAL_OR  = 21,
64    TERNARY_IF  = 22,
65    ASSIGN      = 23,
66    ADD_ASSIGN  = 24,
67    SUB_ASSIGN  = 25,
68    MUL_ASSIGN  = 26,
69    DIV_ASSIGN  = 27,
70    AND_ASSIGN  = 28,
71    OR_ASSIGN   = 29,
72    LS_ASSIGN   = 30,
73    RS_ASSIGN   = 31,
74    /* function */
75    ABSOLUTE               = 32,
76    ADDR                   = 33,
77    ALIGN                  = 34,
78    ALIGNOF                = 35,
79    BLOCK                  = 36,
80    DATA_SEGMENT_ALIGN     = 37,
81    DATA_SEGMENT_END       = 38,
82    DATA_SEGMENT_RELRO_END = 39,
83    DEFINED                = 40,
84    LENGTH                 = 41,
85    LOADADDR               = 42,
86    MAX                    = 43,
87    MIN                    = 44,
88    NEXT                   = 45,
89    ORIGIN                 = 46,
90    SEGMENT_START          = 47,
91    SIZEOF                 = 48,
92    SIZEOF_HEADERS         = 49,
93    MAXPAGESIZE            = 50,
94    COMMONPAGESIZE         = 51
95  };
96
97  static const char* OpNames[];
98
99protected:
100  Operator(Arity pArity, Type pType);
101
102  const IntOperand* result() const { return m_pIntOperand; }
103  IntOperand*       result()       { return m_pIntOperand; }
104
105public:
106  virtual ~Operator();
107
108  Arity arity() const { return m_Arity; }
109
110  Type type() const { return m_Type; }
111
112  virtual void dump() const;
113
114  virtual IntOperand* eval(const Module& pModule,
115                           const TargetLDBackend& pBackend) = 0;
116
117  virtual void appendOperand(Operand* pOperand) = 0;
118
119  static bool classof(const ExprToken* pToken)
120  {
121    return pToken->kind() == ExprToken::OPERATOR;
122  }
123
124  template<Operator::Type TYPE>
125  static Operator& create();
126
127private:
128  Arity m_Arity;
129  Type m_Type;
130  IntOperand* m_pIntOperand;
131};
132
133/* Nullary operator */
134template<>
135Operator& Operator::create<Operator::SIZEOF_HEADERS>();
136template<>
137Operator& Operator::create<Operator::MAXPAGESIZE>();
138template<>
139Operator& Operator::create<Operator::COMMONPAGESIZE>();
140
141/* Unary operator */
142template<>
143Operator& Operator::create<Operator::UNARY_PLUS>();
144template<>
145Operator& Operator::create<Operator::UNARY_MINUS>();
146template<>
147Operator& Operator::create<Operator::LOGICAL_NOT>();
148template<>
149Operator& Operator::create<Operator::BITWISE_NOT>();
150
151template<>
152Operator& Operator::create<Operator::ABSOLUTE>();
153template<>
154Operator& Operator::create<Operator::ADDR>();
155template<>
156Operator& Operator::create<Operator::ALIGNOF>();
157template<>
158Operator& Operator::create<Operator::DATA_SEGMENT_END>();
159template<>
160Operator& Operator::create<Operator::DEFINED>();
161template<>
162Operator& Operator::create<Operator::LENGTH>();
163template<>
164Operator& Operator::create<Operator::LOADADDR>();
165template<>
166Operator& Operator::create<Operator::NEXT>();
167template<>
168Operator& Operator::create<Operator::ORIGIN>();
169template<>
170Operator& Operator::create<Operator::SIZEOF>();
171
172/* Binary operator */
173template<>
174Operator& Operator::create<Operator::MUL>();
175template<>
176Operator& Operator::create<Operator::DIV>();
177template<>
178Operator& Operator::create<Operator::MOD>();
179template<>
180Operator& Operator::create<Operator::ADD>();
181template<>
182Operator& Operator::create<Operator::SUB>();
183template<>
184Operator& Operator::create<Operator::LSHIFT>();
185template<>
186Operator& Operator::create<Operator::RSHIFT>();
187template<>
188Operator& Operator::create<Operator::LT>();
189template<>
190Operator& Operator::create<Operator::LE>();
191template<>
192Operator& Operator::create<Operator::GT>();
193template<>
194Operator& Operator::create<Operator::GE>();
195template<>
196Operator& Operator::create<Operator::EQ>();
197template<>
198Operator& Operator::create<Operator::NE>();
199template<>
200Operator& Operator::create<Operator::BITWISE_AND>();
201template<>
202Operator& Operator::create<Operator::BITWISE_XOR>();
203template<>
204Operator& Operator::create<Operator::BITWISE_OR>();
205template<>
206Operator& Operator::create<Operator::LOGICAL_AND>();
207template<>
208Operator& Operator::create<Operator::LOGICAL_OR>();
209
210template<>
211Operator& Operator::create<Operator::ALIGN>();
212template<>
213Operator& Operator::create<Operator::DATA_SEGMENT_RELRO_END>();
214template<>
215Operator& Operator::create<Operator::MAX>();
216template<>
217Operator& Operator::create<Operator::MIN>();
218template<>
219Operator& Operator::create<Operator::SEGMENT_START>();
220
221/* Ternary operator */
222template<>
223Operator& Operator::create<Operator::TERNARY_IF>();
224
225template<>
226Operator&
227Operator::create<Operator::DATA_SEGMENT_ALIGN>();
228} // namespace of mcld
229
230#endif
231
232