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 378def CheckGlobalCtor : Opcode {} 379 380// [] -> [Value] 381def GetGlobal : AccessOpcode; 382// [Value] -> [] 383def InitGlobal : AccessOpcode; 384// [Value] -> [] 385def InitGlobalTemp : AccessOpcode { 386 let Args = [ArgUint32, ArgLETD]; 387} 388// [Pointer] -> [Pointer] 389def InitGlobalTempComp : Opcode { 390 let Args = [ArgLETD]; 391 let Types = []; 392 let HasGroup = 0; 393} 394// [Value] -> [] 395def SetGlobal : AccessOpcode; 396 397// [] -> [Value] 398def GetParam : AccessOpcode; 399// [Value] -> [] 400def SetParam : AccessOpcode; 401 402// [Pointer] -> [Pointer, Value] 403def GetField : AccessOpcode; 404// [Pointer] -> [Value] 405def GetFieldPop : AccessOpcode; 406// [] -> [Value] 407def GetThisField : AccessOpcode; 408 409// [Pointer, Value] -> [Pointer] 410def SetField : AccessOpcode; 411// [Value] -> [] 412def SetThisField : AccessOpcode; 413 414// [Value] -> [] 415def InitThisField : AccessOpcode; 416// [Value] -> [] 417def InitThisFieldActive : AccessOpcode; 418// [Value] -> [] 419def InitThisBitField : BitFieldOpcode; 420// [Pointer, Value] -> [] 421def InitField : AccessOpcode; 422// [Pointer, Value] -> [] 423def InitBitField : BitFieldOpcode; 424// [Pointer, Value] -> [] 425def InitFieldActive : AccessOpcode; 426 427//===----------------------------------------------------------------------===// 428// Pointer access 429//===----------------------------------------------------------------------===// 430 431class LoadOpcode : Opcode { 432 let Types = [AllTypeClass]; 433 let HasGroup = 1; 434} 435 436// [Pointer] -> [Pointer, Value] 437def Load : LoadOpcode {} 438// [Pointer] -> [Value] 439def LoadPop : LoadOpcode {} 440 441class StoreOpcode : Opcode { 442 let Types = [AllTypeClass]; 443 let HasGroup = 1; 444} 445 446class StoreBitFieldOpcode : Opcode { 447 let Types = [AluTypeClass]; 448 let HasGroup = 1; 449} 450 451// [Pointer, Value] -> [Pointer] 452def Store : StoreOpcode {} 453// [Pointer, Value] -> [] 454def StorePop : StoreOpcode {} 455 456// [Pointer, Value] -> [Pointer] 457def StoreBitField : StoreBitFieldOpcode {} 458// [Pointer, Value] -> [] 459def StoreBitFieldPop : StoreBitFieldOpcode {} 460 461// [Pointer, Value] -> [] 462def InitPop : StoreOpcode {} 463// [Pointer, Value] -> [Pointer] 464def InitElem : Opcode { 465 let Types = [AllTypeClass]; 466 let Args = [ArgUint32]; 467 let HasGroup = 1; 468} 469// [Pointer, Value] -> [] 470def InitElemPop : Opcode { 471 let Types = [AllTypeClass]; 472 let Args = [ArgUint32]; 473 let HasGroup = 1; 474} 475 476//===----------------------------------------------------------------------===// 477// Pointer arithmetic. 478//===----------------------------------------------------------------------===// 479 480// [Pointer, Integral] -> [Pointer] 481def AddOffset : AluOpcode; 482// [Pointer, Integral] -> [Pointer] 483def SubOffset : AluOpcode; 484 485// [Pointer, Pointer] -> [Integral] 486def SubPtr : Opcode { 487 let Types = [IntegerTypeClass]; 488 let HasGroup = 1; 489} 490 491// [Pointer] -> [Pointer] 492def IncPtr : Opcode { 493 let HasGroup = 0; 494} 495// [Pointer] -> [Pointer] 496def DecPtr : Opcode { 497 let HasGroup = 0; 498} 499 500//===----------------------------------------------------------------------===// 501// Function pointers. 502//===----------------------------------------------------------------------===// 503def GetFnPtr : Opcode { 504 let Args = [ArgFunction]; 505} 506 507 508//===----------------------------------------------------------------------===// 509// Binary operators. 510//===----------------------------------------------------------------------===// 511 512// [Real, Real] -> [Real] 513def Add : AluOpcode; 514def Addf : FloatOpcode; 515def Sub : AluOpcode; 516def Subf : FloatOpcode; 517def Mul : AluOpcode; 518def Mulf : FloatOpcode; 519def Rem : IntegerOpcode; 520def Div : IntegerOpcode; 521def Divf : FloatOpcode; 522 523def BitAnd : IntegerOpcode; 524def BitOr : IntegerOpcode; 525def BitXor : IntegerOpcode; 526 527def Shl : Opcode { 528 let Types = [IntegerTypeClass, IntegerTypeClass]; 529 let HasGroup = 1; 530} 531 532def Shr : Opcode { 533 let Types = [IntegerTypeClass, IntegerTypeClass]; 534 let HasGroup = 1; 535} 536 537//===----------------------------------------------------------------------===// 538// Unary operators. 539//===----------------------------------------------------------------------===// 540 541// [Real] -> [Real] 542def Inv: Opcode { 543 let Types = [BoolTypeClass]; 544 let HasGroup = 1; 545} 546 547// Increment and decrement. 548def Inc: IntegerOpcode; 549def IncPop : IntegerOpcode; 550def Dec: IntegerOpcode; 551def DecPop: IntegerOpcode; 552 553// Float increment and decrement. 554def Incf: FloatOpcode; 555def IncfPop : FloatOpcode; 556def Decf: FloatOpcode; 557def DecfPop : FloatOpcode; 558 559// [Real] -> [Real] 560def Neg: Opcode { 561 let Types = [NonPtrTypeClass]; 562 let HasGroup = 1; 563} 564 565// [Real] -> [Real] 566def Comp: Opcode { 567 let Types = [IntegerTypeClass]; 568 let HasGroup = 1; 569} 570 571//===----------------------------------------------------------------------===// 572// Cast, CastFP. 573//===----------------------------------------------------------------------===// 574 575def FromCastTypeClass : TypeClass { 576 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool, IntAP, IntAPS]; 577} 578 579def ToCastTypeClass : TypeClass { 580 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; 581} 582 583def Cast: Opcode { 584 let Types = [FromCastTypeClass, ToCastTypeClass]; 585 let HasGroup = 1; 586} 587 588def CastFP : Opcode { 589 let Types = []; 590 let Args = [ArgFltSemantics, ArgRoundingMode]; 591} 592 593def FixedSizeIntegralTypes : TypeClass { 594 let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; 595} 596 597def CastAP : Opcode { 598 let Types = [AluTypeClass]; 599 let Args = [ArgUint32]; 600 let HasGroup = 1; 601} 602 603def CastAPS : Opcode { 604 let Types = [AluTypeClass]; 605 let Args = [ArgUint32]; 606 let HasGroup = 1; 607} 608 609// Cast an integer to a floating type 610def CastIntegralFloating : Opcode { 611 let Types = [AluTypeClass]; 612 let Args = [ArgFltSemantics, ArgRoundingMode]; 613 let HasGroup = 1; 614} 615 616// Cast a floating to an integer type 617def CastFloatingIntegral : Opcode { 618 let Types = [FixedSizeIntegralTypes]; 619 let Args = []; 620 let HasGroup = 1; 621} 622 623def CastFloatingIntegralAP : Opcode { 624 let Types = []; 625 let Args = [ArgUint32]; 626} 627 628def CastFloatingIntegralAPS : Opcode { 629 let Types = []; 630 let Args = [ArgUint32]; 631} 632 633def CastPointerIntegral : Opcode { 634 let Types = [AluTypeClass]; 635 let Args = []; 636 let HasGroup = 1; 637} 638 639//===----------------------------------------------------------------------===// 640// Comparison opcodes. 641//===----------------------------------------------------------------------===// 642 643class EqualityOpcode : Opcode { 644 let Types = [AllTypeClass]; 645 let HasGroup = 1; 646} 647 648def EQ : EqualityOpcode; 649def NE : EqualityOpcode; 650 651class ComparisonOpcode : Opcode { 652 let Types = [ComparableTypeClass]; 653 let HasGroup = 1; 654} 655 656def CMP3 : ComparisonOpcode { 657 let Args = [ArgCCI]; 658} 659 660def LT : ComparisonOpcode; 661def LE : ComparisonOpcode; 662def GT : ComparisonOpcode; 663def GE : ComparisonOpcode; 664 665//===----------------------------------------------------------------------===// 666// Stack management. 667//===----------------------------------------------------------------------===// 668 669// [Value] -> [] 670def Pop : Opcode { 671 let Types = [AllTypeClass]; 672 let HasGroup = 1; 673} 674 675// [Value] -> [Value, Value] 676def Dup : Opcode { 677 let Types = [AllTypeClass]; 678 let HasGroup = 1; 679} 680 681// [] -> [] 682def Invalid : Opcode {} 683def InvalidCast : Opcode { 684 let Args = [ArgCastKind]; 685} 686 687def InvalidDeclRef : Opcode { 688 let Args = [ArgDeclRef]; 689} 690 691def ArrayDecay : Opcode; 692