1353942Sdim//===--- Opcodes.td - Opcode defitions for the constexpr VM -----*- C++ -*-===//
2353942Sdim//
3353942Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353942Sdim// See https://llvm.org/LICENSE.txt for license information.
5353942Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6353942Sdim//
7353942Sdim//===----------------------------------------------------------------------===//
8353942Sdim//
9353942Sdim// Helper file used to generate opcodes, the interpreter and the disassembler.
10353942Sdim//
11353942Sdim//===----------------------------------------------------------------------===//
12353942Sdim
13353942Sdim
14353942Sdim//===----------------------------------------------------------------------===//
15353942Sdim// Types evaluated by the interpreter.
16353942Sdim//===----------------------------------------------------------------------===//
17353942Sdim
18353942Sdimclass Type;
19353942Sdimdef Bool : Type;
20353942Sdimdef Sint8 : Type;
21353942Sdimdef Uint8 : Type;
22353942Sdimdef Sint16 : Type;
23353942Sdimdef Uint16 : Type;
24353942Sdimdef Sint32 : Type;
25353942Sdimdef Uint32 : Type;
26353942Sdimdef Sint64 : Type;
27353942Sdimdef Uint64 : Type;
28353942Sdimdef Ptr : Type;
29353942Sdim
30353942Sdim//===----------------------------------------------------------------------===//
31353942Sdim// Types transferred to the interpreter.
32353942Sdim//===----------------------------------------------------------------------===//
33353942Sdim
34353942Sdimclass ArgType { string Name = ?; }
35353942Sdimdef ArgSint8 : ArgType { let Name = "int8_t"; }
36353942Sdimdef ArgUint8 : ArgType { let Name = "uint8_t"; }
37353942Sdimdef ArgSint16 : ArgType { let Name = "int16_t"; }
38353942Sdimdef ArgUint16 : ArgType { let Name = "uint16_t"; }
39353942Sdimdef ArgSint32 : ArgType { let Name = "int32_t"; }
40353942Sdimdef ArgUint32 : ArgType { let Name = "uint32_t"; }
41353942Sdimdef ArgSint64 : ArgType { let Name = "int64_t"; }
42353942Sdimdef ArgUint64 : ArgType { let Name = "uint64_t"; }
43353942Sdimdef ArgBool : ArgType { let Name = "bool"; }
44353942Sdim
45353942Sdimdef ArgFunction : ArgType { let Name = "Function *"; }
46353942Sdimdef ArgRecord : ArgType { let Name = "Record *"; }
47353942Sdim
48353942Sdimdef ArgSema : ArgType { let Name = "const fltSemantics *"; }
49353942Sdim
50353942Sdimdef ArgExpr : ArgType { let Name = "const Expr *"; }
51353942Sdimdef ArgFloatingLiteral : ArgType { let Name = "const FloatingLiteral *"; }
52353942Sdimdef ArgCXXMethodDecl : ArgType { let Name = "const CXXMethodDecl *"; }
53353942Sdimdef ArgFunctionDecl : ArgType { let Name = "const FunctionDecl *"; }
54353942Sdimdef ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; }
55353942Sdimdef ArgCXXRecordDecl : ArgType { let Name = "const CXXRecordDecl *"; }
56353942Sdimdef ArgValueDecl : ArgType { let Name = "const ValueDecl *"; }
57353942Sdimdef ArgRecordField : ArgType { let Name = "const Record::Field *"; }
58353942Sdim
59353942Sdim//===----------------------------------------------------------------------===//
60353942Sdim// Classes of types intructions operate on.
61353942Sdim//===----------------------------------------------------------------------===//
62353942Sdim
63353942Sdimclass TypeClass {
64353942Sdim  list<Type> Types;
65353942Sdim}
66353942Sdim
67353942Sdimdef AluTypeClass : TypeClass {
68353942Sdim  let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
69353942Sdim               Uint32, Sint64, Uint64, Bool];
70353942Sdim}
71353942Sdim
72353942Sdimdef PtrTypeClass : TypeClass {
73353942Sdim  let Types = [Ptr];
74353942Sdim}
75353942Sdim
76353942Sdimdef AllTypeClass : TypeClass {
77353942Sdim  let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types);
78353942Sdim}
79353942Sdim
80353942Sdimdef ComparableTypeClass : TypeClass {
81353942Sdim  let Types = !listconcat(AluTypeClass.Types, [Ptr]);
82353942Sdim}
83353942Sdim
84353942Sdimclass SingletonTypeClass<Type Ty> : TypeClass {
85353942Sdim  let Types = [Ty];
86353942Sdim}
87353942Sdim
88353942Sdim//===----------------------------------------------------------------------===//
89353942Sdim// Record describing all opcodes.
90353942Sdim//===----------------------------------------------------------------------===//
91353942Sdim
92353942Sdimclass Opcode {
93353942Sdim  list<TypeClass> Types = [];
94353942Sdim  list<ArgType> Args = [];
95353942Sdim  string Name = "";
96353942Sdim  bit CanReturn = 0;
97353942Sdim  bit ChangesPC = 0;
98353942Sdim  bit HasCustomLink = 0;
99353942Sdim  bit HasCustomEval = 0;
100353942Sdim  bit HasGroup = 0;
101353942Sdim}
102353942Sdim
103353942Sdimclass AluOpcode : Opcode {
104353942Sdim  let Types = [AluTypeClass];
105353942Sdim  let HasGroup = 1;
106353942Sdim}
107353942Sdim
108353942Sdim//===----------------------------------------------------------------------===//
109353942Sdim// Jump opcodes
110353942Sdim//===----------------------------------------------------------------------===//
111353942Sdim
112353942Sdimclass JumpOpcode : Opcode {
113353942Sdim  let Args = [ArgSint32];
114353942Sdim  let ChangesPC = 1;
115353942Sdim  let HasCustomEval = 1;
116353942Sdim}
117353942Sdim
118353942Sdim// [] -> []
119353942Sdimdef Jmp : JumpOpcode;
120353942Sdim// [Bool] -> [], jumps if true.
121353942Sdimdef Jt : JumpOpcode;
122353942Sdim// [Bool] -> [], jumps if false.
123353942Sdimdef Jf : JumpOpcode;
124353942Sdim
125353942Sdim//===----------------------------------------------------------------------===//
126353942Sdim// Returns
127353942Sdim//===----------------------------------------------------------------------===//
128353942Sdim
129353942Sdim// [Value] -> []
130353942Sdimdef Ret : Opcode {
131353942Sdim  let Types = [AllTypeClass];
132353942Sdim  let ChangesPC = 1;
133353942Sdim  let CanReturn = 1;
134353942Sdim  let HasGroup = 1;
135353942Sdim  let HasCustomEval = 1;
136353942Sdim}
137353942Sdim// [] -> []
138353942Sdimdef RetVoid : Opcode {
139353942Sdim  let CanReturn = 1;
140353942Sdim  let ChangesPC = 1;
141353942Sdim  let HasCustomEval = 1;
142353942Sdim}
143353942Sdim// [Value] -> []
144353942Sdimdef RetValue : Opcode {
145353942Sdim  let CanReturn = 1;
146353942Sdim  let ChangesPC = 1;
147353942Sdim  let HasCustomEval = 1;
148353942Sdim}
149353942Sdim// [] -> EXIT
150353942Sdimdef NoRet : Opcode {}
151353942Sdim
152353942Sdim//===----------------------------------------------------------------------===//
153353942Sdim// Frame management
154353942Sdim//===----------------------------------------------------------------------===//
155353942Sdim
156353942Sdim// [] -> []
157353942Sdimdef Destroy : Opcode {
158353942Sdim  let Args = [ArgUint32];
159353942Sdim  let HasCustomEval = 1;
160353942Sdim}
161353942Sdim
162353942Sdim//===----------------------------------------------------------------------===//
163353942Sdim// Constants
164353942Sdim//===----------------------------------------------------------------------===//
165353942Sdim
166353942Sdimclass ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
167353942Sdim  let Types = [SingletonTypeClass<Ty>];
168353942Sdim  let Args = [ArgTy];
169353942Sdim  let Name = "Const";
170353942Sdim}
171353942Sdim
172353942Sdim// [] -> [Integer]
173353942Sdimdef ConstSint8 : ConstOpcode<Sint8, ArgSint8>;
174353942Sdimdef ConstUint8 : ConstOpcode<Uint8, ArgUint8>;
175353942Sdimdef ConstSint16 : ConstOpcode<Sint16, ArgSint16>;
176353942Sdimdef ConstUint16 : ConstOpcode<Uint16, ArgUint16>;
177353942Sdimdef ConstSint32 : ConstOpcode<Sint32, ArgSint32>;
178353942Sdimdef ConstUint32 : ConstOpcode<Uint32, ArgUint32>;
179353942Sdimdef ConstSint64 : ConstOpcode<Sint64, ArgSint64>;
180353942Sdimdef ConstUint64 : ConstOpcode<Uint64, ArgUint64>;
181353942Sdimdef ConstBool : ConstOpcode<Bool, ArgBool>;
182353942Sdim
183353942Sdim// [] -> [Integer]
184353942Sdimdef Zero : Opcode {
185353942Sdim  let Types = [AluTypeClass];
186353942Sdim}
187353942Sdim
188353942Sdim// [] -> [Pointer]
189353942Sdimdef Null : Opcode {
190353942Sdim  let Types = [PtrTypeClass];
191353942Sdim}
192353942Sdim
193353942Sdim//===----------------------------------------------------------------------===//
194353942Sdim// Pointer generation
195353942Sdim//===----------------------------------------------------------------------===//
196353942Sdim
197353942Sdim// [] -> [Pointer]
198353942Sdimdef GetPtrLocal : Opcode {
199353942Sdim  // Offset of local.
200353942Sdim  let Args = [ArgUint32];
201353942Sdim  bit HasCustomEval = 1;
202353942Sdim}
203353942Sdim// [] -> [Pointer]
204353942Sdimdef GetPtrParam : Opcode {
205353942Sdim  // Offset of parameter.
206353942Sdim  let Args = [ArgUint32];
207353942Sdim}
208353942Sdim// [] -> [Pointer]
209353942Sdimdef GetPtrGlobal : Opcode {
210353942Sdim  // Index of global.
211353942Sdim  let Args = [ArgUint32];
212353942Sdim}
213353942Sdim// [Pointer] -> [Pointer]
214353942Sdimdef GetPtrField : Opcode {
215353942Sdim  // Offset of field.
216353942Sdim  let Args = [ArgUint32];
217353942Sdim}
218353942Sdim// [Pointer] -> [Pointer]
219353942Sdimdef GetPtrActiveField : Opcode {
220353942Sdim  // Offset of field.
221353942Sdim  let Args = [ArgUint32];
222353942Sdim}
223353942Sdim// [] -> [Pointer]
224353942Sdimdef GetPtrActiveThisField : Opcode {
225353942Sdim  // Offset of field.
226353942Sdim  let Args = [ArgUint32];
227353942Sdim}
228353942Sdim// [] -> [Pointer]
229353942Sdimdef GetPtrThisField : Opcode {
230353942Sdim  // Offset of field.
231353942Sdim  let Args = [ArgUint32];
232353942Sdim}
233353942Sdim// [Pointer] -> [Pointer]
234353942Sdimdef GetPtrBase : Opcode {
235353942Sdim  // Offset of field, which is a base.
236353942Sdim  let Args = [ArgUint32];
237353942Sdim}
238353942Sdim// [Pointer] -> [Pointer]
239353942Sdimdef GetPtrVirtBase : Opcode {
240353942Sdim  // RecordDecl of base class.
241353942Sdim  let Args = [ArgRecordDecl];
242353942Sdim}
243353942Sdim// [] -> [Pointer]
244353942Sdimdef GetPtrThisBase : Opcode {
245353942Sdim  // Offset of field, which is a base.
246353942Sdim  let Args = [ArgUint32];
247353942Sdim}
248353942Sdim// [] -> [Pointer]
249353942Sdimdef GetPtrThisVirtBase : Opcode {
250353942Sdim  // RecordDecl of base class.
251353942Sdim  let Args = [ArgRecordDecl];
252353942Sdim}
253353942Sdim// [] -> [Pointer]
254353942Sdimdef This : Opcode;
255353942Sdim
256353942Sdim// [Pointer] -> [Pointer]
257353942Sdimdef NarrowPtr : Opcode;
258353942Sdim// [Pointer] -> [Pointer]
259353942Sdimdef ExpandPtr : Opcode;
260353942Sdim
261353942Sdim//===----------------------------------------------------------------------===//
262353942Sdim// Direct field accessors
263353942Sdim//===----------------------------------------------------------------------===//
264353942Sdim
265353942Sdimclass AccessOpcode : Opcode {
266353942Sdim  let Types = [AllTypeClass];
267353942Sdim  let Args = [ArgUint32];
268353942Sdim  let HasGroup = 1;
269353942Sdim}
270353942Sdim
271353942Sdimclass BitFieldOpcode : Opcode {
272353942Sdim  let Types = [AluTypeClass];
273353942Sdim  let Args = [ArgRecordField];
274353942Sdim  let HasGroup = 1;
275353942Sdim}
276353942Sdim
277353942Sdim// [] -> [Pointer]
278353942Sdimdef GetLocal : AccessOpcode { let HasCustomEval = 1; }
279353942Sdim// [] -> [Pointer]
280353942Sdimdef SetLocal : AccessOpcode { let HasCustomEval = 1; }
281353942Sdim
282353942Sdim// [] -> [Value]
283353942Sdimdef GetGlobal : AccessOpcode;
284353942Sdim// [Value] -> []
285353942Sdimdef InitGlobal : AccessOpcode;
286353942Sdim// [Value] -> []
287353942Sdimdef SetGlobal : AccessOpcode;
288353942Sdim
289353942Sdim// [] -> [Value]
290353942Sdimdef GetParam : AccessOpcode;
291353942Sdim// [Value] -> []
292353942Sdimdef SetParam : AccessOpcode;
293353942Sdim
294353942Sdim// [Pointer] -> [Pointer, Value]
295353942Sdimdef GetField : AccessOpcode;
296353942Sdim// [Pointer] -> [Value]
297353942Sdimdef GetFieldPop : AccessOpcode;
298353942Sdim// [] -> [Value]
299353942Sdimdef GetThisField : AccessOpcode;
300353942Sdim
301353942Sdim// [Pointer, Value] -> [Pointer]
302353942Sdimdef SetField : AccessOpcode;
303353942Sdim// [Value] -> []
304353942Sdimdef SetThisField : AccessOpcode;
305353942Sdim
306353942Sdim// [Value] -> []
307353942Sdimdef InitThisField : AccessOpcode;
308353942Sdim// [Value] -> []
309353942Sdimdef InitThisFieldActive : AccessOpcode;
310353942Sdim// [Value] -> []
311353942Sdimdef InitThisBitField : BitFieldOpcode;
312353942Sdim// [Pointer, Value] -> []
313353942Sdimdef InitField : AccessOpcode;
314353942Sdim// [Pointer, Value] -> []
315353942Sdimdef InitBitField : BitFieldOpcode;
316353942Sdim// [Pointer, Value] -> []
317353942Sdimdef InitFieldActive : AccessOpcode;
318353942Sdim
319353942Sdim//===----------------------------------------------------------------------===//
320353942Sdim// Pointer access
321353942Sdim//===----------------------------------------------------------------------===//
322353942Sdim
323353942Sdimclass LoadOpcode : Opcode {
324353942Sdim  let Types = [AllTypeClass];
325353942Sdim  let HasGroup = 1;
326353942Sdim}
327353942Sdim
328353942Sdim// [Pointer] -> [Pointer, Value]
329353942Sdimdef Load : LoadOpcode {}
330353942Sdim// [Pointer] -> [Value]
331353942Sdimdef LoadPop : LoadOpcode {}
332353942Sdim
333353942Sdimclass StoreOpcode : Opcode {
334353942Sdim  let Types = [AllTypeClass];
335353942Sdim  let HasGroup = 1;
336353942Sdim}
337353942Sdim
338353942Sdimclass StoreBitFieldOpcode : Opcode {
339353942Sdim  let Types = [AluTypeClass];
340353942Sdim  let HasGroup = 1;
341353942Sdim}
342353942Sdim
343353942Sdim// [Pointer, Value] -> [Pointer]
344353942Sdimdef Store : StoreOpcode {}
345353942Sdim// [Pointer, Value] -> []
346353942Sdimdef StorePop : StoreOpcode {}
347353942Sdim
348353942Sdim// [Pointer, Value] -> [Pointer]
349353942Sdimdef StoreBitField : StoreBitFieldOpcode {}
350353942Sdim// [Pointer, Value] -> []
351353942Sdimdef StoreBitFieldPop : StoreBitFieldOpcode {}
352353942Sdim
353353942Sdim// [Pointer, Value] -> []
354353942Sdimdef InitPop : StoreOpcode {}
355353942Sdim// [Pointer, Value] -> [Pointer]
356353942Sdimdef InitElem : Opcode {
357353942Sdim  let Types = [AllTypeClass];
358353942Sdim  let Args = [ArgUint32];
359353942Sdim  let HasGroup = 1;
360353942Sdim}
361353942Sdim// [Pointer, Value] -> []
362353942Sdimdef InitElemPop : Opcode {
363353942Sdim  let Types = [AllTypeClass];
364353942Sdim  let Args = [ArgUint32];
365353942Sdim  let HasGroup = 1;
366353942Sdim}
367353942Sdim
368353942Sdim//===----------------------------------------------------------------------===//
369353942Sdim// Pointer arithmetic.
370353942Sdim//===----------------------------------------------------------------------===//
371353942Sdim
372353942Sdim// [Pointer, Integral] -> [Pointer]
373353942Sdimdef AddOffset : AluOpcode;
374353942Sdim// [Pointer, Integral] -> [Pointer]
375353942Sdimdef SubOffset : AluOpcode;
376353942Sdim
377353942Sdim//===----------------------------------------------------------------------===//
378353942Sdim// Binary operators.
379353942Sdim//===----------------------------------------------------------------------===//
380353942Sdim
381353942Sdim// [Real, Real] -> [Real]
382353942Sdimdef Sub : AluOpcode;
383353942Sdimdef Add : AluOpcode;
384353942Sdimdef Mul : AluOpcode;
385353942Sdim
386353942Sdim//===----------------------------------------------------------------------===//
387353942Sdim// Comparison opcodes.
388353942Sdim//===----------------------------------------------------------------------===//
389353942Sdim
390353942Sdimclass EqualityOpcode : Opcode {
391353942Sdim  let Types = [AllTypeClass];
392353942Sdim  let HasGroup = 1;
393353942Sdim}
394353942Sdim
395353942Sdimdef EQ : EqualityOpcode;
396353942Sdimdef NE : EqualityOpcode;
397353942Sdim
398353942Sdimclass ComparisonOpcode : Opcode {
399353942Sdim  let Types = [ComparableTypeClass];
400353942Sdim  let HasGroup = 1;
401353942Sdim}
402353942Sdim
403353942Sdimdef LT : ComparisonOpcode;
404353942Sdimdef LE : ComparisonOpcode;
405353942Sdimdef GT : ComparisonOpcode;
406353942Sdimdef GE : ComparisonOpcode;
407353942Sdim
408353942Sdim//===----------------------------------------------------------------------===//
409353942Sdim// Stack management.
410353942Sdim//===----------------------------------------------------------------------===//
411353942Sdim
412353942Sdim// [Value] -> []
413353942Sdimdef Pop : Opcode {
414353942Sdim  let Types = [AllTypeClass];
415353942Sdim  let HasGroup = 1;
416353942Sdim}
417353942Sdim
418353942Sdim// [Value] -> [Value, Value]
419353942Sdimdef Dup : Opcode {
420353942Sdim  let Types = [AllTypeClass];
421353942Sdim  let HasGroup = 1;
422353942Sdim}
423