1
2
3
4
5
6 #ifndef CMAJOR_CMSXI_INSTRUCTION_INCLUDED
7 #define CMAJOR_CMSXI_INSTRUCTION_INCLUDED
8 #include <cmajor/cmsxi/Value.hpp>
9 #include <soulng/util/CodeFormatter.hpp>
10 #include <vector>
11 #include <utility>
12
13 namespace cmsxi {
14
15 using namespace soulng::util;
16
17 class Type;
18 class BasicBlock;
19 class Function;
20 class Context;
21 class MDStructRef;
22
23 class Instruction : public Value
24 {
25 public:
26 Instruction();
27 Type* GetType(Context& context) override;
28 virtual void Write(CodeFormatter& formatter, Function& function, Context& context) = 0;
29 std::string Name(Context& context) override;
30 void WriteResult(CodeFormatter& formatter, Function& function, Context& context);
31 void SetMetadataRef(MDStructRef* metadataRef_) { metadataRef = metadataRef_; }
32 void WriteMetadataRef(CodeFormatter& formatter);
33 virtual bool IsNoOperation() const { return false; }
34 private:
35 int resultId;
36 MDStructRef* metadataRef;
37 };
38
39 class UnaryInstruction : public Instruction
40 {
41 public:
42 UnaryInstruction(Value* arg_);
43 Type* GetType(Context& context) override { return arg->GetType(context); }
44 void WriteArg(CodeFormatter& formatter, Context& context);
45 private:
46 Value* arg;
47 };
48
49 class UnaryTypeInstruction : public UnaryInstruction
50 {
51 public:
52 UnaryTypeInstruction(Value* arg_, Type* type_);
53 Type* GetType(Context& context) override { return type; }
54 private:
55 Type* type;
56 };
57
58 class BinaryInstruction : public Instruction
59 {
60 public:
61 BinaryInstruction(Value* left_, Value* right_);
62 Type* GetType(Context& context) override;
63 void WriteArgs(CodeFormatter& formatter, Context& context);
64 private:
65 Value* left;
66 Value* right;
67 };
68
69 class NotInstruction : public UnaryInstruction
70 {
71 public:
72 NotInstruction(Value* arg_);
73 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
74 };
75
76 class NegInstruction : public UnaryInstruction
77 {
78 public:
79 NegInstruction(Value* arg_);
80 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
81 };
82
83 class AddInstruction : public BinaryInstruction
84 {
85 public:
86 AddInstruction(Value* left_, Value* right_);
87 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
88 };
89
90 class SubInstruction : public BinaryInstruction
91 {
92 public:
93 SubInstruction(Value* left_, Value* right_);
94 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
95 };
96
97 class MulInstruction : public BinaryInstruction
98 {
99 public:
100 MulInstruction(Value* left_, Value* right_);
101 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
102 };
103
104 class DivInstruction : public BinaryInstruction
105 {
106 public:
107 DivInstruction(Value* left_, Value* right_);
108 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
109 };
110
111 class ModInstruction : public BinaryInstruction
112 {
113 public:
114 ModInstruction(Value* left_, Value* right_);
115 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
116 };
117
118 class AndInstruction : public BinaryInstruction
119 {
120 public:
121 AndInstruction(Value* left_, Value* right_);
122 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
123 };
124
125 class OrInstruction : public BinaryInstruction
126 {
127 public:
128 OrInstruction(Value* left_, Value* right_);
129 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
130 };
131
132 class XorInstruction : public BinaryInstruction
133 {
134 public:
135 XorInstruction(Value* left_, Value* right_);
136 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
137 };
138
139 class ShlInstruction : public BinaryInstruction
140 {
141 public:
142 ShlInstruction(Value* left_, Value* right_);
143 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
144 };
145
146 class ShrInstruction : public BinaryInstruction
147 {
148 public:
149 ShrInstruction(Value* left_, Value* right_);
150 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
151 };
152
153 class EqualInstruction : public BinaryInstruction
154 {
155 public:
156 EqualInstruction(Value* left_, Value* right_);
157 Type* GetType(Context& context) override;
158 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
159 };
160
161 class LessInstruction : public BinaryInstruction
162 {
163 public:
164 LessInstruction(Value* left_, Value* right_);
165 Type* GetType(Context& context) override;
166 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
167 };
168
169 class SignExtendInstruction : public UnaryTypeInstruction
170 {
171 public:
172 SignExtendInstruction(Value* arg_, Type* destType_);
173 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
174 };
175
176 class ZeroExtendInstruction : public UnaryTypeInstruction
177 {
178 public:
179 ZeroExtendInstruction(Value* arg_, Type* destType_);
180 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
181 };
182
183 class TruncateInstruction : public UnaryTypeInstruction
184 {
185 public:
186 TruncateInstruction(Value* arg_, Type* destType_);
187 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
188 };
189
190 class BitCastInstruction : public UnaryTypeInstruction
191 {
192 public:
193 BitCastInstruction(Value* arg_, Type* destType_);
194 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
195 };
196
197 class IntToFloatInstruction : public UnaryTypeInstruction
198 {
199 public:
200 IntToFloatInstruction(Value* arg_, Type* destType_);
201 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
202 };
203
204 class FloatToIntInstruction : public UnaryTypeInstruction
205 {
206 public:
207 FloatToIntInstruction(Value* arg_, Type* destType_);
208 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
209 };
210
211 class IntToPtrInstruction : public UnaryTypeInstruction
212 {
213 public:
214 IntToPtrInstruction(Value* arg_, Type* destType_);
215 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
216 };
217
218 class PtrToIntInstruction : public UnaryTypeInstruction
219 {
220 public:
221 PtrToIntInstruction(Value* arg_, Type* destType_);
222 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
223 };
224
225 class ParamInstruction : public Instruction
226 {
227 public:
228 ParamInstruction(Type* type_);
229 Type* GetType(Context& context) override { return type; }
230 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
231 private:
232 Type* type;
233 };
234
235 class LocalInstruction : public Instruction
236 {
237 public:
238 LocalInstruction(Type* type_);
239 Type* GetType(Context& context) override;
240 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
241 private:
242 Type* type;
243 };
244
245 class LoadInstruction : public Instruction
246 {
247 public:
248 LoadInstruction(Value* ptr_);
249 Type* GetType(Context& context) override;
250 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
251 private:
252 Value* ptr;
253 };
254
255 class StoreInstruction : public Instruction
256 {
257 public:
258 StoreInstruction(Value* value_, Value* ptr_);
259 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
260 private:
261 Value* value;
262 Value* ptr;
263 };
264
265 class ArgInstruction : public Instruction
266 {
267 public:
268 ArgInstruction(Value* arg_);
269 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
270 private:
271 Value* arg;
272 };
273
274 class ElemAddrInstruction : public Instruction
275 {
276 public:
277 ElemAddrInstruction(Value* ptr_, Value* index_);
278 Type* GetType(Context& context) override;
279 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
280 private:
281 Value* ptr;
282 Value* index;
283 };
284
285 class PtrOffsetInstruction : public Instruction
286 {
287 public:
288 PtrOffsetInstruction(Value* ptr_, Value* offset_);
289 Type* GetType(Context& context) override { return ptr->GetType(context); }
290 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
291 private:
292 Value* ptr;
293 Value* offset;
294 };
295
296 class PtrDiffInstruction : public Instruction
297 {
298 public:
299 PtrDiffInstruction(Value* leftPtr_, Value* rightPtr_);
300 Type* GetType(Context& context) override;
301 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
302 private:
303 Value* leftPtr;
304 Value* rightPtr;
305 };
306
307 class CallInstruction : public Instruction
308 {
309 public:
310 CallInstruction(Value* function_);
311 Type* GetType(Context& context) override;
312 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
313 private:
314 Value* function;
315 };
316
317 class RetInstruction : public Instruction
318 {
319 public:
320 RetInstruction(Value* value_);
321 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
322 private:
323 Value* value;
324 };
325
326 class JumpInstruction : public Instruction
327 {
328 public:
329 JumpInstruction(BasicBlock* dest_);
330 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
331 private:
332 BasicBlock* dest;
333 };
334
335 class BranchInstruction : public Instruction
336 {
337 public:
338 BranchInstruction(Value* cond_, BasicBlock* trueDest_, BasicBlock* falseDest_);
339 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
340 private:
341 Value* cond;
342 BasicBlock* trueDest;
343 BasicBlock* falseDest;
344 };
345
346 class SwitchInstruction : public Instruction
347 {
348 public:
349 SwitchInstruction(Value* cond_, BasicBlock* defaultDest_);
350 void AddCase(Value* caseValue, BasicBlock* dest);
351 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
352 private:
353 Value* cond;
354 BasicBlock* defaultDest;
355 std::vector<std::std::pair<Value*, BasicBlock*>>destinations;
356 };
357
358 class TrapInstruction : public Instruction
359 {
360 public:
361 TrapInstruction(Value* b0_, Value* b1_, Value* b2_);
362 Type* GetType(Context& context) override;
363 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
364 private:
365 Value* b0;
366 Value* b1;
367 Value* b2;
368 };
369
370 class NoOperationInstruction : public Instruction
371 {
372 public:
373 NoOperationInstruction();
374 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
375 bool IsNoOperation() const override { return true; }
376 };
377
378 class SaveInstruction : public Instruction
379 {
380 public:
381 SaveInstruction();
382 void Write(CodeFormatter& formatter, Function& function, Context& context) override;
383 };
384
385 }
386
387 #endif // CMAJOR_CMSXI_INSTRUCTION_INCLUDED