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 = "const Function *"; } 46def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; } 47def ArgRecordField : ArgType { let Name = "const Record::Field *"; } 48 49//===----------------------------------------------------------------------===// 50// Classes of types instructions operate on. 51//===----------------------------------------------------------------------===// 52 53class TypeClass { 54 list<Type> Types; 55} 56 57def NumberTypeClass : TypeClass { 58 let Types = [Sint8, Uint8, Sint16, Uint16, Sint32, 59 Uint32, Sint64, Uint64]; 60} 61 62def IntegerTypeClass : TypeClass { 63 let Types = [Sint8, Uint8, Sint16, Uint16, Sint32, 64 Uint32, Sint64, Uint64]; 65} 66 67def AluTypeClass : TypeClass { 68 let Types = !listconcat(NumberTypeClass.Types, [Bool]); 69} 70 71def PtrTypeClass : TypeClass { 72 let Types = [Ptr]; 73} 74 75def BoolTypeClass : TypeClass { 76 let Types = [Bool]; 77} 78 79def AllTypeClass : TypeClass { 80 let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types); 81} 82 83def ComparableTypeClass : TypeClass { 84 let Types = !listconcat(AluTypeClass.Types, [Ptr]); 85} 86 87class SingletonTypeClass<Type Ty> : TypeClass { 88 let Types = [Ty]; 89} 90 91//===----------------------------------------------------------------------===// 92// Record describing all opcodes. 93//===----------------------------------------------------------------------===// 94 95class Opcode { 96 list<TypeClass> Types = []; 97 list<ArgType> Args = []; 98 string Name = ""; 99 bit CanReturn = 0; 100 bit ChangesPC = 0; 101 bit HasCustomLink = 0; 102 bit HasCustomEval = 0; 103 bit HasGroup = 0; 104} 105 106class AluOpcode : Opcode { 107 let Types = [AluTypeClass]; 108 let HasGroup = 1; 109} 110 111class IntegerOpcode : Opcode { 112 let Types = [IntegerTypeClass]; 113 let HasGroup = 1; 114} 115 116//===----------------------------------------------------------------------===// 117// Jump opcodes 118//===----------------------------------------------------------------------===// 119 120class JumpOpcode : Opcode { 121 let Args = [ArgSint32]; 122 let ChangesPC = 1; 123 let HasCustomEval = 1; 124} 125 126// [] -> [] 127def Jmp : JumpOpcode; 128// [Bool] -> [], jumps if true. 129def Jt : JumpOpcode; 130// [Bool] -> [], jumps if false. 131def Jf : JumpOpcode; 132 133//===----------------------------------------------------------------------===// 134// Returns 135//===----------------------------------------------------------------------===// 136 137// [Value] -> [] 138def Ret : Opcode { 139 let Types = [AllTypeClass]; 140 let ChangesPC = 1; 141 let CanReturn = 1; 142 let HasGroup = 1; 143 let HasCustomEval = 1; 144} 145// [] -> [] 146def RetVoid : Opcode { 147 let CanReturn = 1; 148 let ChangesPC = 1; 149 let HasCustomEval = 1; 150} 151// [Value] -> [] 152def RetValue : Opcode { 153 let CanReturn = 1; 154 let ChangesPC = 1; 155 let HasCustomEval = 1; 156} 157// [] -> EXIT 158def NoRet : Opcode {} 159 160 161def Call : Opcode { 162 let Args = [ArgFunction]; 163 let Types = []; 164 let ChangesPC = 1; 165} 166 167//===----------------------------------------------------------------------===// 168// Frame management 169//===----------------------------------------------------------------------===// 170 171// [] -> [] 172def Destroy : Opcode { 173 let Args = [ArgUint32]; 174 let HasCustomEval = 1; 175} 176 177//===----------------------------------------------------------------------===// 178// Constants 179//===----------------------------------------------------------------------===// 180 181class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode { 182 let Types = [SingletonTypeClass<Ty>]; 183 let Args = [ArgTy]; 184 let Name = "Const"; 185} 186 187// [] -> [Integer] 188def ConstSint8 : ConstOpcode<Sint8, ArgSint8>; 189def ConstUint8 : ConstOpcode<Uint8, ArgUint8>; 190def ConstSint16 : ConstOpcode<Sint16, ArgSint16>; 191def ConstUint16 : ConstOpcode<Uint16, ArgUint16>; 192def ConstSint32 : ConstOpcode<Sint32, ArgSint32>; 193def ConstUint32 : ConstOpcode<Uint32, ArgUint32>; 194def ConstSint64 : ConstOpcode<Sint64, ArgSint64>; 195def ConstUint64 : ConstOpcode<Uint64, ArgUint64>; 196def ConstBool : ConstOpcode<Bool, ArgBool>; 197 198// [] -> [Integer] 199def Zero : Opcode { 200 let Types = [AluTypeClass]; 201 let HasGroup = 1; 202} 203 204// [] -> [Pointer] 205def Null : Opcode { 206 let Types = [PtrTypeClass]; 207} 208 209//===----------------------------------------------------------------------===// 210// Pointer generation 211//===----------------------------------------------------------------------===// 212 213// [] -> [Pointer] 214def GetPtrLocal : Opcode { 215 // Offset of local. 216 let Args = [ArgUint32]; 217 bit HasCustomEval = 1; 218} 219// [] -> [Pointer] 220def GetPtrParam : Opcode { 221 // Offset of parameter. 222 let Args = [ArgUint32]; 223} 224// [] -> [Pointer] 225def GetPtrGlobal : Opcode { 226 // Index of global. 227 let Args = [ArgUint32]; 228} 229// [Pointer] -> [Pointer] 230def GetPtrField : Opcode { 231 // Offset of field. 232 let Args = [ArgUint32]; 233} 234// [Pointer] -> [Pointer] 235def GetPtrActiveField : Opcode { 236 // Offset of field. 237 let Args = [ArgUint32]; 238} 239// [] -> [Pointer] 240def GetPtrActiveThisField : Opcode { 241 // Offset of field. 242 let Args = [ArgUint32]; 243} 244// [] -> [Pointer] 245def GetPtrThisField : Opcode { 246 // Offset of field. 247 let Args = [ArgUint32]; 248} 249// [Pointer] -> [Pointer] 250def GetPtrBase : Opcode { 251 // Offset of field, which is a base. 252 let Args = [ArgUint32]; 253} 254// [Pointer] -> [Pointer] 255def GetPtrVirtBase : Opcode { 256 // RecordDecl of base class. 257 let Args = [ArgRecordDecl]; 258} 259// [] -> [Pointer] 260def GetPtrThisBase : Opcode { 261 // Offset of field, which is a base. 262 let Args = [ArgUint32]; 263} 264// [] -> [Pointer] 265def GetPtrThisVirtBase : Opcode { 266 // RecordDecl of base class. 267 let Args = [ArgRecordDecl]; 268} 269// [] -> [Pointer] 270def This : Opcode; 271 272// [] -> [Pointer] 273def RVOPtr : Opcode; 274 275// [Pointer] -> [Pointer] 276def NarrowPtr : Opcode; 277// [Pointer] -> [Pointer] 278def ExpandPtr : Opcode; 279 280//===----------------------------------------------------------------------===// 281// Direct field accessors 282//===----------------------------------------------------------------------===// 283 284class AccessOpcode : Opcode { 285 let Types = [AllTypeClass]; 286 let Args = [ArgUint32]; 287 let HasGroup = 1; 288} 289 290class BitFieldOpcode : Opcode { 291 let Types = [AluTypeClass]; 292 let Args = [ArgRecordField]; 293 let HasGroup = 1; 294} 295 296// [] -> [Pointer] 297def GetLocal : AccessOpcode { let HasCustomEval = 1; } 298// [] -> [Pointer] 299def SetLocal : AccessOpcode { let HasCustomEval = 1; } 300 301// [] -> [Value] 302def GetGlobal : AccessOpcode; 303// [Value] -> [] 304def InitGlobal : AccessOpcode; 305// [Value] -> [] 306def SetGlobal : AccessOpcode; 307 308// [] -> [Value] 309def GetParam : AccessOpcode; 310// [Value] -> [] 311def SetParam : AccessOpcode; 312 313// [Pointer] -> [Pointer, Value] 314def GetField : AccessOpcode; 315// [Pointer] -> [Value] 316def GetFieldPop : AccessOpcode; 317// [] -> [Value] 318def GetThisField : AccessOpcode; 319 320// [Pointer, Value] -> [Pointer] 321def SetField : AccessOpcode; 322// [Value] -> [] 323def SetThisField : AccessOpcode; 324 325// [Value] -> [] 326def InitThisField : AccessOpcode; 327// [Value] -> [] 328def InitThisFieldActive : AccessOpcode; 329// [Value] -> [] 330def InitThisBitField : BitFieldOpcode; 331// [Pointer, Value] -> [] 332def InitField : AccessOpcode; 333// [Pointer, Value] -> [] 334def InitBitField : BitFieldOpcode; 335// [Pointer, Value] -> [] 336def InitFieldActive : AccessOpcode; 337 338//===----------------------------------------------------------------------===// 339// Pointer access 340//===----------------------------------------------------------------------===// 341 342class LoadOpcode : Opcode { 343 let Types = [AllTypeClass]; 344 let HasGroup = 1; 345} 346 347// [Pointer] -> [Pointer, Value] 348def Load : LoadOpcode {} 349// [Pointer] -> [Value] 350def LoadPop : LoadOpcode {} 351 352class StoreOpcode : Opcode { 353 let Types = [AllTypeClass]; 354 let HasGroup = 1; 355} 356 357class StoreBitFieldOpcode : Opcode { 358 let Types = [AluTypeClass]; 359 let HasGroup = 1; 360} 361 362// [Pointer, Value] -> [Pointer] 363def Store : StoreOpcode {} 364// [Pointer, Value] -> [] 365def StorePop : StoreOpcode {} 366 367// [Pointer, Value] -> [Pointer] 368def StoreBitField : StoreBitFieldOpcode {} 369// [Pointer, Value] -> [] 370def StoreBitFieldPop : StoreBitFieldOpcode {} 371 372// [Pointer, Value] -> [] 373def InitPop : StoreOpcode {} 374// [Pointer, Value] -> [Pointer] 375def InitElem : Opcode { 376 let Types = [AllTypeClass]; 377 let Args = [ArgUint32]; 378 let HasGroup = 1; 379} 380// [Pointer, Value] -> [] 381def InitElemPop : Opcode { 382 let Types = [AllTypeClass]; 383 let Args = [ArgUint32]; 384 let HasGroup = 1; 385} 386 387//===----------------------------------------------------------------------===// 388// Pointer arithmetic. 389//===----------------------------------------------------------------------===// 390 391// [Pointer, Integral] -> [Pointer] 392def AddOffset : AluOpcode; 393// [Pointer, Integral] -> [Pointer] 394def SubOffset : AluOpcode; 395 396// Pointer, Pointer] - [Integral] 397def SubPtr : Opcode { 398 let Types = [IntegerTypeClass]; 399 let HasGroup = 1; 400} 401 402//===----------------------------------------------------------------------===// 403// Binary operators. 404//===----------------------------------------------------------------------===// 405 406// [Real, Real] -> [Real] 407def Sub : AluOpcode; 408def Add : AluOpcode; 409def Mul : AluOpcode; 410def Rem : Opcode { 411 let Types = [NumberTypeClass]; 412 let HasGroup = 1; 413} 414 415def Shl : Opcode { 416 let Types = [IntegerTypeClass, IntegerTypeClass]; 417 let HasGroup = 1; 418} 419 420def Shr : Opcode { 421 let Types = [IntegerTypeClass, IntegerTypeClass]; 422 let HasGroup = 1; 423} 424 425def BitAnd : IntegerOpcode; 426def BitOr : IntegerOpcode; 427def Div : Opcode { 428 let Types = [NumberTypeClass]; 429 let HasGroup = 1; 430} 431def BitXor : IntegerOpcode; 432 433//===----------------------------------------------------------------------===// 434// Unary operators. 435//===----------------------------------------------------------------------===// 436 437// [Real] -> [Real] 438def Inv: Opcode { 439 let Types = [BoolTypeClass]; 440 let HasGroup = 1; 441} 442 443def Inc: IntegerOpcode; 444def IncPop : IntegerOpcode; 445def Dec: IntegerOpcode; 446def DecPop: IntegerOpcode; 447 448// [Real] -> [Real] 449def Neg: Opcode { 450 let Types = [AluTypeClass]; 451 let HasGroup = 1; 452} 453 454// [Real] -> [Real] 455def Comp: Opcode { 456 let Types = [NumberTypeClass]; 457 let HasGroup = 1; 458} 459 460//===----------------------------------------------------------------------===// 461// Cast. 462//===----------------------------------------------------------------------===// 463// TODO: Expand this to handle casts between more types. 464 465def FromCastTypeClass : TypeClass { 466 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; 467} 468 469def ToCastTypeClass : TypeClass { 470 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; 471} 472 473def Cast: Opcode { 474 let Types = [FromCastTypeClass, ToCastTypeClass]; 475 let HasGroup = 1; 476} 477 478//===----------------------------------------------------------------------===// 479// Comparison opcodes. 480//===----------------------------------------------------------------------===// 481 482class EqualityOpcode : Opcode { 483 let Types = [AllTypeClass]; 484 let HasGroup = 1; 485} 486 487def EQ : EqualityOpcode; 488def NE : EqualityOpcode; 489 490class ComparisonOpcode : Opcode { 491 let Types = [ComparableTypeClass]; 492 let HasGroup = 1; 493} 494 495def LT : ComparisonOpcode; 496def LE : ComparisonOpcode; 497def GT : ComparisonOpcode; 498def GE : ComparisonOpcode; 499 500//===----------------------------------------------------------------------===// 501// Stack management. 502//===----------------------------------------------------------------------===// 503 504// [Value] -> [] 505def Pop : Opcode { 506 let Types = [AllTypeClass]; 507 let HasGroup = 1; 508} 509 510// [Value] -> [Value, Value] 511def Dup : Opcode { 512 let Types = [AllTypeClass]; 513 let HasGroup = 1; 514} 515