blob: 4aba5f5cd83cd68e9faa7e48cd2c4a63354914b9 [file] [log] [blame]
Nandor Licker950b70d2019-09-13 09:46:16 +00001//===--- Opcodes.td - Opcode defitions for the constexpr VM -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Helper file used to generate opcodes, the interpreter and the disassembler.
10//
11//===----------------------------------------------------------------------===//
12
13
14//===----------------------------------------------------------------------===//
15// Types evaluated by the interpreter.
16//===----------------------------------------------------------------------===//
17
18class Type;
19def Bool : Type;
20def Sint8 : Type;
21def Uint8 : Type;
22def Sint16 : Type;
23def Uint16 : Type;
24def Sint32 : Type;
25def Uint32 : Type;
26def Sint64 : Type;
27def Uint64 : Type;
28def Ptr : Type;
29
30//===----------------------------------------------------------------------===//
31// Types transferred to the interpreter.
32//===----------------------------------------------------------------------===//
33
34class ArgType { string Name = ?; }
35def ArgSint8 : ArgType { let Name = "int8_t"; }
36def ArgUint8 : ArgType { let Name = "uint8_t"; }
37def ArgSint16 : ArgType { let Name = "int16_t"; }
38def ArgUint16 : ArgType { let Name = "uint16_t"; }
39def ArgSint32 : ArgType { let Name = "int32_t"; }
40def ArgUint32 : ArgType { let Name = "uint32_t"; }
41def ArgSint64 : ArgType { let Name = "int64_t"; }
42def ArgUint64 : ArgType { let Name = "uint64_t"; }
43def ArgBool : ArgType { let Name = "bool"; }
44
45def ArgFunction : ArgType { let Name = "Function *"; }
46def ArgRecord : ArgType { let Name = "Record *"; }
47
48def ArgSema : ArgType { let Name = "const fltSemantics *"; }
49
50def ArgExpr : ArgType { let Name = "const Expr *"; }
51def ArgFloatingLiteral : ArgType { let Name = "const FloatingLiteral *"; }
52def ArgCXXMethodDecl : ArgType { let Name = "const CXXMethodDecl *"; }
53def ArgFunctionDecl : ArgType { let Name = "const FunctionDecl *"; }
54def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; }
55def ArgCXXRecordDecl : ArgType { let Name = "const CXXRecordDecl *"; }
56def ArgValueDecl : ArgType { let Name = "const ValueDecl *"; }
57def ArgRecordField : ArgType { let Name = "const Record::Field *"; }
58
59//===----------------------------------------------------------------------===//
60// Classes of types intructions operate on.
61//===----------------------------------------------------------------------===//
62
63class TypeClass {
64 list<Type> Types;
65}
66
67def AluTypeClass : TypeClass {
68 let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
69 Uint32, Sint64, Uint64, Bool];
70}
71
72def PtrTypeClass : TypeClass {
73 let Types = [Ptr];
74}
75
76def AllTypeClass : TypeClass {
77 let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types);
78}
79
80def ComparableTypeClass : TypeClass {
81 let Types = !listconcat(AluTypeClass.Types, [Ptr]);
82}
83
84class SingletonTypeClass<Type Ty> : TypeClass {
85 let Types = [Ty];
86}
87
88//===----------------------------------------------------------------------===//
89// Record describing all opcodes.
90//===----------------------------------------------------------------------===//
91
92class Opcode {
93 list<TypeClass> Types = [];
94 list<ArgType> Args = [];
95 string Name = "";
96 bit CanReturn = 0;
97 bit ChangesPC = 0;
98 bit HasCustomLink = 0;
99 bit HasCustomEval = 0;
100 bit HasGroup = 0;
101}
102
103class AluOpcode : Opcode {
104 let Types = [AluTypeClass];
105 let HasGroup = 1;
106}
107
108//===----------------------------------------------------------------------===//
109// Jump opcodes
110//===----------------------------------------------------------------------===//
111
112class JumpOpcode : Opcode {
113 let Args = [ArgSint32];
114 let ChangesPC = 1;
115 let HasCustomEval = 1;
116}
117
118// [] -> []
119def Jmp : JumpOpcode;
120// [Bool] -> [], jumps if true.
121def Jt : JumpOpcode;
122// [Bool] -> [], jumps if false.
123def Jf : JumpOpcode;
124
125//===----------------------------------------------------------------------===//
126// Returns
127//===----------------------------------------------------------------------===//
128
129// [Value] -> []
130def Ret : Opcode {
131 let Types = [AllTypeClass];
132 let ChangesPC = 1;
133 let CanReturn = 1;
134 let HasGroup = 1;
135 let HasCustomEval = 1;
136}
137// [] -> []
138def RetVoid : Opcode {
139 let CanReturn = 1;
140 let ChangesPC = 1;
141 let HasCustomEval = 1;
142}
143// [Value] -> []
144def RetValue : Opcode {
145 let CanReturn = 1;
146 let ChangesPC = 1;
147 let HasCustomEval = 1;
148}
149// [] -> EXIT
150def NoRet : Opcode {}
151
152//===----------------------------------------------------------------------===//
153// Frame management
154//===----------------------------------------------------------------------===//
155
156// [] -> []
157def Destroy : Opcode {
158 let Args = [ArgUint32];
159 let HasCustomEval = 1;
160}
161
162//===----------------------------------------------------------------------===//
163// Constants
164//===----------------------------------------------------------------------===//
165
166class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
167 let Types = [SingletonTypeClass<Ty>];
168 let Args = [ArgTy];
169 let Name = "Const";
170}
171
172// [] -> [Integer]
173def ConstSint8 : ConstOpcode<Sint8, ArgSint8>;
174def ConstUint8 : ConstOpcode<Uint8, ArgUint8>;
175def ConstSint16 : ConstOpcode<Sint16, ArgSint16>;
176def ConstUint16 : ConstOpcode<Uint16, ArgUint16>;
177def ConstSint32 : ConstOpcode<Sint32, ArgSint32>;
178def ConstUint32 : ConstOpcode<Uint32, ArgUint32>;
179def ConstSint64 : ConstOpcode<Sint64, ArgSint64>;
180def ConstUint64 : ConstOpcode<Uint64, ArgUint64>;
181def ConstBool : ConstOpcode<Bool, ArgBool>;
182
183// [] -> [Integer]
184def Zero : Opcode {
185 let Types = [AluTypeClass];
186}
187
188// [] -> [Pointer]
189def Null : Opcode {
190 let Types = [PtrTypeClass];
191}
192
193//===----------------------------------------------------------------------===//
194// Pointer generation
195//===----------------------------------------------------------------------===//
196
197// [] -> [Pointer]
198def GetPtrLocal : Opcode {
199 // Offset of local.
200 let Args = [ArgUint32];
201 bit HasCustomEval = 1;
202}
203// [] -> [Pointer]
204def GetPtrParam : Opcode {
205 // Offset of parameter.
206 let Args = [ArgUint32];
207}
208// [] -> [Pointer]
209def GetPtrGlobal : Opcode {
210 // Index of global.
211 let Args = [ArgUint32];
212}
213// [Pointer] -> [Pointer]
214def GetPtrField : Opcode {
215 // Offset of field.
216 let Args = [ArgUint32];
217}
218// [Pointer] -> [Pointer]
219def GetPtrActiveField : Opcode {
220 // Offset of field.
221 let Args = [ArgUint32];
222}
223// [] -> [Pointer]
224def GetPtrActiveThisField : Opcode {
225 // Offset of field.
226 let Args = [ArgUint32];
227}
228// [] -> [Pointer]
229def GetPtrThisField : Opcode {
230 // Offset of field.
231 let Args = [ArgUint32];
232}
233// [Pointer] -> [Pointer]
234def GetPtrBase : Opcode {
235 // Offset of field, which is a base.
236 let Args = [ArgUint32];
237}
238// [Pointer] -> [Pointer]
239def GetPtrVirtBase : Opcode {
240 // RecordDecl of base class.
241 let Args = [ArgRecordDecl];
242}
243// [] -> [Pointer]
244def GetPtrThisBase : Opcode {
245 // Offset of field, which is a base.
246 let Args = [ArgUint32];
247}
248// [] -> [Pointer]
249def GetPtrThisVirtBase : Opcode {
250 // RecordDecl of base class.
251 let Args = [ArgRecordDecl];
252}
253// [] -> [Pointer]
254def This : Opcode;
255
256// [Pointer] -> [Pointer]
257def NarrowPtr : Opcode;
258// [Pointer] -> [Pointer]
259def ExpandPtr : Opcode;
260
261//===----------------------------------------------------------------------===//
262// Direct field accessors
263//===----------------------------------------------------------------------===//
264
265class AccessOpcode : Opcode {
266 let Types = [AllTypeClass];
267 let Args = [ArgUint32];
268 let HasGroup = 1;
269}
270
271class BitFieldOpcode : Opcode {
272 let Types = [AluTypeClass];
273 let Args = [ArgRecordField];
274 let HasGroup = 1;
275}
276
277// [] -> [Pointer]
278def GetLocal : AccessOpcode { let HasCustomEval = 1; }
279// [] -> [Pointer]
280def SetLocal : AccessOpcode { let HasCustomEval = 1; }
281
282// [] -> [Value]
283def GetGlobal : AccessOpcode;
284// [Value] -> []
285def InitGlobal : AccessOpcode;
286// [Value] -> []
287def SetGlobal : AccessOpcode;
288
289// [] -> [Value]
290def GetParam : AccessOpcode;
291// [Value] -> []
292def SetParam : AccessOpcode;
293
294// [Pointer] -> [Pointer, Value]
295def GetField : AccessOpcode;
296// [Pointer] -> [Value]
297def GetFieldPop : AccessOpcode;
298// [] -> [Value]
299def GetThisField : AccessOpcode;
300
301// [Pointer, Value] -> [Pointer]
302def SetField : AccessOpcode;
303// [Value] -> []
304def SetThisField : AccessOpcode;
305
306// [Value] -> []
307def InitThisField : AccessOpcode;
308// [Value] -> []
309def InitThisFieldActive : AccessOpcode;
310// [Value] -> []
311def InitThisBitField : BitFieldOpcode;
312// [Pointer, Value] -> []
313def InitField : AccessOpcode;
314// [Pointer, Value] -> []
315def InitBitField : BitFieldOpcode;
316// [Pointer, Value] -> []
317def InitFieldActive : AccessOpcode;
318
319//===----------------------------------------------------------------------===//
320// Pointer access
321//===----------------------------------------------------------------------===//
322
323class LoadOpcode : Opcode {
324 let Types = [AllTypeClass];
325 let HasGroup = 1;
326}
327
328// [Pointer] -> [Pointer, Value]
329def Load : LoadOpcode {}
330// [Pointer] -> [Value]
331def LoadPop : LoadOpcode {}
332
333class StoreOpcode : Opcode {
334 let Types = [AllTypeClass];
335 let HasGroup = 1;
336}
337
338class StoreBitFieldOpcode : Opcode {
339 let Types = [AluTypeClass];
340 let HasGroup = 1;
341}
342
343// [Pointer, Value] -> [Pointer]
344def Store : StoreOpcode {}
345// [Pointer, Value] -> []
346def StorePop : StoreOpcode {}
347
348// [Pointer, Value] -> [Pointer]
349def StoreBitField : StoreBitFieldOpcode {}
350// [Pointer, Value] -> []
351def StoreBitFieldPop : StoreBitFieldOpcode {}
352
353// [Pointer, Value] -> []
354def InitPop : StoreOpcode {}
355// [Pointer, Value] -> [Pointer]
356def InitElem : Opcode {
357 let Types = [AllTypeClass];
358 let Args = [ArgUint32];
359 let HasGroup = 1;
360}
361// [Pointer, Value] -> []
362def InitElemPop : Opcode {
363 let Types = [AllTypeClass];
364 let Args = [ArgUint32];
365 let HasGroup = 1;
366}
367
368//===----------------------------------------------------------------------===//
369// Pointer arithmetic.
370//===----------------------------------------------------------------------===//
371
372// [Pointer, Integral] -> [Pointer]
373def AddOffset : AluOpcode;
374// [Pointer, Integral] -> [Pointer]
375def SubOffset : AluOpcode;
376
377//===----------------------------------------------------------------------===//
378// Binary operators.
379//===----------------------------------------------------------------------===//
380
381// [Real, Real] -> [Real]
382def Sub : AluOpcode;
383def Add : AluOpcode;
384def Mul : AluOpcode;
385
386//===----------------------------------------------------------------------===//
387// Comparison opcodes.
388//===----------------------------------------------------------------------===//
389
390class EqualityOpcode : Opcode {
391 let Types = [AllTypeClass];
392 let HasGroup = 1;
393}
394
395def EQ : EqualityOpcode;
396def NE : EqualityOpcode;
397
398class ComparisonOpcode : Opcode {
399 let Types = [ComparableTypeClass];
400 let HasGroup = 1;
401}
402
403def LT : ComparisonOpcode;
404def LE : ComparisonOpcode;
405def GT : ComparisonOpcode;
406def GE : ComparisonOpcode;
407
408//===----------------------------------------------------------------------===//
409// Stack management.
410//===----------------------------------------------------------------------===//
411
412// [Value] -> []
413def Pop : Opcode {
414 let Types = [AllTypeClass];
415 let HasGroup = 1;
416}
417
418// [Value] -> [Value, Value]
419def Dup : Opcode {
420 let Types = [AllTypeClass];
421 let HasGroup = 1;
422}