Home | History | Annotate | Line # | Download | only in Interp
Opcodes.td revision 1.1
      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 
     18 class Type;
     19 def Bool : Type;
     20 def Sint8 : Type;
     21 def Uint8 : Type;
     22 def Sint16 : Type;
     23 def Uint16 : Type;
     24 def Sint32 : Type;
     25 def Uint32 : Type;
     26 def Sint64 : Type;
     27 def Uint64 : Type;
     28 def Ptr : Type;
     29 
     30 //===----------------------------------------------------------------------===//
     31 // Types transferred to the interpreter.
     32 //===----------------------------------------------------------------------===//
     33 
     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"; }
     44 
     45 def ArgFunction : ArgType { let Name = "Function *"; }
     46 def ArgRecord : ArgType { let Name = "Record *"; }
     47 
     48 def ArgSema : ArgType { let Name = "const fltSemantics *"; }
     49 
     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 *"; }
     58 
     59 //===----------------------------------------------------------------------===//
     60 // Classes of types intructions operate on.
     61 //===----------------------------------------------------------------------===//
     62 
     63 class TypeClass {
     64   list<Type> Types;
     65 }
     66 
     67 def AluTypeClass : TypeClass {
     68   let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
     69                Uint32, Sint64, Uint64, Bool];
     70 }
     71 
     72 def PtrTypeClass : TypeClass {
     73   let Types = [Ptr];
     74 }
     75 
     76 def AllTypeClass : TypeClass {
     77   let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types);
     78 }
     79 
     80 def ComparableTypeClass : TypeClass {
     81   let Types = !listconcat(AluTypeClass.Types, [Ptr]);
     82 }
     83 
     84 class SingletonTypeClass<Type Ty> : TypeClass {
     85   let Types = [Ty];
     86 }
     87 
     88 //===----------------------------------------------------------------------===//
     89 // Record describing all opcodes.
     90 //===----------------------------------------------------------------------===//
     91 
     92 class Opcode {
     93   list<TypeClass> Types = [];
     94   list<ArgType> Args = [];
     95   string Name = "";
     96   bit CanReturn = 0;
     97   bit ChangesPC = 0;
     98   bit HasCustomLink = 0;
     99   bit HasCustomEval = 0;
    100   bit HasGroup = 0;
    101 }
    102 
    103 class AluOpcode : Opcode {
    104   let Types = [AluTypeClass];
    105   let HasGroup = 1;
    106 }
    107 
    108 //===----------------------------------------------------------------------===//
    109 // Jump opcodes
    110 //===----------------------------------------------------------------------===//
    111 
    112 class JumpOpcode : Opcode {
    113   let Args = [ArgSint32];
    114   let ChangesPC = 1;
    115   let HasCustomEval = 1;
    116 }
    117 
    118 // [] -> []
    119 def Jmp : JumpOpcode;
    120 // [Bool] -> [], jumps if true.
    121 def Jt : JumpOpcode;
    122 // [Bool] -> [], jumps if false.
    123 def Jf : JumpOpcode;
    124 
    125 //===----------------------------------------------------------------------===//
    126 // Returns
    127 //===----------------------------------------------------------------------===//
    128 
    129 // [Value] -> []
    130 def Ret : Opcode {
    131   let Types = [AllTypeClass];
    132   let ChangesPC = 1;
    133   let CanReturn = 1;
    134   let HasGroup = 1;
    135   let HasCustomEval = 1;
    136 }
    137 // [] -> []
    138 def RetVoid : Opcode {
    139   let CanReturn = 1;
    140   let ChangesPC = 1;
    141   let HasCustomEval = 1;
    142 }
    143 // [Value] -> []
    144 def RetValue : Opcode {
    145   let CanReturn = 1;
    146   let ChangesPC = 1;
    147   let HasCustomEval = 1;
    148 }
    149 // [] -> EXIT
    150 def NoRet : Opcode {}
    151 
    152 //===----------------------------------------------------------------------===//
    153 // Frame management
    154 //===----------------------------------------------------------------------===//
    155 
    156 // [] -> []
    157 def Destroy : Opcode {
    158   let Args = [ArgUint32];
    159   let HasCustomEval = 1;
    160 }
    161 
    162 //===----------------------------------------------------------------------===//
    163 // Constants
    164 //===----------------------------------------------------------------------===//
    165 
    166 class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
    167   let Types = [SingletonTypeClass<Ty>];
    168   let Args = [ArgTy];
    169   let Name = "Const";
    170 }
    171 
    172 // [] -> [Integer]
    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>;
    182 
    183 // [] -> [Integer]
    184 def Zero : Opcode {
    185   let Types = [AluTypeClass];
    186 }
    187 
    188 // [] -> [Pointer]
    189 def Null : Opcode {
    190   let Types = [PtrTypeClass];
    191 }
    192 
    193 //===----------------------------------------------------------------------===//
    194 // Pointer generation
    195 //===----------------------------------------------------------------------===//
    196 
    197 // [] -> [Pointer]
    198 def GetPtrLocal : Opcode {
    199   // Offset of local.
    200   let Args = [ArgUint32];
    201   bit HasCustomEval = 1;
    202 }
    203 // [] -> [Pointer]
    204 def GetPtrParam : Opcode {
    205   // Offset of parameter.
    206   let Args = [ArgUint32];
    207 }
    208 // [] -> [Pointer]
    209 def GetPtrGlobal : Opcode {
    210   // Index of global.
    211   let Args = [ArgUint32];
    212 }
    213 // [Pointer] -> [Pointer]
    214 def GetPtrField : Opcode {
    215   // Offset of field.
    216   let Args = [ArgUint32];
    217 }
    218 // [Pointer] -> [Pointer]
    219 def GetPtrActiveField : Opcode {
    220   // Offset of field.
    221   let Args = [ArgUint32];
    222 }
    223 // [] -> [Pointer]
    224 def GetPtrActiveThisField : Opcode {
    225   // Offset of field.
    226   let Args = [ArgUint32];
    227 }
    228 // [] -> [Pointer]
    229 def GetPtrThisField : Opcode {
    230   // Offset of field.
    231   let Args = [ArgUint32];
    232 }
    233 // [Pointer] -> [Pointer]
    234 def GetPtrBase : Opcode {
    235   // Offset of field, which is a base.
    236   let Args = [ArgUint32];
    237 }
    238 // [Pointer] -> [Pointer]
    239 def GetPtrVirtBase : Opcode {
    240   // RecordDecl of base class.
    241   let Args = [ArgRecordDecl];
    242 }
    243 // [] -> [Pointer]
    244 def GetPtrThisBase : Opcode {
    245   // Offset of field, which is a base.
    246   let Args = [ArgUint32];
    247 }
    248 // [] -> [Pointer]
    249 def GetPtrThisVirtBase : Opcode {
    250   // RecordDecl of base class.
    251   let Args = [ArgRecordDecl];
    252 }
    253 // [] -> [Pointer]
    254 def This : Opcode;
    255 
    256 // [Pointer] -> [Pointer]
    257 def NarrowPtr : Opcode;
    258 // [Pointer] -> [Pointer]
    259 def ExpandPtr : Opcode;
    260 
    261 //===----------------------------------------------------------------------===//
    262 // Direct field accessors
    263 //===----------------------------------------------------------------------===//
    264 
    265 class AccessOpcode : Opcode {
    266   let Types = [AllTypeClass];
    267   let Args = [ArgUint32];
    268   let HasGroup = 1;
    269 }
    270 
    271 class BitFieldOpcode : Opcode {
    272   let Types = [AluTypeClass];
    273   let Args = [ArgRecordField];
    274   let HasGroup = 1;
    275 }
    276 
    277 // [] -> [Pointer]
    278 def GetLocal : AccessOpcode { let HasCustomEval = 1; }
    279 // [] -> [Pointer]
    280 def SetLocal : AccessOpcode { let HasCustomEval = 1; }
    281 
    282 // [] -> [Value]
    283 def GetGlobal : AccessOpcode;
    284 // [Value] -> []
    285 def InitGlobal : AccessOpcode;
    286 // [Value] -> []
    287 def SetGlobal : AccessOpcode;
    288 
    289 // [] -> [Value]
    290 def GetParam : AccessOpcode;
    291 // [Value] -> []
    292 def SetParam : AccessOpcode;
    293 
    294 // [Pointer] -> [Pointer, Value]
    295 def GetField : AccessOpcode;
    296 // [Pointer] -> [Value]
    297 def GetFieldPop : AccessOpcode;
    298 // [] -> [Value]
    299 def GetThisField : AccessOpcode;
    300 
    301 // [Pointer, Value] -> [Pointer]
    302 def SetField : AccessOpcode;
    303 // [Value] -> []
    304 def SetThisField : AccessOpcode;
    305 
    306 // [Value] -> []
    307 def InitThisField : AccessOpcode;
    308 // [Value] -> []
    309 def InitThisFieldActive : AccessOpcode;
    310 // [Value] -> []
    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;
    318 
    319 //===----------------------------------------------------------------------===//
    320 // Pointer access
    321 //===----------------------------------------------------------------------===//
    322 
    323 class LoadOpcode : Opcode {
    324   let Types = [AllTypeClass];
    325   let HasGroup = 1;
    326 }
    327 
    328 // [Pointer] -> [Pointer, Value]
    329 def Load : LoadOpcode {}
    330 // [Pointer] -> [Value]
    331 def LoadPop : LoadOpcode {}
    332 
    333 class StoreOpcode : Opcode {
    334   let Types = [AllTypeClass];
    335   let HasGroup = 1;
    336 }
    337 
    338 class StoreBitFieldOpcode : Opcode {
    339   let Types = [AluTypeClass];
    340   let HasGroup = 1;
    341 }
    342 
    343 // [Pointer, Value] -> [Pointer]
    344 def Store : StoreOpcode {}
    345 // [Pointer, Value] -> []
    346 def StorePop : StoreOpcode {}
    347 
    348 // [Pointer, Value] -> [Pointer]
    349 def StoreBitField : StoreBitFieldOpcode {}
    350 // [Pointer, Value] -> []
    351 def StoreBitFieldPop : StoreBitFieldOpcode {}
    352 
    353 // [Pointer, Value] -> []
    354 def InitPop : StoreOpcode {}
    355 // [Pointer, Value] -> [Pointer]
    356 def InitElem : Opcode {
    357   let Types = [AllTypeClass];
    358   let Args = [ArgUint32];
    359   let HasGroup = 1;
    360 }
    361 // [Pointer, Value] -> []
    362 def InitElemPop : Opcode {
    363   let Types = [AllTypeClass];
    364   let Args = [ArgUint32];
    365   let HasGroup = 1;
    366 }
    367 
    368 //===----------------------------------------------------------------------===//
    369 // Pointer arithmetic.
    370 //===----------------------------------------------------------------------===//
    371 
    372 // [Pointer, Integral] -> [Pointer]
    373 def AddOffset : AluOpcode;
    374 // [Pointer, Integral] -> [Pointer]
    375 def SubOffset : AluOpcode;
    376 
    377 //===----------------------------------------------------------------------===//
    378 // Binary operators.
    379 //===----------------------------------------------------------------------===//
    380 
    381 // [Real, Real] -> [Real]
    382 def Sub : AluOpcode;
    383 def Add : AluOpcode;
    384 def Mul : AluOpcode;
    385 
    386 //===----------------------------------------------------------------------===//
    387 // Comparison opcodes.
    388 //===----------------------------------------------------------------------===//
    389 
    390 class EqualityOpcode : Opcode {
    391   let Types = [AllTypeClass];
    392   let HasGroup = 1;
    393 }
    394 
    395 def EQ : EqualityOpcode;
    396 def NE : EqualityOpcode;
    397 
    398 class ComparisonOpcode : Opcode {
    399   let Types = [ComparableTypeClass];
    400   let HasGroup = 1;
    401 }
    402 
    403 def LT : ComparisonOpcode;
    404 def LE : ComparisonOpcode;
    405 def GT : ComparisonOpcode;
    406 def GE : ComparisonOpcode;
    407 
    408 //===----------------------------------------------------------------------===//
    409 // Stack management.
    410 //===----------------------------------------------------------------------===//
    411 
    412 // [Value] -> []
    413 def Pop : Opcode {
    414   let Types = [AllTypeClass];
    415   let HasGroup = 1;
    416 }
    417 
    418 // [Value] -> [Value, Value]
    419 def Dup : Opcode {
    420   let Types = [AllTypeClass];
    421   let HasGroup = 1;
    422 }
    423