xref: /freebsd/contrib/llvm-project/clang/lib/AST/Interp/Opcodes.td (revision 7ef62cebc2f965b0f640263e179276928885e33d)
1//===--- 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 = "const Function *"; }
46def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; }
47def ArgRecordField : ArgType { let Name = "const Record::Field *"; }
48
49//===----------------------------------------------------------------------===//
50// Classes of types instructions operate on.
51//===----------------------------------------------------------------------===//
52
53class TypeClass {
54  list<Type> Types;
55}
56
57def NumberTypeClass : TypeClass {
58  let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
59               Uint32, Sint64, Uint64];
60}
61
62def IntegerTypeClass : TypeClass {
63  let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
64               Uint32, Sint64, Uint64];
65}
66
67def AluTypeClass : TypeClass {
68  let Types = !listconcat(NumberTypeClass.Types, [Bool]);
69}
70
71def PtrTypeClass : TypeClass {
72  let Types = [Ptr];
73}
74
75def BoolTypeClass : TypeClass {
76  let Types = [Bool];
77}
78
79def AllTypeClass : TypeClass {
80  let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types);
81}
82
83def ComparableTypeClass : TypeClass {
84  let Types = !listconcat(AluTypeClass.Types, [Ptr]);
85}
86
87class SingletonTypeClass<Type Ty> : TypeClass {
88  let Types = [Ty];
89}
90
91//===----------------------------------------------------------------------===//
92// Record describing all opcodes.
93//===----------------------------------------------------------------------===//
94
95class Opcode {
96  list<TypeClass> Types = [];
97  list<ArgType> Args = [];
98  string Name = "";
99  bit CanReturn = 0;
100  bit ChangesPC = 0;
101  bit HasCustomLink = 0;
102  bit HasCustomEval = 0;
103  bit HasGroup = 0;
104}
105
106class AluOpcode : Opcode {
107  let Types = [AluTypeClass];
108  let HasGroup = 1;
109}
110
111class IntegerOpcode : Opcode {
112  let Types = [IntegerTypeClass];
113  let HasGroup = 1;
114}
115
116//===----------------------------------------------------------------------===//
117// Jump opcodes
118//===----------------------------------------------------------------------===//
119
120class JumpOpcode : Opcode {
121  let Args = [ArgSint32];
122  let ChangesPC = 1;
123  let HasCustomEval = 1;
124}
125
126// [] -> []
127def Jmp : JumpOpcode;
128// [Bool] -> [], jumps if true.
129def Jt : JumpOpcode;
130// [Bool] -> [], jumps if false.
131def Jf : JumpOpcode;
132
133//===----------------------------------------------------------------------===//
134// Returns
135//===----------------------------------------------------------------------===//
136
137// [Value] -> []
138def Ret : Opcode {
139  let Types = [AllTypeClass];
140  let ChangesPC = 1;
141  let CanReturn = 1;
142  let HasGroup = 1;
143  let HasCustomEval = 1;
144}
145// [] -> []
146def RetVoid : Opcode {
147  let CanReturn = 1;
148  let ChangesPC = 1;
149  let HasCustomEval = 1;
150}
151// [Value] -> []
152def RetValue : Opcode {
153  let CanReturn = 1;
154  let ChangesPC = 1;
155  let HasCustomEval = 1;
156}
157// [] -> EXIT
158def NoRet : Opcode {}
159
160
161def Call : Opcode {
162  let Args = [ArgFunction];
163  let Types = [];
164  let ChangesPC = 1;
165}
166
167//===----------------------------------------------------------------------===//
168// Frame management
169//===----------------------------------------------------------------------===//
170
171// [] -> []
172def Destroy : Opcode {
173  let Args = [ArgUint32];
174  let HasCustomEval = 1;
175}
176
177//===----------------------------------------------------------------------===//
178// Constants
179//===----------------------------------------------------------------------===//
180
181class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
182  let Types = [SingletonTypeClass<Ty>];
183  let Args = [ArgTy];
184  let Name = "Const";
185}
186
187// [] -> [Integer]
188def ConstSint8 : ConstOpcode<Sint8, ArgSint8>;
189def ConstUint8 : ConstOpcode<Uint8, ArgUint8>;
190def ConstSint16 : ConstOpcode<Sint16, ArgSint16>;
191def ConstUint16 : ConstOpcode<Uint16, ArgUint16>;
192def ConstSint32 : ConstOpcode<Sint32, ArgSint32>;
193def ConstUint32 : ConstOpcode<Uint32, ArgUint32>;
194def ConstSint64 : ConstOpcode<Sint64, ArgSint64>;
195def ConstUint64 : ConstOpcode<Uint64, ArgUint64>;
196def ConstBool : ConstOpcode<Bool, ArgBool>;
197
198// [] -> [Integer]
199def Zero : Opcode {
200  let Types = [AluTypeClass];
201  let HasGroup = 1;
202}
203
204// [] -> [Pointer]
205def Null : Opcode {
206  let Types = [PtrTypeClass];
207}
208
209//===----------------------------------------------------------------------===//
210// Pointer generation
211//===----------------------------------------------------------------------===//
212
213// [] -> [Pointer]
214def GetPtrLocal : Opcode {
215  // Offset of local.
216  let Args = [ArgUint32];
217  bit HasCustomEval = 1;
218}
219// [] -> [Pointer]
220def GetPtrParam : Opcode {
221  // Offset of parameter.
222  let Args = [ArgUint32];
223}
224// [] -> [Pointer]
225def GetPtrGlobal : Opcode {
226  // Index of global.
227  let Args = [ArgUint32];
228}
229// [Pointer] -> [Pointer]
230def GetPtrField : Opcode {
231  // Offset of field.
232  let Args = [ArgUint32];
233}
234// [Pointer] -> [Pointer]
235def GetPtrActiveField : Opcode {
236  // Offset of field.
237  let Args = [ArgUint32];
238}
239// [] -> [Pointer]
240def GetPtrActiveThisField : Opcode {
241  // Offset of field.
242  let Args = [ArgUint32];
243}
244// [] -> [Pointer]
245def GetPtrThisField : Opcode {
246  // Offset of field.
247  let Args = [ArgUint32];
248}
249// [Pointer] -> [Pointer]
250def GetPtrBase : Opcode {
251  // Offset of field, which is a base.
252  let Args = [ArgUint32];
253}
254// [Pointer] -> [Pointer]
255def GetPtrVirtBase : Opcode {
256  // RecordDecl of base class.
257  let Args = [ArgRecordDecl];
258}
259// [] -> [Pointer]
260def GetPtrThisBase : Opcode {
261  // Offset of field, which is a base.
262  let Args = [ArgUint32];
263}
264// [] -> [Pointer]
265def GetPtrThisVirtBase : Opcode {
266  // RecordDecl of base class.
267  let Args = [ArgRecordDecl];
268}
269// [] -> [Pointer]
270def This : Opcode;
271
272// [] -> [Pointer]
273def RVOPtr : Opcode;
274
275// [Pointer] -> [Pointer]
276def NarrowPtr : Opcode;
277// [Pointer] -> [Pointer]
278def ExpandPtr : Opcode;
279
280//===----------------------------------------------------------------------===//
281// Direct field accessors
282//===----------------------------------------------------------------------===//
283
284class AccessOpcode : Opcode {
285  let Types = [AllTypeClass];
286  let Args = [ArgUint32];
287  let HasGroup = 1;
288}
289
290class BitFieldOpcode : Opcode {
291  let Types = [AluTypeClass];
292  let Args = [ArgRecordField];
293  let HasGroup = 1;
294}
295
296// [] -> [Pointer]
297def GetLocal : AccessOpcode { let HasCustomEval = 1; }
298// [] -> [Pointer]
299def SetLocal : AccessOpcode { let HasCustomEval = 1; }
300
301// [] -> [Value]
302def GetGlobal : AccessOpcode;
303// [Value] -> []
304def InitGlobal : AccessOpcode;
305// [Value] -> []
306def SetGlobal : AccessOpcode;
307
308// [] -> [Value]
309def GetParam : AccessOpcode;
310// [Value] -> []
311def SetParam : AccessOpcode;
312
313// [Pointer] -> [Pointer, Value]
314def GetField : AccessOpcode;
315// [Pointer] -> [Value]
316def GetFieldPop : AccessOpcode;
317// [] -> [Value]
318def GetThisField : AccessOpcode;
319
320// [Pointer, Value] -> [Pointer]
321def SetField : AccessOpcode;
322// [Value] -> []
323def SetThisField : AccessOpcode;
324
325// [Value] -> []
326def InitThisField : AccessOpcode;
327// [Value] -> []
328def InitThisFieldActive : AccessOpcode;
329// [Value] -> []
330def InitThisBitField : BitFieldOpcode;
331// [Pointer, Value] -> []
332def InitField : AccessOpcode;
333// [Pointer, Value] -> []
334def InitBitField : BitFieldOpcode;
335// [Pointer, Value] -> []
336def InitFieldActive : AccessOpcode;
337
338//===----------------------------------------------------------------------===//
339// Pointer access
340//===----------------------------------------------------------------------===//
341
342class LoadOpcode : Opcode {
343  let Types = [AllTypeClass];
344  let HasGroup = 1;
345}
346
347// [Pointer] -> [Pointer, Value]
348def Load : LoadOpcode {}
349// [Pointer] -> [Value]
350def LoadPop : LoadOpcode {}
351
352class StoreOpcode : Opcode {
353  let Types = [AllTypeClass];
354  let HasGroup = 1;
355}
356
357class StoreBitFieldOpcode : Opcode {
358  let Types = [AluTypeClass];
359  let HasGroup = 1;
360}
361
362// [Pointer, Value] -> [Pointer]
363def Store : StoreOpcode {}
364// [Pointer, Value] -> []
365def StorePop : StoreOpcode {}
366
367// [Pointer, Value] -> [Pointer]
368def StoreBitField : StoreBitFieldOpcode {}
369// [Pointer, Value] -> []
370def StoreBitFieldPop : StoreBitFieldOpcode {}
371
372// [Pointer, Value] -> []
373def InitPop : StoreOpcode {}
374// [Pointer, Value] -> [Pointer]
375def InitElem : Opcode {
376  let Types = [AllTypeClass];
377  let Args = [ArgUint32];
378  let HasGroup = 1;
379}
380// [Pointer, Value] -> []
381def InitElemPop : Opcode {
382  let Types = [AllTypeClass];
383  let Args = [ArgUint32];
384  let HasGroup = 1;
385}
386
387//===----------------------------------------------------------------------===//
388// Pointer arithmetic.
389//===----------------------------------------------------------------------===//
390
391// [Pointer, Integral] -> [Pointer]
392def AddOffset : AluOpcode;
393// [Pointer, Integral] -> [Pointer]
394def SubOffset : AluOpcode;
395
396// Pointer, Pointer] - [Integral]
397def SubPtr : Opcode {
398  let Types = [IntegerTypeClass];
399  let HasGroup = 1;
400}
401
402//===----------------------------------------------------------------------===//
403// Binary operators.
404//===----------------------------------------------------------------------===//
405
406// [Real, Real] -> [Real]
407def Sub : AluOpcode;
408def Add : AluOpcode;
409def Mul : AluOpcode;
410def Rem : Opcode {
411  let Types = [NumberTypeClass];
412  let HasGroup = 1;
413}
414
415def Shl : Opcode {
416  let Types = [IntegerTypeClass, IntegerTypeClass];
417  let HasGroup = 1;
418}
419
420def Shr : Opcode {
421  let Types = [IntegerTypeClass, IntegerTypeClass];
422  let HasGroup = 1;
423}
424
425def BitAnd : IntegerOpcode;
426def BitOr : IntegerOpcode;
427def Div : Opcode {
428  let Types = [NumberTypeClass];
429  let HasGroup = 1;
430}
431def BitXor : IntegerOpcode;
432
433//===----------------------------------------------------------------------===//
434// Unary operators.
435//===----------------------------------------------------------------------===//
436
437// [Real] -> [Real]
438def Inv: Opcode {
439  let Types = [BoolTypeClass];
440  let HasGroup = 1;
441}
442
443def Inc: IntegerOpcode;
444def IncPop : IntegerOpcode;
445def Dec: IntegerOpcode;
446def DecPop: IntegerOpcode;
447
448// [Real] -> [Real]
449def Neg: Opcode {
450  let Types = [AluTypeClass];
451  let HasGroup = 1;
452}
453
454// [Real] -> [Real]
455def Comp: Opcode {
456  let Types = [NumberTypeClass];
457  let HasGroup = 1;
458}
459
460//===----------------------------------------------------------------------===//
461// Cast.
462//===----------------------------------------------------------------------===//
463// TODO: Expand this to handle casts between more types.
464
465def FromCastTypeClass : TypeClass {
466  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
467}
468
469def ToCastTypeClass : TypeClass {
470  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
471}
472
473def Cast: Opcode {
474  let Types = [FromCastTypeClass, ToCastTypeClass];
475  let HasGroup = 1;
476}
477
478//===----------------------------------------------------------------------===//
479// Comparison opcodes.
480//===----------------------------------------------------------------------===//
481
482class EqualityOpcode : Opcode {
483  let Types = [AllTypeClass];
484  let HasGroup = 1;
485}
486
487def EQ : EqualityOpcode;
488def NE : EqualityOpcode;
489
490class ComparisonOpcode : Opcode {
491  let Types = [ComparableTypeClass];
492  let HasGroup = 1;
493}
494
495def LT : ComparisonOpcode;
496def LE : ComparisonOpcode;
497def GT : ComparisonOpcode;
498def GE : ComparisonOpcode;
499
500//===----------------------------------------------------------------------===//
501// Stack management.
502//===----------------------------------------------------------------------===//
503
504// [Value] -> []
505def Pop : Opcode {
506  let Types = [AllTypeClass];
507  let HasGroup = 1;
508}
509
510// [Value] -> [Value, Value]
511def Dup : Opcode {
512  let Types = [AllTypeClass];
513  let HasGroup = 1;
514}
515