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 IntAP : Type; 29def IntAPS : Type; 30def Float : Type; 31def Ptr : Type; 32def FnPtr : Type; 33 34//===----------------------------------------------------------------------===// 35// Types transferred to the interpreter. 36//===----------------------------------------------------------------------===// 37 38class ArgType { string Name = ?; } 39def ArgSint8 : ArgType { let Name = "int8_t"; } 40def ArgUint8 : ArgType { let Name = "uint8_t"; } 41def ArgSint16 : ArgType { let Name = "int16_t"; } 42def ArgUint16 : ArgType { let Name = "uint16_t"; } 43def ArgSint32 : ArgType { let Name = "int32_t"; } 44def ArgUint32 : ArgType { let Name = "uint32_t"; } 45def ArgSint64 : ArgType { let Name = "int64_t"; } 46def ArgUint64 : ArgType { let Name = "uint64_t"; } 47def ArgFloat : ArgType { let Name = "Floating"; } 48def ArgBool : ArgType { let Name = "bool"; } 49 50def ArgFunction : ArgType { let Name = "const Function *"; } 51def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; } 52def ArgRecordField : ArgType { let Name = "const Record::Field *"; } 53def ArgFltSemantics : ArgType { let Name = "const llvm::fltSemantics *"; } 54def ArgRoundingMode : ArgType { let Name = "llvm::RoundingMode"; } 55def ArgLETD: ArgType { let Name = "const LifetimeExtendedTemporaryDecl *"; } 56def ArgCastKind : ArgType { let Name = "CastKind"; } 57def ArgCallExpr : ArgType { let Name = "const CallExpr *"; } 58def ArgOffsetOfExpr : ArgType { let Name = "const OffsetOfExpr *"; } 59def ArgDeclRef : ArgType { let Name = "const DeclRefExpr *"; } 60def ArgCCI : ArgType { let Name = "const ComparisonCategoryInfo *"; } 61 62//===----------------------------------------------------------------------===// 63// Classes of types instructions operate on. 64//===----------------------------------------------------------------------===// 65 66class TypeClass { 67 list<Type> Types; 68} 69 70def IntegerTypeClass : TypeClass { 71 let Types = [Sint8, Uint8, Sint16, Uint16, Sint32, 72 Uint32, Sint64, Uint64, IntAP, IntAPS]; 73} 74 75def FixedSizeIntegralTypeClass : TypeClass { 76 let Types = [Sint8, Uint8, Sint16, Uint16, Sint32, 77 Uint32, Sint64, Uint64, Bool]; 78} 79 80def NumberTypeClass : TypeClass { 81 let Types = !listconcat(IntegerTypeClass.Types, [Float]); 82} 83 84def FloatTypeClass : TypeClass { 85 let Types = [Float]; 86} 87 88def AluTypeClass : TypeClass { 89 let Types = !listconcat(IntegerTypeClass.Types, [Bool]); 90} 91 92def PtrTypeClass : TypeClass { 93 let Types = [Ptr, FnPtr]; 94} 95 96def BoolTypeClass : TypeClass { 97 let Types = [Bool]; 98} 99 100def NonPtrTypeClass : TypeClass { 101 let Types = !listconcat(IntegerTypeClass.Types, [Bool], [Float]); 102} 103 104def AllTypeClass : TypeClass { 105 let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types, FloatTypeClass.Types); 106} 107 108def ComparableTypeClass : TypeClass { 109 let Types = !listconcat(AluTypeClass.Types, [Ptr], [Float], [FnPtr]); 110} 111 112class SingletonTypeClass<Type Ty> : TypeClass { 113 let Types = [Ty]; 114} 115 116//===----------------------------------------------------------------------===// 117// Record describing all opcodes. 118//===----------------------------------------------------------------------===// 119 120class Opcode { 121 list<TypeClass> Types = []; 122 list<ArgType> Args = []; 123 string Name = ""; 124 bit CanReturn = 0; 125 bit ChangesPC = 0; 126 bit HasCustomLink = 0; 127 bit HasCustomEval = 0; 128 bit HasGroup = 0; 129} 130 131class AluOpcode : Opcode { 132 let Types = [AluTypeClass]; 133 let HasGroup = 1; 134} 135 136class FloatOpcode : Opcode { 137 let Types = []; 138 let Args = [ArgRoundingMode]; 139} 140 141class IntegerOpcode : Opcode { 142 let Types = [IntegerTypeClass]; 143 let HasGroup = 1; 144} 145 146//===----------------------------------------------------------------------===// 147// Jump opcodes 148//===----------------------------------------------------------------------===// 149 150class JumpOpcode : Opcode { 151 let Args = [ArgSint32]; 152 let ChangesPC = 1; 153 let HasCustomEval = 1; 154} 155 156// [] -> [] 157def Jmp : JumpOpcode; 158// [Bool] -> [], jumps if true. 159def Jt : JumpOpcode; 160// [Bool] -> [], jumps if false. 161def Jf : JumpOpcode; 162 163//===----------------------------------------------------------------------===// 164// Returns 165//===----------------------------------------------------------------------===// 166 167// [Value] -> [] 168def Ret : Opcode { 169 let Types = [AllTypeClass]; 170 let ChangesPC = 1; 171 let CanReturn = 1; 172 let HasGroup = 1; 173 let HasCustomEval = 1; 174} 175// [] -> [] 176def RetVoid : Opcode { 177 let CanReturn = 1; 178 let ChangesPC = 1; 179 let HasCustomEval = 1; 180} 181// [Value] -> [] 182def RetValue : Opcode { 183 let CanReturn = 1; 184 let ChangesPC = 1; 185 let HasCustomEval = 1; 186} 187// [] -> EXIT 188def NoRet : Opcode {} 189 190 191def Call : Opcode { 192 let Args = [ArgFunction]; 193 let Types = []; 194} 195 196def CallVirt : Opcode { 197 let Args = [ArgFunction]; 198 let Types = []; 199} 200 201def CallBI : Opcode { 202 let Args = [ArgFunction, ArgCallExpr]; 203 let Types = []; 204} 205 206def CallPtr : Opcode { 207 let Args = []; 208 let Types = []; 209} 210 211def OffsetOf : Opcode { 212 let Types = [IntegerTypeClass]; 213 let Args = [ArgOffsetOfExpr]; 214 let HasGroup = 1; 215} 216 217//===----------------------------------------------------------------------===// 218// Frame management 219//===----------------------------------------------------------------------===// 220 221// [] -> [] 222def Destroy : Opcode { 223 let Args = [ArgUint32]; 224 let HasCustomEval = 1; 225} 226 227//===----------------------------------------------------------------------===// 228// Constants 229//===----------------------------------------------------------------------===// 230 231class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode { 232 let Types = [SingletonTypeClass<Ty>]; 233 let Args = [ArgTy]; 234 let Name = "Const"; 235} 236 237// [] -> [Integer] 238def ConstSint8 : ConstOpcode<Sint8, ArgSint8>; 239def ConstUint8 : ConstOpcode<Uint8, ArgUint8>; 240def ConstSint16 : ConstOpcode<Sint16, ArgSint16>; 241def ConstUint16 : ConstOpcode<Uint16, ArgUint16>; 242def ConstSint32 : ConstOpcode<Sint32, ArgSint32>; 243def ConstUint32 : ConstOpcode<Uint32, ArgUint32>; 244def ConstSint64 : ConstOpcode<Sint64, ArgSint64>; 245def ConstUint64 : ConstOpcode<Uint64, ArgUint64>; 246def ConstFloat : ConstOpcode<Float, ArgFloat>; 247def ConstBool : ConstOpcode<Bool, ArgBool>; 248 249// [] -> [Integer] 250def Zero : Opcode { 251 let Types = [FixedSizeIntegralTypeClass]; 252 let HasGroup = 1; 253} 254 255def ZeroIntAP : Opcode { 256 let Args = [ArgUint32]; 257} 258 259def ZeroIntAPS : Opcode { 260 let Args = [ArgUint32]; 261} 262 263// [] -> [Pointer] 264def Null : Opcode { 265 let Types = [PtrTypeClass]; 266 let HasGroup = 1; 267} 268 269//===----------------------------------------------------------------------===// 270// Pointer generation 271//===----------------------------------------------------------------------===// 272 273// [] -> [Pointer] 274def GetPtrLocal : Opcode { 275 // Offset of local. 276 let Args = [ArgUint32]; 277 bit HasCustomEval = 1; 278} 279// [] -> [Pointer] 280def GetPtrParam : Opcode { 281 // Offset of parameter. 282 let Args = [ArgUint32]; 283} 284// [] -> [Pointer] 285def GetPtrGlobal : Opcode { 286 // Index of global. 287 let Args = [ArgUint32]; 288} 289// [Pointer] -> [Pointer] 290def GetPtrField : Opcode { 291 // Offset of field. 292 let Args = [ArgUint32]; 293} 294// [Pointer] -> [Pointer] 295def GetPtrActiveField : Opcode { 296 // Offset of field. 297 let Args = [ArgUint32]; 298} 299// [] -> [Pointer] 300def GetPtrActiveThisField : Opcode { 301 // Offset of field. 302 let Args = [ArgUint32]; 303} 304// [] -> [Pointer] 305def GetPtrThisField : Opcode { 306 // Offset of field. 307 let Args = [ArgUint32]; 308} 309// [Pointer] -> [Pointer] 310def GetPtrBase : Opcode { 311 // Offset of field, which is a base. 312 let Args = [ArgUint32]; 313} 314// [Pointer] -> [Pointer] 315def GetPtrBasePop : Opcode { 316 // Offset of field, which is a base. 317 let Args = [ArgUint32]; 318} 319 320def InitPtrPop : Opcode { 321 let Args = []; 322} 323 324def GetPtrDerivedPop : Opcode { 325 let Args = [ArgUint32]; 326} 327 328// [Pointer] -> [Pointer] 329def GetPtrVirtBase : Opcode { 330 // RecordDecl of base class. 331 let Args = [ArgRecordDecl]; 332} 333// [] -> [Pointer] 334def GetPtrThisBase : Opcode { 335 // Offset of field, which is a base. 336 let Args = [ArgUint32]; 337} 338// [] -> [Pointer] 339def GetPtrThisVirtBase : Opcode { 340 // RecordDecl of base class. 341 let Args = [ArgRecordDecl]; 342} 343// [] -> [Pointer] 344def This : Opcode; 345 346// [] -> [Pointer] 347def RVOPtr : Opcode; 348 349// [Pointer] -> [Pointer] 350def NarrowPtr : Opcode; 351// [Pointer] -> [Pointer] 352def ExpandPtr : Opcode; 353// [Pointer, Offset] -> [Pointer] 354def ArrayElemPtr : AluOpcode; 355def ArrayElemPtrPop : AluOpcode; 356 357//===----------------------------------------------------------------------===// 358// Direct field accessors 359//===----------------------------------------------------------------------===// 360 361class AccessOpcode : Opcode { 362 let Types = [AllTypeClass]; 363 let Args = [ArgUint32]; 364 let HasGroup = 1; 365} 366 367class BitFieldOpcode : Opcode { 368 let Types = [AluTypeClass]; 369 let Args = [ArgRecordField]; 370 let HasGroup = 1; 371} 372 373// [] -> [Pointer] 374def GetLocal : AccessOpcode { let HasCustomEval = 1; } 375// [] -> [Pointer] 376def SetLocal : AccessOpcode { let HasCustomEval = 1; } 377 378// [] -> [Value] 379def GetGlobal : AccessOpcode; 380def GetGlobalUnchecked : AccessOpcode; 381// [Value] -> [] 382def InitGlobal : AccessOpcode; 383// [Value] -> [] 384def InitGlobalTemp : AccessOpcode { 385 let Args = [ArgUint32, ArgLETD]; 386} 387// [Pointer] -> [Pointer] 388def InitGlobalTempComp : Opcode { 389 let Args = [ArgLETD]; 390 let Types = []; 391 let HasGroup = 0; 392} 393// [Value] -> [] 394def SetGlobal : AccessOpcode; 395 396// [] -> [Value] 397def GetParam : AccessOpcode; 398// [Value] -> [] 399def SetParam : AccessOpcode; 400 401// [Pointer] -> [Pointer, Value] 402def GetField : AccessOpcode; 403// [Pointer] -> [Value] 404def GetFieldPop : AccessOpcode; 405// [] -> [Value] 406def GetThisField : AccessOpcode; 407 408// [Pointer, Value] -> [Pointer] 409def SetField : AccessOpcode; 410// [Value] -> [] 411def SetThisField : AccessOpcode; 412 413// [Value] -> [] 414def InitThisField : AccessOpcode; 415// [Value] -> [] 416def InitThisFieldActive : AccessOpcode; 417// [Value] -> [] 418def InitThisBitField : Opcode { 419 let Types = [AluTypeClass]; 420 let Args = [ArgRecordField, ArgUint32]; 421 let HasGroup = 1; 422} 423// [Pointer, Value] -> [] 424def InitField : AccessOpcode; 425// [Pointer, Value] -> [] 426def InitBitField : BitFieldOpcode; 427// [Pointer, Value] -> [] 428def InitFieldActive : AccessOpcode; 429 430//===----------------------------------------------------------------------===// 431// Pointer access 432//===----------------------------------------------------------------------===// 433 434class LoadOpcode : Opcode { 435 let Types = [AllTypeClass]; 436 let HasGroup = 1; 437} 438 439// [Pointer] -> [Pointer, Value] 440def Load : LoadOpcode {} 441// [Pointer] -> [Value] 442def LoadPop : LoadOpcode {} 443 444class StoreOpcode : Opcode { 445 let Types = [AllTypeClass]; 446 let HasGroup = 1; 447} 448 449class StoreBitFieldOpcode : Opcode { 450 let Types = [AluTypeClass]; 451 let HasGroup = 1; 452} 453 454// [Pointer, Value] -> [Pointer] 455def Store : StoreOpcode {} 456// [Pointer, Value] -> [] 457def StorePop : StoreOpcode {} 458 459// [Pointer, Value] -> [Pointer] 460def StoreBitField : StoreBitFieldOpcode {} 461// [Pointer, Value] -> [] 462def StoreBitFieldPop : StoreBitFieldOpcode {} 463 464// [Pointer, Value] -> [] 465def InitPop : StoreOpcode {} 466// [Pointer, Value] -> [Pointer] 467def InitElem : Opcode { 468 let Types = [AllTypeClass]; 469 let Args = [ArgUint32]; 470 let HasGroup = 1; 471} 472// [Pointer, Value] -> [] 473def InitElemPop : Opcode { 474 let Types = [AllTypeClass]; 475 let Args = [ArgUint32]; 476 let HasGroup = 1; 477} 478 479//===----------------------------------------------------------------------===// 480// Pointer arithmetic. 481//===----------------------------------------------------------------------===// 482 483// [Pointer, Integral] -> [Pointer] 484def AddOffset : AluOpcode; 485// [Pointer, Integral] -> [Pointer] 486def SubOffset : AluOpcode; 487 488// [Pointer, Pointer] -> [Integral] 489def SubPtr : Opcode { 490 let Types = [IntegerTypeClass]; 491 let HasGroup = 1; 492} 493 494// [Pointer] -> [Pointer] 495def IncPtr : Opcode { 496 let HasGroup = 0; 497} 498// [Pointer] -> [Pointer] 499def DecPtr : Opcode { 500 let HasGroup = 0; 501} 502 503//===----------------------------------------------------------------------===// 504// Function pointers. 505//===----------------------------------------------------------------------===// 506def GetFnPtr : Opcode { 507 let Args = [ArgFunction]; 508} 509 510 511//===----------------------------------------------------------------------===// 512// Binary operators. 513//===----------------------------------------------------------------------===// 514 515// [Real, Real] -> [Real] 516def Add : AluOpcode; 517def Addf : FloatOpcode; 518def Sub : AluOpcode; 519def Subf : FloatOpcode; 520def Mul : AluOpcode; 521def Mulf : FloatOpcode; 522def Rem : IntegerOpcode; 523def Div : IntegerOpcode; 524def Divf : FloatOpcode; 525 526def BitAnd : IntegerOpcode; 527def BitOr : IntegerOpcode; 528def BitXor : IntegerOpcode; 529 530def Shl : Opcode { 531 let Types = [IntegerTypeClass, IntegerTypeClass]; 532 let HasGroup = 1; 533} 534 535def Shr : Opcode { 536 let Types = [IntegerTypeClass, IntegerTypeClass]; 537 let HasGroup = 1; 538} 539 540//===----------------------------------------------------------------------===// 541// Unary operators. 542//===----------------------------------------------------------------------===// 543 544// [Real] -> [Real] 545def Inv: Opcode { 546 let Types = [BoolTypeClass]; 547 let HasGroup = 1; 548} 549 550// Increment and decrement. 551def Inc: IntegerOpcode; 552def IncPop : IntegerOpcode; 553def Dec: IntegerOpcode; 554def DecPop: IntegerOpcode; 555 556// Float increment and decrement. 557def Incf: FloatOpcode; 558def IncfPop : FloatOpcode; 559def Decf: FloatOpcode; 560def DecfPop : FloatOpcode; 561 562// [Real] -> [Real] 563def Neg: Opcode { 564 let Types = [NonPtrTypeClass]; 565 let HasGroup = 1; 566} 567 568// [Real] -> [Real] 569def Comp: Opcode { 570 let Types = [IntegerTypeClass]; 571 let HasGroup = 1; 572} 573 574//===----------------------------------------------------------------------===// 575// Cast, CastFP. 576//===----------------------------------------------------------------------===// 577 578def FromCastTypeClass : TypeClass { 579 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool, IntAP, IntAPS]; 580} 581 582def ToCastTypeClass : TypeClass { 583 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; 584} 585 586def Cast: Opcode { 587 let Types = [FromCastTypeClass, ToCastTypeClass]; 588 let HasGroup = 1; 589} 590 591def CastFP : Opcode { 592 let Types = []; 593 let Args = [ArgFltSemantics, ArgRoundingMode]; 594} 595 596def FixedSizeIntegralTypes : TypeClass { 597 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; 598} 599 600def CastAP : Opcode { 601 let Types = [AluTypeClass]; 602 let Args = [ArgUint32]; 603 let HasGroup = 1; 604} 605 606def CastAPS : Opcode { 607 let Types = [AluTypeClass]; 608 let Args = [ArgUint32]; 609 let HasGroup = 1; 610} 611 612// Cast an integer to a floating type 613def CastIntegralFloating : Opcode { 614 let Types = [AluTypeClass]; 615 let Args = [ArgFltSemantics, ArgRoundingMode]; 616 let HasGroup = 1; 617} 618 619// Cast a floating to an integer type 620def CastFloatingIntegral : Opcode { 621 let Types = [FixedSizeIntegralTypes]; 622 let Args = []; 623 let HasGroup = 1; 624} 625 626def CastFloatingIntegralAP : Opcode { 627 let Types = []; 628 let Args = [ArgUint32]; 629} 630 631def CastFloatingIntegralAPS : Opcode { 632 let Types = []; 633 let Args = [ArgUint32]; 634} 635 636def CastPointerIntegral : Opcode { 637 let Types = [AluTypeClass]; 638 let Args = []; 639 let HasGroup = 1; 640} 641 642//===----------------------------------------------------------------------===// 643// Comparison opcodes. 644//===----------------------------------------------------------------------===// 645 646class EqualityOpcode : Opcode { 647 let Types = [AllTypeClass]; 648 let HasGroup = 1; 649} 650 651def EQ : EqualityOpcode; 652def NE : EqualityOpcode; 653 654class ComparisonOpcode : Opcode { 655 let Types = [ComparableTypeClass]; 656 let HasGroup = 1; 657} 658 659def CMP3 : ComparisonOpcode { 660 let Args = [ArgCCI]; 661} 662 663def LT : ComparisonOpcode; 664def LE : ComparisonOpcode; 665def GT : ComparisonOpcode; 666def GE : ComparisonOpcode; 667 668//===----------------------------------------------------------------------===// 669// Stack management. 670//===----------------------------------------------------------------------===// 671 672// [Value] -> [] 673def Pop : Opcode { 674 let Types = [AllTypeClass]; 675 let HasGroup = 1; 676} 677 678// [Value] -> [Value, Value] 679def Dup : Opcode { 680 let Types = [AllTypeClass]; 681 let HasGroup = 1; 682} 683 684// [] -> [] 685def Invalid : Opcode {} 686def InvalidCast : Opcode { 687 let Args = [ArgCastKind]; 688} 689 690def InvalidDeclRef : Opcode { 691 let Args = [ArgDeclRef]; 692} 693 694def ArrayDecay : Opcode; 695