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