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