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