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 //===----------------------------------------------------------------------===//
34 //===----------------------------------------------------------------------===//
35 // Types transferred to the interpreter.
36 //===----------------------------------------------------------------------===//
38 class ArgType { string Name = ?; }
39 def ArgSint8 : ArgType { let Name = "int8_t"; }
40 def ArgUint8 : ArgType { let Name = "uint8_t"; }
41 def ArgSint16 : ArgType { let Name = "int16_t"; }
42 def ArgUint16 : ArgType { let Name = "uint16_t"; }
43 def ArgSint32 : ArgType { let Name = "int32_t"; }
44 def ArgUint32 : ArgType { let Name = "uint32_t"; }
45 def ArgSint64 : ArgType { let Name = "int64_t"; }
46 def ArgUint64 : ArgType { let Name = "uint64_t"; }
47 def ArgFloat : ArgType { let Name = "Floating"; }
48 def ArgBool : ArgType { let Name = "bool"; }
50 def ArgFunction : ArgType { let Name = "const Function *"; }
51 def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; }
52 def ArgRecordField : ArgType { let Name = "const Record::Field *"; }
53 def ArgFltSemantics : ArgType { let Name = "const llvm::fltSemantics *"; }
54 def ArgRoundingMode : ArgType { let Name = "llvm::RoundingMode"; }
55 def ArgLETD: ArgType { let Name = "const LifetimeExtendedTemporaryDecl *"; }
56 def ArgCastKind : ArgType { let Name = "CastKind"; }
57 def ArgCallExpr : ArgType { let Name = "const CallExpr *"; }
58 def ArgOffsetOfExpr : ArgType { let Name = "const OffsetOfExpr *"; }
59 def ArgDeclRef : ArgType { let Name = "const DeclRefExpr *"; }
60 def ArgCCI : ArgType { let Name = "const ComparisonCategoryInfo *"; }
62 //===----------------------------------------------------------------------===//
63 // Classes of types instructions operate on.
64 //===----------------------------------------------------------------------===//
70 def IntegerTypeClass : TypeClass {
71 let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
72 Uint32, Sint64, Uint64, IntAP, IntAPS];
75 def FixedSizeIntegralTypeClass : TypeClass {
76 let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
77 Uint32, Sint64, Uint64, Bool];
80 def NumberTypeClass : TypeClass {
81 let Types = !listconcat(IntegerTypeClass.Types, [Float]);
84 def FloatTypeClass : TypeClass {
88 def AluTypeClass : TypeClass {
89 let Types = !listconcat(IntegerTypeClass.Types, [Bool]);
92 def PtrTypeClass : TypeClass {
93 let Types = [Ptr, FnPtr];
96 def BoolTypeClass : TypeClass {
100 def NonPtrTypeClass : TypeClass {
101 let Types = !listconcat(IntegerTypeClass.Types, [Bool], [Float]);
104 def AllTypeClass : TypeClass {
105 let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types, FloatTypeClass.Types);
108 def ComparableTypeClass : TypeClass {
109 let Types = !listconcat(AluTypeClass.Types, [Ptr], [Float], [FnPtr]);
112 class SingletonTypeClass<Type Ty> : TypeClass {
116 //===----------------------------------------------------------------------===//
117 // Record describing all opcodes.
118 //===----------------------------------------------------------------------===//
121 list<TypeClass> Types = [];
122 list<ArgType> Args = [];
126 bit HasCustomLink = 0;
127 bit HasCustomEval = 0;
131 class AluOpcode : Opcode {
132 let Types = [AluTypeClass];
136 class FloatOpcode : Opcode {
138 let Args = [ArgRoundingMode];
141 class IntegerOpcode : Opcode {
142 let Types = [IntegerTypeClass];
146 //===----------------------------------------------------------------------===//
148 //===----------------------------------------------------------------------===//
150 class JumpOpcode : Opcode {
151 let Args = [ArgSint32];
153 let HasCustomEval = 1;
157 def Jmp : JumpOpcode;
158 // [Bool] -> [], jumps if true.
160 // [Bool] -> [], jumps if false.
163 //===----------------------------------------------------------------------===//
165 //===----------------------------------------------------------------------===//
169 let Types = [AllTypeClass];
173 let HasCustomEval = 1;
176 def RetVoid : Opcode {
179 let HasCustomEval = 1;
182 def RetValue : Opcode {
185 let HasCustomEval = 1;
188 def NoRet : Opcode {}
192 let Args = [ArgFunction];
196 def CallVirt : Opcode {
197 let Args = [ArgFunction];
201 def CallBI : Opcode {
202 let Args = [ArgFunction, ArgCallExpr];
206 def CallPtr : Opcode {
211 def OffsetOf : Opcode {
212 let Types = [IntegerTypeClass];
213 let Args = [ArgOffsetOfExpr];
217 //===----------------------------------------------------------------------===//
219 //===----------------------------------------------------------------------===//
222 def Destroy : Opcode {
223 let Args = [ArgUint32];
224 let HasCustomEval = 1;
227 //===----------------------------------------------------------------------===//
229 //===----------------------------------------------------------------------===//
231 class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
232 let Types = [SingletonTypeClass<Ty>];
238 def ConstSint8 : ConstOpcode<Sint8, ArgSint8>;
239 def ConstUint8 : ConstOpcode<Uint8, ArgUint8>;
240 def ConstSint16 : ConstOpcode<Sint16, ArgSint16>;
241 def ConstUint16 : ConstOpcode<Uint16, ArgUint16>;
242 def ConstSint32 : ConstOpcode<Sint32, ArgSint32>;
243 def ConstUint32 : ConstOpcode<Uint32, ArgUint32>;
244 def ConstSint64 : ConstOpcode<Sint64, ArgSint64>;
245 def ConstUint64 : ConstOpcode<Uint64, ArgUint64>;
246 def ConstFloat : ConstOpcode<Float, ArgFloat>;
247 def ConstBool : ConstOpcode<Bool, ArgBool>;
251 let Types = [FixedSizeIntegralTypeClass];
255 def ZeroIntAP : Opcode {
256 let Args = [ArgUint32];
259 def ZeroIntAPS : Opcode {
260 let Args = [ArgUint32];
265 let Types = [PtrTypeClass];
269 //===----------------------------------------------------------------------===//
270 // Pointer generation
271 //===----------------------------------------------------------------------===//
274 def GetPtrLocal : Opcode {
276 let Args = [ArgUint32];
277 bit HasCustomEval = 1;
280 def GetPtrParam : Opcode {
281 // Offset of parameter.
282 let Args = [ArgUint32];
285 def GetPtrGlobal : Opcode {
287 let Args = [ArgUint32];
289 // [Pointer] -> [Pointer]
290 def GetPtrField : Opcode {
292 let Args = [ArgUint32];
294 // [Pointer] -> [Pointer]
295 def GetPtrActiveField : Opcode {
297 let Args = [ArgUint32];
300 def GetPtrActiveThisField : Opcode {
302 let Args = [ArgUint32];
305 def GetPtrThisField : Opcode {
307 let Args = [ArgUint32];
309 // [Pointer] -> [Pointer]
310 def GetPtrBase : Opcode {
311 // Offset of field, which is a base.
312 let Args = [ArgUint32];
314 // [Pointer] -> [Pointer]
315 def GetPtrBasePop : Opcode {
316 // Offset of field, which is a base.
317 let Args = [ArgUint32];
320 def InitPtrPop : Opcode {
324 def GetPtrDerivedPop : Opcode {
325 let Args = [ArgUint32];
328 // [Pointer] -> [Pointer]
329 def GetPtrVirtBase : Opcode {
330 // RecordDecl of base class.
331 let Args = [ArgRecordDecl];
334 def GetPtrThisBase : Opcode {
335 // Offset of field, which is a base.
336 let Args = [ArgUint32];
339 def GetPtrThisVirtBase : Opcode {
340 // RecordDecl of base class.
341 let Args = [ArgRecordDecl];
349 // [Pointer] -> [Pointer]
350 def NarrowPtr : Opcode;
351 // [Pointer] -> [Pointer]
352 def ExpandPtr : Opcode;
353 // [Pointer, Offset] -> [Pointer]
354 def ArrayElemPtr : AluOpcode;
355 def ArrayElemPtrPop : AluOpcode;
357 //===----------------------------------------------------------------------===//
358 // Direct field accessors
359 //===----------------------------------------------------------------------===//
361 class AccessOpcode : Opcode {
362 let Types = [AllTypeClass];
363 let Args = [ArgUint32];
367 class BitFieldOpcode : Opcode {
368 let Types = [AluTypeClass];
369 let Args = [ArgRecordField];
374 def GetLocal : AccessOpcode { let HasCustomEval = 1; }
376 def SetLocal : AccessOpcode { let HasCustomEval = 1; }
378 def CheckGlobalCtor : Opcode {}
381 def GetGlobal : AccessOpcode;
383 def InitGlobal : AccessOpcode;
385 def InitGlobalTemp : AccessOpcode {
386 let Args = [ArgUint32, ArgLETD];
388 // [Pointer] -> [Pointer]
389 def InitGlobalTempComp : Opcode {
390 let Args = [ArgLETD];
395 def SetGlobal : AccessOpcode;
398 def GetParam : AccessOpcode;
400 def SetParam : AccessOpcode;
402 // [Pointer] -> [Pointer, Value]
403 def GetField : AccessOpcode;
404 // [Pointer] -> [Value]
405 def GetFieldPop : AccessOpcode;
407 def GetThisField : AccessOpcode;
409 // [Pointer, Value] -> [Pointer]
410 def SetField : AccessOpcode;
412 def SetThisField : AccessOpcode;
415 def InitThisField : AccessOpcode;
417 def InitThisFieldActive : AccessOpcode;
419 def InitThisBitField : BitFieldOpcode;
420 // [Pointer, Value] -> []
421 def InitField : AccessOpcode;
422 // [Pointer, Value] -> []
423 def InitBitField : BitFieldOpcode;
424 // [Pointer, Value] -> []
425 def InitFieldActive : AccessOpcode;
427 //===----------------------------------------------------------------------===//
429 //===----------------------------------------------------------------------===//
431 class LoadOpcode : Opcode {
432 let Types = [AllTypeClass];
436 // [Pointer] -> [Pointer, Value]
437 def Load : LoadOpcode {}
438 // [Pointer] -> [Value]
439 def LoadPop : LoadOpcode {}
441 class StoreOpcode : Opcode {
442 let Types = [AllTypeClass];
446 class StoreBitFieldOpcode : Opcode {
447 let Types = [AluTypeClass];
451 // [Pointer, Value] -> [Pointer]
452 def Store : StoreOpcode {}
453 // [Pointer, Value] -> []
454 def StorePop : StoreOpcode {}
456 // [Pointer, Value] -> [Pointer]
457 def StoreBitField : StoreBitFieldOpcode {}
458 // [Pointer, Value] -> []
459 def StoreBitFieldPop : StoreBitFieldOpcode {}
461 // [Pointer, Value] -> []
462 def InitPop : StoreOpcode {}
463 // [Pointer, Value] -> [Pointer]
464 def InitElem : Opcode {
465 let Types = [AllTypeClass];
466 let Args = [ArgUint32];
469 // [Pointer, Value] -> []
470 def InitElemPop : Opcode {
471 let Types = [AllTypeClass];
472 let Args = [ArgUint32];
476 //===----------------------------------------------------------------------===//
477 // Pointer arithmetic.
478 //===----------------------------------------------------------------------===//
480 // [Pointer, Integral] -> [Pointer]
481 def AddOffset : AluOpcode;
482 // [Pointer, Integral] -> [Pointer]
483 def SubOffset : AluOpcode;
485 // [Pointer, Pointer] -> [Integral]
486 def SubPtr : Opcode {
487 let Types = [IntegerTypeClass];
491 // [Pointer] -> [Pointer]
492 def IncPtr : Opcode {
495 // [Pointer] -> [Pointer]
496 def DecPtr : Opcode {
500 //===----------------------------------------------------------------------===//
501 // Function pointers.
502 //===----------------------------------------------------------------------===//
503 def GetFnPtr : Opcode {
504 let Args = [ArgFunction];
508 //===----------------------------------------------------------------------===//
510 //===----------------------------------------------------------------------===//
512 // [Real, Real] -> [Real]
514 def Addf : FloatOpcode;
516 def Subf : FloatOpcode;
518 def Mulf : FloatOpcode;
519 def Rem : IntegerOpcode;
520 def Div : IntegerOpcode;
521 def Divf : FloatOpcode;
523 def BitAnd : IntegerOpcode;
524 def BitOr : IntegerOpcode;
525 def BitXor : IntegerOpcode;
528 let Types = [IntegerTypeClass, IntegerTypeClass];
533 let Types = [IntegerTypeClass, IntegerTypeClass];
537 //===----------------------------------------------------------------------===//
539 //===----------------------------------------------------------------------===//
543 let Types = [BoolTypeClass];
547 // Increment and decrement.
548 def Inc: IntegerOpcode;
549 def IncPop : IntegerOpcode;
550 def Dec: IntegerOpcode;
551 def DecPop: IntegerOpcode;
553 // Float increment and decrement.
554 def Incf: FloatOpcode;
555 def IncfPop : FloatOpcode;
556 def Decf: FloatOpcode;
557 def DecfPop : FloatOpcode;
561 let Types = [NonPtrTypeClass];
567 let Types = [IntegerTypeClass];
571 //===----------------------------------------------------------------------===//
573 //===----------------------------------------------------------------------===//
575 def FromCastTypeClass : TypeClass {
576 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool, IntAP, IntAPS];
579 def ToCastTypeClass : TypeClass {
580 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
584 let Types = [FromCastTypeClass, ToCastTypeClass];
588 def CastFP : Opcode {
590 let Args = [ArgFltSemantics, ArgRoundingMode];
593 def FixedSizeIntegralTypes : TypeClass {
594 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
597 def CastAP : Opcode {
598 let Types = [AluTypeClass];
599 let Args = [ArgUint32];
603 def CastAPS : Opcode {
604 let Types = [AluTypeClass];
605 let Args = [ArgUint32];
609 // Cast an integer to a floating type
610 def CastIntegralFloating : Opcode {
611 let Types = [AluTypeClass];
612 let Args = [ArgFltSemantics, ArgRoundingMode];
616 // Cast a floating to an integer type
617 def CastFloatingIntegral : Opcode {
618 let Types = [FixedSizeIntegralTypes];
623 def CastFloatingIntegralAP : Opcode {
625 let Args = [ArgUint32];
628 def CastFloatingIntegralAPS : Opcode {
630 let Args = [ArgUint32];
633 def CastPointerIntegral : Opcode {
634 let Types = [AluTypeClass];
639 //===----------------------------------------------------------------------===//
640 // Comparison opcodes.
641 //===----------------------------------------------------------------------===//
643 class EqualityOpcode : Opcode {
644 let Types = [AllTypeClass];
648 def EQ : EqualityOpcode;
649 def NE : EqualityOpcode;
651 class ComparisonOpcode : Opcode {
652 let Types = [ComparableTypeClass];
656 def CMP3 : ComparisonOpcode {
660 def LT : ComparisonOpcode;
661 def LE : ComparisonOpcode;
662 def GT : ComparisonOpcode;
663 def GE : ComparisonOpcode;
665 //===----------------------------------------------------------------------===//
667 //===----------------------------------------------------------------------===//
671 let Types = [AllTypeClass];
675 // [Value] -> [Value, Value]
677 let Types = [AllTypeClass];
682 def Invalid : Opcode {}
683 def InvalidCast : Opcode {
684 let Args = [ArgCastKind];
687 def InvalidDeclRef : Opcode {
688 let Args = [ArgDeclRef];
691 def ArrayDecay : Opcode;