1 //===--- Opcodes.td - Opcode defitions for the constexpr VM -----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Helper file used to generate opcodes, the interpreter and the disassembler.
11 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // Types evaluated by the interpreter.
16 //===----------------------------------------------------------------------===//
30 //===----------------------------------------------------------------------===//
31 // Types transferred to the interpreter.
32 //===----------------------------------------------------------------------===//
34 class ArgType { string Name = ?; }
35 def ArgSint8 : ArgType { let Name = "int8_t"; }
36 def ArgUint8 : ArgType { let Name = "uint8_t"; }
37 def ArgSint16 : ArgType { let Name = "int16_t"; }
38 def ArgUint16 : ArgType { let Name = "uint16_t"; }
39 def ArgSint32 : ArgType { let Name = "int32_t"; }
40 def ArgUint32 : ArgType { let Name = "uint32_t"; }
41 def ArgSint64 : ArgType { let Name = "int64_t"; }
42 def ArgUint64 : ArgType { let Name = "uint64_t"; }
43 def ArgBool : ArgType { let Name = "bool"; }
45 def ArgFunction : ArgType { let Name = "Function *"; }
46 def ArgRecord : ArgType { let Name = "Record *"; }
48 def ArgSema : ArgType { let Name = "const fltSemantics *"; }
50 def ArgExpr : ArgType { let Name = "const Expr *"; }
51 def ArgFloatingLiteral : ArgType { let Name = "const FloatingLiteral *"; }
52 def ArgCXXMethodDecl : ArgType { let Name = "const CXXMethodDecl *"; }
53 def ArgFunctionDecl : ArgType { let Name = "const FunctionDecl *"; }
54 def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; }
55 def ArgCXXRecordDecl : ArgType { let Name = "const CXXRecordDecl *"; }
56 def ArgValueDecl : ArgType { let Name = "const ValueDecl *"; }
57 def ArgRecordField : ArgType { let Name = "const Record::Field *"; }
59 //===----------------------------------------------------------------------===//
60 // Classes of types intructions operate on.
61 //===----------------------------------------------------------------------===//
67 def AluTypeClass : TypeClass {
68 let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
69 Uint32, Sint64, Uint64, Bool];
72 def PtrTypeClass : TypeClass {
76 def AllTypeClass : TypeClass {
77 let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types);
80 def ComparableTypeClass : TypeClass {
81 let Types = !listconcat(AluTypeClass.Types, [Ptr]);
84 class SingletonTypeClass<Type Ty> : TypeClass {
88 //===----------------------------------------------------------------------===//
89 // Record describing all opcodes.
90 //===----------------------------------------------------------------------===//
93 list<TypeClass> Types = [];
94 list<ArgType> Args = [];
98 bit HasCustomLink = 0;
99 bit HasCustomEval = 0;
103 class AluOpcode : Opcode {
104 let Types = [AluTypeClass];
108 //===----------------------------------------------------------------------===//
110 //===----------------------------------------------------------------------===//
112 class JumpOpcode : Opcode {
113 let Args = [ArgSint32];
115 let HasCustomEval = 1;
119 def Jmp : JumpOpcode;
120 // [Bool] -> [], jumps if true.
122 // [Bool] -> [], jumps if false.
125 //===----------------------------------------------------------------------===//
127 //===----------------------------------------------------------------------===//
131 let Types = [AllTypeClass];
135 let HasCustomEval = 1;
138 def RetVoid : Opcode {
141 let HasCustomEval = 1;
144 def RetValue : Opcode {
147 let HasCustomEval = 1;
150 def NoRet : Opcode {}
152 //===----------------------------------------------------------------------===//
154 //===----------------------------------------------------------------------===//
157 def Destroy : Opcode {
158 let Args = [ArgUint32];
159 let HasCustomEval = 1;
162 //===----------------------------------------------------------------------===//
164 //===----------------------------------------------------------------------===//
166 class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
167 let Types = [SingletonTypeClass<Ty>];
173 def ConstSint8 : ConstOpcode<Sint8, ArgSint8>;
174 def ConstUint8 : ConstOpcode<Uint8, ArgUint8>;
175 def ConstSint16 : ConstOpcode<Sint16, ArgSint16>;
176 def ConstUint16 : ConstOpcode<Uint16, ArgUint16>;
177 def ConstSint32 : ConstOpcode<Sint32, ArgSint32>;
178 def ConstUint32 : ConstOpcode<Uint32, ArgUint32>;
179 def ConstSint64 : ConstOpcode<Sint64, ArgSint64>;
180 def ConstUint64 : ConstOpcode<Uint64, ArgUint64>;
181 def ConstBool : ConstOpcode<Bool, ArgBool>;
185 let Types = [AluTypeClass];
190 let Types = [PtrTypeClass];
193 //===----------------------------------------------------------------------===//
194 // Pointer generation
195 //===----------------------------------------------------------------------===//
198 def GetPtrLocal : Opcode {
200 let Args = [ArgUint32];
201 bit HasCustomEval = 1;
204 def GetPtrParam : Opcode {
205 // Offset of parameter.
206 let Args = [ArgUint32];
209 def GetPtrGlobal : Opcode {
211 let Args = [ArgUint32];
213 // [Pointer] -> [Pointer]
214 def GetPtrField : Opcode {
216 let Args = [ArgUint32];
218 // [Pointer] -> [Pointer]
219 def GetPtrActiveField : Opcode {
221 let Args = [ArgUint32];
224 def GetPtrActiveThisField : Opcode {
226 let Args = [ArgUint32];
229 def GetPtrThisField : Opcode {
231 let Args = [ArgUint32];
233 // [Pointer] -> [Pointer]
234 def GetPtrBase : Opcode {
235 // Offset of field, which is a base.
236 let Args = [ArgUint32];
238 // [Pointer] -> [Pointer]
239 def GetPtrVirtBase : Opcode {
240 // RecordDecl of base class.
241 let Args = [ArgRecordDecl];
244 def GetPtrThisBase : Opcode {
245 // Offset of field, which is a base.
246 let Args = [ArgUint32];
249 def GetPtrThisVirtBase : Opcode {
250 // RecordDecl of base class.
251 let Args = [ArgRecordDecl];
256 // [Pointer] -> [Pointer]
257 def NarrowPtr : Opcode;
258 // [Pointer] -> [Pointer]
259 def ExpandPtr : Opcode;
261 //===----------------------------------------------------------------------===//
262 // Direct field accessors
263 //===----------------------------------------------------------------------===//
265 class AccessOpcode : Opcode {
266 let Types = [AllTypeClass];
267 let Args = [ArgUint32];
271 class BitFieldOpcode : Opcode {
272 let Types = [AluTypeClass];
273 let Args = [ArgRecordField];
278 def GetLocal : AccessOpcode { let HasCustomEval = 1; }
280 def SetLocal : AccessOpcode { let HasCustomEval = 1; }
283 def GetGlobal : AccessOpcode;
285 def InitGlobal : AccessOpcode;
287 def SetGlobal : AccessOpcode;
290 def GetParam : AccessOpcode;
292 def SetParam : AccessOpcode;
294 // [Pointer] -> [Pointer, Value]
295 def GetField : AccessOpcode;
296 // [Pointer] -> [Value]
297 def GetFieldPop : AccessOpcode;
299 def GetThisField : AccessOpcode;
301 // [Pointer, Value] -> [Pointer]
302 def SetField : AccessOpcode;
304 def SetThisField : AccessOpcode;
307 def InitThisField : AccessOpcode;
309 def InitThisFieldActive : AccessOpcode;
311 def InitThisBitField : BitFieldOpcode;
312 // [Pointer, Value] -> []
313 def InitField : AccessOpcode;
314 // [Pointer, Value] -> []
315 def InitBitField : BitFieldOpcode;
316 // [Pointer, Value] -> []
317 def InitFieldActive : AccessOpcode;
319 //===----------------------------------------------------------------------===//
321 //===----------------------------------------------------------------------===//
323 class LoadOpcode : Opcode {
324 let Types = [AllTypeClass];
328 // [Pointer] -> [Pointer, Value]
329 def Load : LoadOpcode {}
330 // [Pointer] -> [Value]
331 def LoadPop : LoadOpcode {}
333 class StoreOpcode : Opcode {
334 let Types = [AllTypeClass];
338 class StoreBitFieldOpcode : Opcode {
339 let Types = [AluTypeClass];
343 // [Pointer, Value] -> [Pointer]
344 def Store : StoreOpcode {}
345 // [Pointer, Value] -> []
346 def StorePop : StoreOpcode {}
348 // [Pointer, Value] -> [Pointer]
349 def StoreBitField : StoreBitFieldOpcode {}
350 // [Pointer, Value] -> []
351 def StoreBitFieldPop : StoreBitFieldOpcode {}
353 // [Pointer, Value] -> []
354 def InitPop : StoreOpcode {}
355 // [Pointer, Value] -> [Pointer]
356 def InitElem : Opcode {
357 let Types = [AllTypeClass];
358 let Args = [ArgUint32];
361 // [Pointer, Value] -> []
362 def InitElemPop : Opcode {
363 let Types = [AllTypeClass];
364 let Args = [ArgUint32];
368 //===----------------------------------------------------------------------===//
369 // Pointer arithmetic.
370 //===----------------------------------------------------------------------===//
372 // [Pointer, Integral] -> [Pointer]
373 def AddOffset : AluOpcode;
374 // [Pointer, Integral] -> [Pointer]
375 def SubOffset : AluOpcode;
377 //===----------------------------------------------------------------------===//
379 //===----------------------------------------------------------------------===//
381 // [Real, Real] -> [Real]
386 //===----------------------------------------------------------------------===//
387 // Comparison opcodes.
388 //===----------------------------------------------------------------------===//
390 class EqualityOpcode : Opcode {
391 let Types = [AllTypeClass];
395 def EQ : EqualityOpcode;
396 def NE : EqualityOpcode;
398 class ComparisonOpcode : Opcode {
399 let Types = [ComparableTypeClass];
403 def LT : ComparisonOpcode;
404 def LE : ComparisonOpcode;
405 def GT : ComparisonOpcode;
406 def GE : ComparisonOpcode;
408 //===----------------------------------------------------------------------===//
410 //===----------------------------------------------------------------------===//
414 let Types = [AllTypeClass];
418 // [Value] -> [Value, Value]
420 let Types = [AllTypeClass];