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