1353942Sdim//===--- Opcodes.td - Opcode defitions for the constexpr VM -----*- C++ -*-===// 2353942Sdim// 3353942Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353942Sdim// See https://llvm.org/LICENSE.txt for license information. 5353942Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353942Sdim// 7353942Sdim//===----------------------------------------------------------------------===// 8353942Sdim// 9353942Sdim// Helper file used to generate opcodes, the interpreter and the disassembler. 10353942Sdim// 11353942Sdim//===----------------------------------------------------------------------===// 12353942Sdim 13353942Sdim 14353942Sdim//===----------------------------------------------------------------------===// 15353942Sdim// Types evaluated by the interpreter. 16353942Sdim//===----------------------------------------------------------------------===// 17353942Sdim 18353942Sdimclass Type; 19353942Sdimdef Bool : Type; 20353942Sdimdef Sint8 : Type; 21353942Sdimdef Uint8 : Type; 22353942Sdimdef Sint16 : Type; 23353942Sdimdef Uint16 : Type; 24353942Sdimdef Sint32 : Type; 25353942Sdimdef Uint32 : Type; 26353942Sdimdef Sint64 : Type; 27353942Sdimdef Uint64 : Type; 28353942Sdimdef Ptr : Type; 29353942Sdim 30353942Sdim//===----------------------------------------------------------------------===// 31353942Sdim// Types transferred to the interpreter. 32353942Sdim//===----------------------------------------------------------------------===// 33353942Sdim 34353942Sdimclass ArgType { string Name = ?; } 35353942Sdimdef ArgSint8 : ArgType { let Name = "int8_t"; } 36353942Sdimdef ArgUint8 : ArgType { let Name = "uint8_t"; } 37353942Sdimdef ArgSint16 : ArgType { let Name = "int16_t"; } 38353942Sdimdef ArgUint16 : ArgType { let Name = "uint16_t"; } 39353942Sdimdef ArgSint32 : ArgType { let Name = "int32_t"; } 40353942Sdimdef ArgUint32 : ArgType { let Name = "uint32_t"; } 41353942Sdimdef ArgSint64 : ArgType { let Name = "int64_t"; } 42353942Sdimdef ArgUint64 : ArgType { let Name = "uint64_t"; } 43353942Sdimdef ArgBool : ArgType { let Name = "bool"; } 44353942Sdim 45353942Sdimdef ArgFunction : ArgType { let Name = "Function *"; } 46353942Sdimdef ArgRecord : ArgType { let Name = "Record *"; } 47353942Sdim 48353942Sdimdef ArgSema : ArgType { let Name = "const fltSemantics *"; } 49353942Sdim 50353942Sdimdef ArgExpr : ArgType { let Name = "const Expr *"; } 51353942Sdimdef ArgFloatingLiteral : ArgType { let Name = "const FloatingLiteral *"; } 52353942Sdimdef ArgCXXMethodDecl : ArgType { let Name = "const CXXMethodDecl *"; } 53353942Sdimdef ArgFunctionDecl : ArgType { let Name = "const FunctionDecl *"; } 54353942Sdimdef ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; } 55353942Sdimdef ArgCXXRecordDecl : ArgType { let Name = "const CXXRecordDecl *"; } 56353942Sdimdef ArgValueDecl : ArgType { let Name = "const ValueDecl *"; } 57353942Sdimdef ArgRecordField : ArgType { let Name = "const Record::Field *"; } 58353942Sdim 59353942Sdim//===----------------------------------------------------------------------===// 60353942Sdim// Classes of types intructions operate on. 61353942Sdim//===----------------------------------------------------------------------===// 62353942Sdim 63353942Sdimclass TypeClass { 64353942Sdim list<Type> Types; 65353942Sdim} 66353942Sdim 67353942Sdimdef AluTypeClass : TypeClass { 68353942Sdim let Types = [Sint8, Uint8, Sint16, Uint16, Sint32, 69353942Sdim Uint32, Sint64, Uint64, Bool]; 70353942Sdim} 71353942Sdim 72353942Sdimdef PtrTypeClass : TypeClass { 73353942Sdim let Types = [Ptr]; 74353942Sdim} 75353942Sdim 76353942Sdimdef AllTypeClass : TypeClass { 77353942Sdim let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types); 78353942Sdim} 79353942Sdim 80353942Sdimdef ComparableTypeClass : TypeClass { 81353942Sdim let Types = !listconcat(AluTypeClass.Types, [Ptr]); 82353942Sdim} 83353942Sdim 84353942Sdimclass SingletonTypeClass<Type Ty> : TypeClass { 85353942Sdim let Types = [Ty]; 86353942Sdim} 87353942Sdim 88353942Sdim//===----------------------------------------------------------------------===// 89353942Sdim// Record describing all opcodes. 90353942Sdim//===----------------------------------------------------------------------===// 91353942Sdim 92353942Sdimclass Opcode { 93353942Sdim list<TypeClass> Types = []; 94353942Sdim list<ArgType> Args = []; 95353942Sdim string Name = ""; 96353942Sdim bit CanReturn = 0; 97353942Sdim bit ChangesPC = 0; 98353942Sdim bit HasCustomLink = 0; 99353942Sdim bit HasCustomEval = 0; 100353942Sdim bit HasGroup = 0; 101353942Sdim} 102353942Sdim 103353942Sdimclass AluOpcode : Opcode { 104353942Sdim let Types = [AluTypeClass]; 105353942Sdim let HasGroup = 1; 106353942Sdim} 107353942Sdim 108353942Sdim//===----------------------------------------------------------------------===// 109353942Sdim// Jump opcodes 110353942Sdim//===----------------------------------------------------------------------===// 111353942Sdim 112353942Sdimclass JumpOpcode : Opcode { 113353942Sdim let Args = [ArgSint32]; 114353942Sdim let ChangesPC = 1; 115353942Sdim let HasCustomEval = 1; 116353942Sdim} 117353942Sdim 118353942Sdim// [] -> [] 119353942Sdimdef Jmp : JumpOpcode; 120353942Sdim// [Bool] -> [], jumps if true. 121353942Sdimdef Jt : JumpOpcode; 122353942Sdim// [Bool] -> [], jumps if false. 123353942Sdimdef Jf : JumpOpcode; 124353942Sdim 125353942Sdim//===----------------------------------------------------------------------===// 126353942Sdim// Returns 127353942Sdim//===----------------------------------------------------------------------===// 128353942Sdim 129353942Sdim// [Value] -> [] 130353942Sdimdef Ret : Opcode { 131353942Sdim let Types = [AllTypeClass]; 132353942Sdim let ChangesPC = 1; 133353942Sdim let CanReturn = 1; 134353942Sdim let HasGroup = 1; 135353942Sdim let HasCustomEval = 1; 136353942Sdim} 137353942Sdim// [] -> [] 138353942Sdimdef RetVoid : Opcode { 139353942Sdim let CanReturn = 1; 140353942Sdim let ChangesPC = 1; 141353942Sdim let HasCustomEval = 1; 142353942Sdim} 143353942Sdim// [Value] -> [] 144353942Sdimdef RetValue : Opcode { 145353942Sdim let CanReturn = 1; 146353942Sdim let ChangesPC = 1; 147353942Sdim let HasCustomEval = 1; 148353942Sdim} 149353942Sdim// [] -> EXIT 150353942Sdimdef NoRet : Opcode {} 151353942Sdim 152353942Sdim//===----------------------------------------------------------------------===// 153353942Sdim// Frame management 154353942Sdim//===----------------------------------------------------------------------===// 155353942Sdim 156353942Sdim// [] -> [] 157353942Sdimdef Destroy : Opcode { 158353942Sdim let Args = [ArgUint32]; 159353942Sdim let HasCustomEval = 1; 160353942Sdim} 161353942Sdim 162353942Sdim//===----------------------------------------------------------------------===// 163353942Sdim// Constants 164353942Sdim//===----------------------------------------------------------------------===// 165353942Sdim 166353942Sdimclass ConstOpcode<Type Ty, ArgType ArgTy> : Opcode { 167353942Sdim let Types = [SingletonTypeClass<Ty>]; 168353942Sdim let Args = [ArgTy]; 169353942Sdim let Name = "Const"; 170353942Sdim} 171353942Sdim 172353942Sdim// [] -> [Integer] 173353942Sdimdef ConstSint8 : ConstOpcode<Sint8, ArgSint8>; 174353942Sdimdef ConstUint8 : ConstOpcode<Uint8, ArgUint8>; 175353942Sdimdef ConstSint16 : ConstOpcode<Sint16, ArgSint16>; 176353942Sdimdef ConstUint16 : ConstOpcode<Uint16, ArgUint16>; 177353942Sdimdef ConstSint32 : ConstOpcode<Sint32, ArgSint32>; 178353942Sdimdef ConstUint32 : ConstOpcode<Uint32, ArgUint32>; 179353942Sdimdef ConstSint64 : ConstOpcode<Sint64, ArgSint64>; 180353942Sdimdef ConstUint64 : ConstOpcode<Uint64, ArgUint64>; 181353942Sdimdef ConstBool : ConstOpcode<Bool, ArgBool>; 182353942Sdim 183353942Sdim// [] -> [Integer] 184353942Sdimdef Zero : Opcode { 185353942Sdim let Types = [AluTypeClass]; 186353942Sdim} 187353942Sdim 188353942Sdim// [] -> [Pointer] 189353942Sdimdef Null : Opcode { 190353942Sdim let Types = [PtrTypeClass]; 191353942Sdim} 192353942Sdim 193353942Sdim//===----------------------------------------------------------------------===// 194353942Sdim// Pointer generation 195353942Sdim//===----------------------------------------------------------------------===// 196353942Sdim 197353942Sdim// [] -> [Pointer] 198353942Sdimdef GetPtrLocal : Opcode { 199353942Sdim // Offset of local. 200353942Sdim let Args = [ArgUint32]; 201353942Sdim bit HasCustomEval = 1; 202353942Sdim} 203353942Sdim// [] -> [Pointer] 204353942Sdimdef GetPtrParam : Opcode { 205353942Sdim // Offset of parameter. 206353942Sdim let Args = [ArgUint32]; 207353942Sdim} 208353942Sdim// [] -> [Pointer] 209353942Sdimdef GetPtrGlobal : Opcode { 210353942Sdim // Index of global. 211353942Sdim let Args = [ArgUint32]; 212353942Sdim} 213353942Sdim// [Pointer] -> [Pointer] 214353942Sdimdef GetPtrField : Opcode { 215353942Sdim // Offset of field. 216353942Sdim let Args = [ArgUint32]; 217353942Sdim} 218353942Sdim// [Pointer] -> [Pointer] 219353942Sdimdef GetPtrActiveField : Opcode { 220353942Sdim // Offset of field. 221353942Sdim let Args = [ArgUint32]; 222353942Sdim} 223353942Sdim// [] -> [Pointer] 224353942Sdimdef GetPtrActiveThisField : Opcode { 225353942Sdim // Offset of field. 226353942Sdim let Args = [ArgUint32]; 227353942Sdim} 228353942Sdim// [] -> [Pointer] 229353942Sdimdef GetPtrThisField : Opcode { 230353942Sdim // Offset of field. 231353942Sdim let Args = [ArgUint32]; 232353942Sdim} 233353942Sdim// [Pointer] -> [Pointer] 234353942Sdimdef GetPtrBase : Opcode { 235353942Sdim // Offset of field, which is a base. 236353942Sdim let Args = [ArgUint32]; 237353942Sdim} 238353942Sdim// [Pointer] -> [Pointer] 239353942Sdimdef GetPtrVirtBase : Opcode { 240353942Sdim // RecordDecl of base class. 241353942Sdim let Args = [ArgRecordDecl]; 242353942Sdim} 243353942Sdim// [] -> [Pointer] 244353942Sdimdef GetPtrThisBase : Opcode { 245353942Sdim // Offset of field, which is a base. 246353942Sdim let Args = [ArgUint32]; 247353942Sdim} 248353942Sdim// [] -> [Pointer] 249353942Sdimdef GetPtrThisVirtBase : Opcode { 250353942Sdim // RecordDecl of base class. 251353942Sdim let Args = [ArgRecordDecl]; 252353942Sdim} 253353942Sdim// [] -> [Pointer] 254353942Sdimdef This : Opcode; 255353942Sdim 256353942Sdim// [Pointer] -> [Pointer] 257353942Sdimdef NarrowPtr : Opcode; 258353942Sdim// [Pointer] -> [Pointer] 259353942Sdimdef ExpandPtr : Opcode; 260353942Sdim 261353942Sdim//===----------------------------------------------------------------------===// 262353942Sdim// Direct field accessors 263353942Sdim//===----------------------------------------------------------------------===// 264353942Sdim 265353942Sdimclass AccessOpcode : Opcode { 266353942Sdim let Types = [AllTypeClass]; 267353942Sdim let Args = [ArgUint32]; 268353942Sdim let HasGroup = 1; 269353942Sdim} 270353942Sdim 271353942Sdimclass BitFieldOpcode : Opcode { 272353942Sdim let Types = [AluTypeClass]; 273353942Sdim let Args = [ArgRecordField]; 274353942Sdim let HasGroup = 1; 275353942Sdim} 276353942Sdim 277353942Sdim// [] -> [Pointer] 278353942Sdimdef GetLocal : AccessOpcode { let HasCustomEval = 1; } 279353942Sdim// [] -> [Pointer] 280353942Sdimdef SetLocal : AccessOpcode { let HasCustomEval = 1; } 281353942Sdim 282353942Sdim// [] -> [Value] 283353942Sdimdef GetGlobal : AccessOpcode; 284353942Sdim// [Value] -> [] 285353942Sdimdef InitGlobal : AccessOpcode; 286353942Sdim// [Value] -> [] 287353942Sdimdef SetGlobal : AccessOpcode; 288353942Sdim 289353942Sdim// [] -> [Value] 290353942Sdimdef GetParam : AccessOpcode; 291353942Sdim// [Value] -> [] 292353942Sdimdef SetParam : AccessOpcode; 293353942Sdim 294353942Sdim// [Pointer] -> [Pointer, Value] 295353942Sdimdef GetField : AccessOpcode; 296353942Sdim// [Pointer] -> [Value] 297353942Sdimdef GetFieldPop : AccessOpcode; 298353942Sdim// [] -> [Value] 299353942Sdimdef GetThisField : AccessOpcode; 300353942Sdim 301353942Sdim// [Pointer, Value] -> [Pointer] 302353942Sdimdef SetField : AccessOpcode; 303353942Sdim// [Value] -> [] 304353942Sdimdef SetThisField : AccessOpcode; 305353942Sdim 306353942Sdim// [Value] -> [] 307353942Sdimdef InitThisField : AccessOpcode; 308353942Sdim// [Value] -> [] 309353942Sdimdef InitThisFieldActive : AccessOpcode; 310353942Sdim// [Value] -> [] 311353942Sdimdef InitThisBitField : BitFieldOpcode; 312353942Sdim// [Pointer, Value] -> [] 313353942Sdimdef InitField : AccessOpcode; 314353942Sdim// [Pointer, Value] -> [] 315353942Sdimdef InitBitField : BitFieldOpcode; 316353942Sdim// [Pointer, Value] -> [] 317353942Sdimdef InitFieldActive : AccessOpcode; 318353942Sdim 319353942Sdim//===----------------------------------------------------------------------===// 320353942Sdim// Pointer access 321353942Sdim//===----------------------------------------------------------------------===// 322353942Sdim 323353942Sdimclass LoadOpcode : Opcode { 324353942Sdim let Types = [AllTypeClass]; 325353942Sdim let HasGroup = 1; 326353942Sdim} 327353942Sdim 328353942Sdim// [Pointer] -> [Pointer, Value] 329353942Sdimdef Load : LoadOpcode {} 330353942Sdim// [Pointer] -> [Value] 331353942Sdimdef LoadPop : LoadOpcode {} 332353942Sdim 333353942Sdimclass StoreOpcode : Opcode { 334353942Sdim let Types = [AllTypeClass]; 335353942Sdim let HasGroup = 1; 336353942Sdim} 337353942Sdim 338353942Sdimclass StoreBitFieldOpcode : Opcode { 339353942Sdim let Types = [AluTypeClass]; 340353942Sdim let HasGroup = 1; 341353942Sdim} 342353942Sdim 343353942Sdim// [Pointer, Value] -> [Pointer] 344353942Sdimdef Store : StoreOpcode {} 345353942Sdim// [Pointer, Value] -> [] 346353942Sdimdef StorePop : StoreOpcode {} 347353942Sdim 348353942Sdim// [Pointer, Value] -> [Pointer] 349353942Sdimdef StoreBitField : StoreBitFieldOpcode {} 350353942Sdim// [Pointer, Value] -> [] 351353942Sdimdef StoreBitFieldPop : StoreBitFieldOpcode {} 352353942Sdim 353353942Sdim// [Pointer, Value] -> [] 354353942Sdimdef InitPop : StoreOpcode {} 355353942Sdim// [Pointer, Value] -> [Pointer] 356353942Sdimdef InitElem : Opcode { 357353942Sdim let Types = [AllTypeClass]; 358353942Sdim let Args = [ArgUint32]; 359353942Sdim let HasGroup = 1; 360353942Sdim} 361353942Sdim// [Pointer, Value] -> [] 362353942Sdimdef InitElemPop : Opcode { 363353942Sdim let Types = [AllTypeClass]; 364353942Sdim let Args = [ArgUint32]; 365353942Sdim let HasGroup = 1; 366353942Sdim} 367353942Sdim 368353942Sdim//===----------------------------------------------------------------------===// 369353942Sdim// Pointer arithmetic. 370353942Sdim//===----------------------------------------------------------------------===// 371353942Sdim 372353942Sdim// [Pointer, Integral] -> [Pointer] 373353942Sdimdef AddOffset : AluOpcode; 374353942Sdim// [Pointer, Integral] -> [Pointer] 375353942Sdimdef SubOffset : AluOpcode; 376353942Sdim 377353942Sdim//===----------------------------------------------------------------------===// 378353942Sdim// Binary operators. 379353942Sdim//===----------------------------------------------------------------------===// 380353942Sdim 381353942Sdim// [Real, Real] -> [Real] 382353942Sdimdef Sub : AluOpcode; 383353942Sdimdef Add : AluOpcode; 384353942Sdimdef Mul : AluOpcode; 385353942Sdim 386353942Sdim//===----------------------------------------------------------------------===// 387353942Sdim// Comparison opcodes. 388353942Sdim//===----------------------------------------------------------------------===// 389353942Sdim 390353942Sdimclass EqualityOpcode : Opcode { 391353942Sdim let Types = [AllTypeClass]; 392353942Sdim let HasGroup = 1; 393353942Sdim} 394353942Sdim 395353942Sdimdef EQ : EqualityOpcode; 396353942Sdimdef NE : EqualityOpcode; 397353942Sdim 398353942Sdimclass ComparisonOpcode : Opcode { 399353942Sdim let Types = [ComparableTypeClass]; 400353942Sdim let HasGroup = 1; 401353942Sdim} 402353942Sdim 403353942Sdimdef LT : ComparisonOpcode; 404353942Sdimdef LE : ComparisonOpcode; 405353942Sdimdef GT : ComparisonOpcode; 406353942Sdimdef GE : ComparisonOpcode; 407353942Sdim 408353942Sdim//===----------------------------------------------------------------------===// 409353942Sdim// Stack management. 410353942Sdim//===----------------------------------------------------------------------===// 411353942Sdim 412353942Sdim// [Value] -> [] 413353942Sdimdef Pop : Opcode { 414353942Sdim let Types = [AllTypeClass]; 415353942Sdim let HasGroup = 1; 416353942Sdim} 417353942Sdim 418353942Sdim// [Value] -> [Value, Value] 419353942Sdimdef Dup : Opcode { 420353942Sdim let Types = [AllTypeClass]; 421353942Sdim let HasGroup = 1; 422353942Sdim} 423