xref: /freebsd/contrib/llvm-project/clang/lib/AST/Interp/Opcodes.td (revision a90b9d0159070121c221b966469c3e36d912bf82)
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 IntAP : Type;
29def IntAPS : Type;
30def Float : Type;
31def Ptr : Type;
32def FnPtr : Type;
33
34//===----------------------------------------------------------------------===//
35// Types transferred to the interpreter.
36//===----------------------------------------------------------------------===//
37
38class ArgType { string Name = ?; }
39def ArgSint8 : ArgType { let Name = "int8_t"; }
40def ArgUint8 : ArgType { let Name = "uint8_t"; }
41def ArgSint16 : ArgType { let Name = "int16_t"; }
42def ArgUint16 : ArgType { let Name = "uint16_t"; }
43def ArgSint32 : ArgType { let Name = "int32_t"; }
44def ArgUint32 : ArgType { let Name = "uint32_t"; }
45def ArgSint64 : ArgType { let Name = "int64_t"; }
46def ArgUint64 : ArgType { let Name = "uint64_t"; }
47def ArgFloat : ArgType { let Name = "Floating"; }
48def ArgBool : ArgType { let Name = "bool"; }
49
50def ArgFunction : ArgType { let Name = "const Function *"; }
51def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; }
52def ArgRecordField : ArgType { let Name = "const Record::Field *"; }
53def ArgFltSemantics : ArgType { let Name = "const llvm::fltSemantics *"; }
54def ArgRoundingMode : ArgType { let Name = "llvm::RoundingMode"; }
55def ArgLETD: ArgType { let Name = "const LifetimeExtendedTemporaryDecl *"; }
56def ArgCastKind : ArgType { let Name = "CastKind"; }
57def ArgCallExpr : ArgType { let Name = "const CallExpr *"; }
58def ArgOffsetOfExpr : ArgType { let Name = "const OffsetOfExpr *"; }
59def ArgDeclRef : ArgType { let Name = "const DeclRefExpr *"; }
60def ArgCCI : ArgType { let Name = "const ComparisonCategoryInfo *"; }
61
62//===----------------------------------------------------------------------===//
63// Classes of types instructions operate on.
64//===----------------------------------------------------------------------===//
65
66class TypeClass {
67  list<Type> Types;
68}
69
70def IntegerTypeClass : TypeClass {
71  let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
72               Uint32, Sint64, Uint64, IntAP, IntAPS];
73}
74
75def FixedSizeIntegralTypeClass : TypeClass {
76  let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
77               Uint32, Sint64, Uint64, Bool];
78}
79
80def NumberTypeClass : TypeClass {
81  let Types = !listconcat(IntegerTypeClass.Types, [Float]);
82}
83
84def FloatTypeClass : TypeClass {
85  let Types = [Float];
86}
87
88def AluTypeClass : TypeClass {
89  let Types = !listconcat(IntegerTypeClass.Types, [Bool]);
90}
91
92def PtrTypeClass : TypeClass {
93  let Types = [Ptr, FnPtr];
94}
95
96def BoolTypeClass : TypeClass {
97  let Types = [Bool];
98}
99
100def NonPtrTypeClass : TypeClass {
101  let Types = !listconcat(IntegerTypeClass.Types, [Bool], [Float]);
102}
103
104def AllTypeClass : TypeClass {
105  let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types, FloatTypeClass.Types);
106}
107
108def ComparableTypeClass : TypeClass {
109  let Types = !listconcat(AluTypeClass.Types, [Ptr], [Float], [FnPtr]);
110}
111
112class SingletonTypeClass<Type Ty> : TypeClass {
113  let Types = [Ty];
114}
115
116//===----------------------------------------------------------------------===//
117// Record describing all opcodes.
118//===----------------------------------------------------------------------===//
119
120class Opcode {
121  list<TypeClass> Types = [];
122  list<ArgType> Args = [];
123  string Name = "";
124  bit CanReturn = 0;
125  bit ChangesPC = 0;
126  bit HasCustomLink = 0;
127  bit HasCustomEval = 0;
128  bit HasGroup = 0;
129}
130
131class AluOpcode : Opcode {
132  let Types = [AluTypeClass];
133  let HasGroup = 1;
134}
135
136class FloatOpcode : Opcode {
137  let Types = [];
138  let Args = [ArgRoundingMode];
139}
140
141class IntegerOpcode : Opcode {
142  let Types = [IntegerTypeClass];
143  let HasGroup = 1;
144}
145
146//===----------------------------------------------------------------------===//
147// Jump opcodes
148//===----------------------------------------------------------------------===//
149
150class JumpOpcode : Opcode {
151  let Args = [ArgSint32];
152  let ChangesPC = 1;
153  let HasCustomEval = 1;
154}
155
156// [] -> []
157def Jmp : JumpOpcode;
158// [Bool] -> [], jumps if true.
159def Jt : JumpOpcode;
160// [Bool] -> [], jumps if false.
161def Jf : JumpOpcode;
162
163//===----------------------------------------------------------------------===//
164// Returns
165//===----------------------------------------------------------------------===//
166
167// [Value] -> []
168def Ret : Opcode {
169  let Types = [AllTypeClass];
170  let ChangesPC = 1;
171  let CanReturn = 1;
172  let HasGroup = 1;
173  let HasCustomEval = 1;
174}
175// [] -> []
176def RetVoid : Opcode {
177  let CanReturn = 1;
178  let ChangesPC = 1;
179  let HasCustomEval = 1;
180}
181// [Value] -> []
182def RetValue : Opcode {
183  let CanReturn = 1;
184  let ChangesPC = 1;
185  let HasCustomEval = 1;
186}
187// [] -> EXIT
188def NoRet : Opcode {}
189
190
191def Call : Opcode {
192  let Args = [ArgFunction];
193  let Types = [];
194}
195
196def CallVirt : Opcode {
197  let Args = [ArgFunction];
198  let Types = [];
199}
200
201def CallBI : Opcode {
202  let Args = [ArgFunction, ArgCallExpr];
203  let Types = [];
204}
205
206def CallPtr : Opcode {
207  let Args = [];
208  let Types = [];
209}
210
211def OffsetOf : Opcode {
212  let Types = [IntegerTypeClass];
213  let Args = [ArgOffsetOfExpr];
214  let HasGroup = 1;
215}
216
217//===----------------------------------------------------------------------===//
218// Frame management
219//===----------------------------------------------------------------------===//
220
221// [] -> []
222def Destroy : Opcode {
223  let Args = [ArgUint32];
224  let HasCustomEval = 1;
225}
226
227//===----------------------------------------------------------------------===//
228// Constants
229//===----------------------------------------------------------------------===//
230
231class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
232  let Types = [SingletonTypeClass<Ty>];
233  let Args = [ArgTy];
234  let Name = "Const";
235}
236
237// [] -> [Integer]
238def ConstSint8 : ConstOpcode<Sint8, ArgSint8>;
239def ConstUint8 : ConstOpcode<Uint8, ArgUint8>;
240def ConstSint16 : ConstOpcode<Sint16, ArgSint16>;
241def ConstUint16 : ConstOpcode<Uint16, ArgUint16>;
242def ConstSint32 : ConstOpcode<Sint32, ArgSint32>;
243def ConstUint32 : ConstOpcode<Uint32, ArgUint32>;
244def ConstSint64 : ConstOpcode<Sint64, ArgSint64>;
245def ConstUint64 : ConstOpcode<Uint64, ArgUint64>;
246def ConstFloat : ConstOpcode<Float, ArgFloat>;
247def ConstBool : ConstOpcode<Bool, ArgBool>;
248
249// [] -> [Integer]
250def Zero : Opcode {
251  let Types = [FixedSizeIntegralTypeClass];
252  let HasGroup = 1;
253}
254
255def ZeroIntAP : Opcode {
256  let Args = [ArgUint32];
257}
258
259def ZeroIntAPS : Opcode {
260  let Args = [ArgUint32];
261}
262
263// [] -> [Pointer]
264def Null : Opcode {
265  let Types = [PtrTypeClass];
266  let HasGroup = 1;
267}
268
269//===----------------------------------------------------------------------===//
270// Pointer generation
271//===----------------------------------------------------------------------===//
272
273// [] -> [Pointer]
274def GetPtrLocal : Opcode {
275  // Offset of local.
276  let Args = [ArgUint32];
277  bit HasCustomEval = 1;
278}
279// [] -> [Pointer]
280def GetPtrParam : Opcode {
281  // Offset of parameter.
282  let Args = [ArgUint32];
283}
284// [] -> [Pointer]
285def GetPtrGlobal : Opcode {
286  // Index of global.
287  let Args = [ArgUint32];
288}
289// [Pointer] -> [Pointer]
290def GetPtrField : Opcode {
291  // Offset of field.
292  let Args = [ArgUint32];
293}
294// [Pointer] -> [Pointer]
295def GetPtrActiveField : Opcode {
296  // Offset of field.
297  let Args = [ArgUint32];
298}
299// [] -> [Pointer]
300def GetPtrActiveThisField : Opcode {
301  // Offset of field.
302  let Args = [ArgUint32];
303}
304// [] -> [Pointer]
305def GetPtrThisField : Opcode {
306  // Offset of field.
307  let Args = [ArgUint32];
308}
309// [Pointer] -> [Pointer]
310def GetPtrBase : Opcode {
311  // Offset of field, which is a base.
312  let Args = [ArgUint32];
313}
314// [Pointer] -> [Pointer]
315def GetPtrBasePop : Opcode {
316  // Offset of field, which is a base.
317  let Args = [ArgUint32];
318}
319
320def InitPtrPop : Opcode {
321  let Args = [];
322}
323
324def GetPtrDerivedPop : Opcode {
325  let Args = [ArgUint32];
326}
327
328// [Pointer] -> [Pointer]
329def GetPtrVirtBase : Opcode {
330  // RecordDecl of base class.
331  let Args = [ArgRecordDecl];
332}
333// [] -> [Pointer]
334def GetPtrThisBase : Opcode {
335  // Offset of field, which is a base.
336  let Args = [ArgUint32];
337}
338// [] -> [Pointer]
339def GetPtrThisVirtBase : Opcode {
340  // RecordDecl of base class.
341  let Args = [ArgRecordDecl];
342}
343// [] -> [Pointer]
344def This : Opcode;
345
346// [] -> [Pointer]
347def RVOPtr : Opcode;
348
349// [Pointer] -> [Pointer]
350def NarrowPtr : Opcode;
351// [Pointer] -> [Pointer]
352def ExpandPtr : Opcode;
353// [Pointer, Offset] -> [Pointer]
354def ArrayElemPtr : AluOpcode;
355def ArrayElemPtrPop : AluOpcode;
356
357//===----------------------------------------------------------------------===//
358// Direct field accessors
359//===----------------------------------------------------------------------===//
360
361class AccessOpcode : Opcode {
362  let Types = [AllTypeClass];
363  let Args = [ArgUint32];
364  let HasGroup = 1;
365}
366
367class BitFieldOpcode : Opcode {
368  let Types = [AluTypeClass];
369  let Args = [ArgRecordField];
370  let HasGroup = 1;
371}
372
373// [] -> [Pointer]
374def GetLocal : AccessOpcode { let HasCustomEval = 1; }
375// [] -> [Pointer]
376def SetLocal : AccessOpcode { let HasCustomEval = 1; }
377
378// [] -> [Value]
379def GetGlobal : AccessOpcode;
380def GetGlobalUnchecked : AccessOpcode;
381// [Value] -> []
382def InitGlobal : AccessOpcode;
383// [Value] -> []
384def InitGlobalTemp : AccessOpcode {
385  let Args = [ArgUint32, ArgLETD];
386}
387// [Pointer] -> [Pointer]
388def InitGlobalTempComp : Opcode {
389  let Args = [ArgLETD];
390  let Types = [];
391  let HasGroup = 0;
392}
393// [Value] -> []
394def SetGlobal : AccessOpcode;
395
396// [] -> [Value]
397def GetParam : AccessOpcode;
398// [Value] -> []
399def SetParam : AccessOpcode;
400
401// [Pointer] -> [Pointer, Value]
402def GetField : AccessOpcode;
403// [Pointer] -> [Value]
404def GetFieldPop : AccessOpcode;
405// [] -> [Value]
406def GetThisField : AccessOpcode;
407
408// [Pointer, Value] -> [Pointer]
409def SetField : AccessOpcode;
410// [Value] -> []
411def SetThisField : AccessOpcode;
412
413// [Value] -> []
414def InitThisField : AccessOpcode;
415// [Value] -> []
416def InitThisFieldActive : AccessOpcode;
417// [Value] -> []
418def InitThisBitField : Opcode {
419  let Types = [AluTypeClass];
420  let Args = [ArgRecordField, ArgUint32];
421  let HasGroup = 1;
422}
423// [Pointer, Value] -> []
424def InitField : AccessOpcode;
425// [Pointer, Value] -> []
426def InitBitField : BitFieldOpcode;
427// [Pointer, Value] -> []
428def InitFieldActive : AccessOpcode;
429
430//===----------------------------------------------------------------------===//
431// Pointer access
432//===----------------------------------------------------------------------===//
433
434class LoadOpcode : Opcode {
435  let Types = [AllTypeClass];
436  let HasGroup = 1;
437}
438
439// [Pointer] -> [Pointer, Value]
440def Load : LoadOpcode {}
441// [Pointer] -> [Value]
442def LoadPop : LoadOpcode {}
443
444class StoreOpcode : Opcode {
445  let Types = [AllTypeClass];
446  let HasGroup = 1;
447}
448
449class StoreBitFieldOpcode : Opcode {
450  let Types = [AluTypeClass];
451  let HasGroup = 1;
452}
453
454// [Pointer, Value] -> [Pointer]
455def Store : StoreOpcode {}
456// [Pointer, Value] -> []
457def StorePop : StoreOpcode {}
458
459// [Pointer, Value] -> [Pointer]
460def StoreBitField : StoreBitFieldOpcode {}
461// [Pointer, Value] -> []
462def StoreBitFieldPop : StoreBitFieldOpcode {}
463
464// [Pointer, Value] -> []
465def InitPop : StoreOpcode {}
466// [Pointer, Value] -> [Pointer]
467def InitElem : Opcode {
468  let Types = [AllTypeClass];
469  let Args = [ArgUint32];
470  let HasGroup = 1;
471}
472// [Pointer, Value] -> []
473def InitElemPop : Opcode {
474  let Types = [AllTypeClass];
475  let Args = [ArgUint32];
476  let HasGroup = 1;
477}
478
479//===----------------------------------------------------------------------===//
480// Pointer arithmetic.
481//===----------------------------------------------------------------------===//
482
483// [Pointer, Integral] -> [Pointer]
484def AddOffset : AluOpcode;
485// [Pointer, Integral] -> [Pointer]
486def SubOffset : AluOpcode;
487
488// [Pointer, Pointer] -> [Integral]
489def SubPtr : Opcode {
490  let Types = [IntegerTypeClass];
491  let HasGroup = 1;
492}
493
494// [Pointer] -> [Pointer]
495def IncPtr : Opcode {
496  let HasGroup = 0;
497}
498// [Pointer] -> [Pointer]
499def DecPtr : Opcode {
500  let HasGroup = 0;
501}
502
503//===----------------------------------------------------------------------===//
504// Function pointers.
505//===----------------------------------------------------------------------===//
506def GetFnPtr : Opcode {
507  let Args = [ArgFunction];
508}
509
510
511//===----------------------------------------------------------------------===//
512// Binary operators.
513//===----------------------------------------------------------------------===//
514
515// [Real, Real] -> [Real]
516def Add  : AluOpcode;
517def Addf : FloatOpcode;
518def Sub  : AluOpcode;
519def Subf : FloatOpcode;
520def Mul  : AluOpcode;
521def Mulf : FloatOpcode;
522def Rem  : IntegerOpcode;
523def Div  : IntegerOpcode;
524def Divf : FloatOpcode;
525
526def BitAnd : IntegerOpcode;
527def BitOr : IntegerOpcode;
528def BitXor : IntegerOpcode;
529
530def Shl : Opcode {
531  let Types = [IntegerTypeClass, IntegerTypeClass];
532  let HasGroup = 1;
533}
534
535def Shr : Opcode {
536  let Types = [IntegerTypeClass, IntegerTypeClass];
537  let HasGroup = 1;
538}
539
540//===----------------------------------------------------------------------===//
541// Unary operators.
542//===----------------------------------------------------------------------===//
543
544// [Real] -> [Real]
545def Inv: Opcode {
546  let Types = [BoolTypeClass];
547  let HasGroup = 1;
548}
549
550// Increment and decrement.
551def Inc: IntegerOpcode;
552def IncPop : IntegerOpcode;
553def Dec: IntegerOpcode;
554def DecPop: IntegerOpcode;
555
556// Float increment and decrement.
557def Incf: FloatOpcode;
558def IncfPop : FloatOpcode;
559def Decf: FloatOpcode;
560def DecfPop : FloatOpcode;
561
562// [Real] -> [Real]
563def Neg: Opcode {
564  let Types = [NonPtrTypeClass];
565  let HasGroup = 1;
566}
567
568// [Real] -> [Real]
569def Comp: Opcode {
570  let Types = [IntegerTypeClass];
571  let HasGroup = 1;
572}
573
574//===----------------------------------------------------------------------===//
575// Cast, CastFP.
576//===----------------------------------------------------------------------===//
577
578def FromCastTypeClass : TypeClass {
579  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool, IntAP, IntAPS];
580}
581
582def ToCastTypeClass : TypeClass {
583  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
584}
585
586def Cast: Opcode {
587  let Types = [FromCastTypeClass, ToCastTypeClass];
588  let HasGroup = 1;
589}
590
591def CastFP : Opcode {
592  let Types = [];
593  let Args = [ArgFltSemantics, ArgRoundingMode];
594}
595
596def FixedSizeIntegralTypes : TypeClass {
597  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
598}
599
600def CastAP : Opcode {
601  let Types = [AluTypeClass];
602  let Args = [ArgUint32];
603  let HasGroup = 1;
604}
605
606def CastAPS : Opcode {
607  let Types = [AluTypeClass];
608  let Args = [ArgUint32];
609  let HasGroup = 1;
610}
611
612// Cast an integer to a floating type
613def CastIntegralFloating : Opcode {
614  let Types = [AluTypeClass];
615  let Args = [ArgFltSemantics, ArgRoundingMode];
616  let HasGroup = 1;
617}
618
619// Cast a floating to an integer type
620def CastFloatingIntegral : Opcode {
621  let Types = [FixedSizeIntegralTypes];
622  let Args = [];
623  let HasGroup = 1;
624}
625
626def CastFloatingIntegralAP : Opcode {
627  let Types = [];
628  let Args = [ArgUint32];
629}
630
631def CastFloatingIntegralAPS : Opcode {
632  let Types = [];
633  let Args = [ArgUint32];
634}
635
636def CastPointerIntegral : Opcode {
637  let Types = [AluTypeClass];
638  let Args = [];
639  let HasGroup = 1;
640}
641
642//===----------------------------------------------------------------------===//
643// Comparison opcodes.
644//===----------------------------------------------------------------------===//
645
646class EqualityOpcode : Opcode {
647  let Types = [AllTypeClass];
648  let HasGroup = 1;
649}
650
651def EQ : EqualityOpcode;
652def NE : EqualityOpcode;
653
654class ComparisonOpcode : Opcode {
655  let Types = [ComparableTypeClass];
656  let HasGroup = 1;
657}
658
659def CMP3 : ComparisonOpcode {
660  let Args = [ArgCCI];
661}
662
663def LT : ComparisonOpcode;
664def LE : ComparisonOpcode;
665def GT : ComparisonOpcode;
666def GE : ComparisonOpcode;
667
668//===----------------------------------------------------------------------===//
669// Stack management.
670//===----------------------------------------------------------------------===//
671
672// [Value] -> []
673def Pop : Opcode {
674  let Types = [AllTypeClass];
675  let HasGroup = 1;
676}
677
678// [Value] -> [Value, Value]
679def Dup : Opcode {
680  let Types = [AllTypeClass];
681  let HasGroup = 1;
682}
683
684// [] -> []
685def Invalid : Opcode {}
686def InvalidCast : Opcode {
687  let Args = [ArgCastKind];
688}
689
690def InvalidDeclRef : Opcode {
691  let Args = [ArgDeclRef];
692}
693
694def ArrayDecay : Opcode;
695