123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- //===--- Opcodes.td - Opcode defitions for the constexpr VM -----*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // Helper file used to generate opcodes, the interpreter and the disassembler.
- //
- //===----------------------------------------------------------------------===//
- //===----------------------------------------------------------------------===//
- // Types evaluated by the interpreter.
- //===----------------------------------------------------------------------===//
- class Type;
- def Bool : Type;
- def Sint8 : Type;
- def Uint8 : Type;
- def Sint16 : Type;
- def Uint16 : Type;
- def Sint32 : Type;
- def Uint32 : Type;
- def Sint64 : Type;
- def Uint64 : Type;
- def Ptr : Type;
- //===----------------------------------------------------------------------===//
- // Types transferred to the interpreter.
- //===----------------------------------------------------------------------===//
- class ArgType { string Name = ?; }
- def ArgSint8 : ArgType { let Name = "int8_t"; }
- def ArgUint8 : ArgType { let Name = "uint8_t"; }
- def ArgSint16 : ArgType { let Name = "int16_t"; }
- def ArgUint16 : ArgType { let Name = "uint16_t"; }
- def ArgSint32 : ArgType { let Name = "int32_t"; }
- def ArgUint32 : ArgType { let Name = "uint32_t"; }
- def ArgSint64 : ArgType { let Name = "int64_t"; }
- def ArgUint64 : ArgType { let Name = "uint64_t"; }
- def ArgBool : ArgType { let Name = "bool"; }
- def ArgFunction : ArgType { let Name = "const Function *"; }
- def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; }
- def ArgRecordField : ArgType { let Name = "const Record::Field *"; }
- //===----------------------------------------------------------------------===//
- // Classes of types instructions operate on.
- //===----------------------------------------------------------------------===//
- class TypeClass {
- list<Type> Types;
- }
- def NumberTypeClass : TypeClass {
- let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
- Uint32, Sint64, Uint64];
- }
- def IntegerTypeClass : TypeClass {
- let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
- Uint32, Sint64, Uint64];
- }
- def AluTypeClass : TypeClass {
- let Types = !listconcat(NumberTypeClass.Types, [Bool]);
- }
- def PtrTypeClass : TypeClass {
- let Types = [Ptr];
- }
- def BoolTypeClass : TypeClass {
- let Types = [Bool];
- }
- def AllTypeClass : TypeClass {
- let Types = !listconcat(AluTypeClass.Types, PtrTypeClass.Types);
- }
- def ComparableTypeClass : TypeClass {
- let Types = !listconcat(AluTypeClass.Types, [Ptr]);
- }
- class SingletonTypeClass<Type Ty> : TypeClass {
- let Types = [Ty];
- }
- //===----------------------------------------------------------------------===//
- // Record describing all opcodes.
- //===----------------------------------------------------------------------===//
- class Opcode {
- list<TypeClass> Types = [];
- list<ArgType> Args = [];
- string Name = "";
- bit CanReturn = 0;
- bit ChangesPC = 0;
- bit HasCustomLink = 0;
- bit HasCustomEval = 0;
- bit HasGroup = 0;
- }
- class AluOpcode : Opcode {
- let Types = [AluTypeClass];
- let HasGroup = 1;
- }
- class IntegerOpcode : Opcode {
- let Types = [IntegerTypeClass];
- let HasGroup = 1;
- }
- //===----------------------------------------------------------------------===//
- // Jump opcodes
- //===----------------------------------------------------------------------===//
- class JumpOpcode : Opcode {
- let Args = [ArgSint32];
- let ChangesPC = 1;
- let HasCustomEval = 1;
- }
- // [] -> []
- def Jmp : JumpOpcode;
- // [Bool] -> [], jumps if true.
- def Jt : JumpOpcode;
- // [Bool] -> [], jumps if false.
- def Jf : JumpOpcode;
- //===----------------------------------------------------------------------===//
- // Returns
- //===----------------------------------------------------------------------===//
- // [Value] -> []
- def Ret : Opcode {
- let Types = [AllTypeClass];
- let ChangesPC = 1;
- let CanReturn = 1;
- let HasGroup = 1;
- let HasCustomEval = 1;
- }
- // [] -> []
- def RetVoid : Opcode {
- let CanReturn = 1;
- let ChangesPC = 1;
- let HasCustomEval = 1;
- }
- // [Value] -> []
- def RetValue : Opcode {
- let CanReturn = 1;
- let ChangesPC = 1;
- let HasCustomEval = 1;
- }
- // [] -> EXIT
- def NoRet : Opcode {}
- def Call : Opcode {
- let Args = [ArgFunction];
- let Types = [];
- let ChangesPC = 1;
- }
- //===----------------------------------------------------------------------===//
- // Frame management
- //===----------------------------------------------------------------------===//
- // [] -> []
- def Destroy : Opcode {
- let Args = [ArgUint32];
- let HasCustomEval = 1;
- }
- //===----------------------------------------------------------------------===//
- // Constants
- //===----------------------------------------------------------------------===//
- class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
- let Types = [SingletonTypeClass<Ty>];
- let Args = [ArgTy];
- let Name = "Const";
- }
- // [] -> [Integer]
- def ConstSint8 : ConstOpcode<Sint8, ArgSint8>;
- def ConstUint8 : ConstOpcode<Uint8, ArgUint8>;
- def ConstSint16 : ConstOpcode<Sint16, ArgSint16>;
- def ConstUint16 : ConstOpcode<Uint16, ArgUint16>;
- def ConstSint32 : ConstOpcode<Sint32, ArgSint32>;
- def ConstUint32 : ConstOpcode<Uint32, ArgUint32>;
- def ConstSint64 : ConstOpcode<Sint64, ArgSint64>;
- def ConstUint64 : ConstOpcode<Uint64, ArgUint64>;
- def ConstBool : ConstOpcode<Bool, ArgBool>;
- // [] -> [Integer]
- def Zero : Opcode {
- let Types = [AluTypeClass];
- let HasGroup = 1;
- }
- // [] -> [Pointer]
- def Null : Opcode {
- let Types = [PtrTypeClass];
- }
- //===----------------------------------------------------------------------===//
- // Pointer generation
- //===----------------------------------------------------------------------===//
- // [] -> [Pointer]
- def GetPtrLocal : Opcode {
- // Offset of local.
- let Args = [ArgUint32];
- bit HasCustomEval = 1;
- }
- // [] -> [Pointer]
- def GetPtrParam : Opcode {
- // Offset of parameter.
- let Args = [ArgUint32];
- }
- // [] -> [Pointer]
- def GetPtrGlobal : Opcode {
- // Index of global.
- let Args = [ArgUint32];
- }
- // [Pointer] -> [Pointer]
- def GetPtrField : Opcode {
- // Offset of field.
- let Args = [ArgUint32];
- }
- // [Pointer] -> [Pointer]
- def GetPtrActiveField : Opcode {
- // Offset of field.
- let Args = [ArgUint32];
- }
- // [] -> [Pointer]
- def GetPtrActiveThisField : Opcode {
- // Offset of field.
- let Args = [ArgUint32];
- }
- // [] -> [Pointer]
- def GetPtrThisField : Opcode {
- // Offset of field.
- let Args = [ArgUint32];
- }
- // [Pointer] -> [Pointer]
- def GetPtrBase : Opcode {
- // Offset of field, which is a base.
- let Args = [ArgUint32];
- }
- // [Pointer] -> [Pointer]
- def GetPtrVirtBase : Opcode {
- // RecordDecl of base class.
- let Args = [ArgRecordDecl];
- }
- // [] -> [Pointer]
- def GetPtrThisBase : Opcode {
- // Offset of field, which is a base.
- let Args = [ArgUint32];
- }
- // [] -> [Pointer]
- def GetPtrThisVirtBase : Opcode {
- // RecordDecl of base class.
- let Args = [ArgRecordDecl];
- }
- // [] -> [Pointer]
- def This : Opcode;
- // [] -> [Pointer]
- def RVOPtr : Opcode;
- // [Pointer] -> [Pointer]
- def NarrowPtr : Opcode;
- // [Pointer] -> [Pointer]
- def ExpandPtr : Opcode;
- //===----------------------------------------------------------------------===//
- // Direct field accessors
- //===----------------------------------------------------------------------===//
- class AccessOpcode : Opcode {
- let Types = [AllTypeClass];
- let Args = [ArgUint32];
- let HasGroup = 1;
- }
- class BitFieldOpcode : Opcode {
- let Types = [AluTypeClass];
- let Args = [ArgRecordField];
- let HasGroup = 1;
- }
- // [] -> [Pointer]
- def GetLocal : AccessOpcode { let HasCustomEval = 1; }
- // [] -> [Pointer]
- def SetLocal : AccessOpcode { let HasCustomEval = 1; }
- // [] -> [Value]
- def GetGlobal : AccessOpcode;
- // [Value] -> []
- def InitGlobal : AccessOpcode;
- // [Value] -> []
- def SetGlobal : AccessOpcode;
- // [] -> [Value]
- def GetParam : AccessOpcode;
- // [Value] -> []
- def SetParam : AccessOpcode;
- // [Pointer] -> [Pointer, Value]
- def GetField : AccessOpcode;
- // [Pointer] -> [Value]
- def GetFieldPop : AccessOpcode;
- // [] -> [Value]
- def GetThisField : AccessOpcode;
- // [Pointer, Value] -> [Pointer]
- def SetField : AccessOpcode;
- // [Value] -> []
- def SetThisField : AccessOpcode;
- // [Value] -> []
- def InitThisField : AccessOpcode;
- // [Value] -> []
- def InitThisFieldActive : AccessOpcode;
- // [Value] -> []
- def InitThisBitField : BitFieldOpcode;
- // [Pointer, Value] -> []
- def InitField : AccessOpcode;
- // [Pointer, Value] -> []
- def InitBitField : BitFieldOpcode;
- // [Pointer, Value] -> []
- def InitFieldActive : AccessOpcode;
- //===----------------------------------------------------------------------===//
- // Pointer access
- //===----------------------------------------------------------------------===//
- class LoadOpcode : Opcode {
- let Types = [AllTypeClass];
- let HasGroup = 1;
- }
- // [Pointer] -> [Pointer, Value]
- def Load : LoadOpcode {}
- // [Pointer] -> [Value]
- def LoadPop : LoadOpcode {}
- class StoreOpcode : Opcode {
- let Types = [AllTypeClass];
- let HasGroup = 1;
- }
- class StoreBitFieldOpcode : Opcode {
- let Types = [AluTypeClass];
- let HasGroup = 1;
- }
- // [Pointer, Value] -> [Pointer]
- def Store : StoreOpcode {}
- // [Pointer, Value] -> []
- def StorePop : StoreOpcode {}
- // [Pointer, Value] -> [Pointer]
- def StoreBitField : StoreBitFieldOpcode {}
- // [Pointer, Value] -> []
- def StoreBitFieldPop : StoreBitFieldOpcode {}
- // [Pointer, Value] -> []
- def InitPop : StoreOpcode {}
- // [Pointer, Value] -> [Pointer]
- def InitElem : Opcode {
- let Types = [AllTypeClass];
- let Args = [ArgUint32];
- let HasGroup = 1;
- }
- // [Pointer, Value] -> []
- def InitElemPop : Opcode {
- let Types = [AllTypeClass];
- let Args = [ArgUint32];
- let HasGroup = 1;
- }
- //===----------------------------------------------------------------------===//
- // Pointer arithmetic.
- //===----------------------------------------------------------------------===//
- // [Pointer, Integral] -> [Pointer]
- def AddOffset : AluOpcode;
- // [Pointer, Integral] -> [Pointer]
- def SubOffset : AluOpcode;
- // Pointer, Pointer] - [Integral]
- def SubPtr : Opcode {
- let Types = [IntegerTypeClass];
- let HasGroup = 1;
- }
- //===----------------------------------------------------------------------===//
- // Binary operators.
- //===----------------------------------------------------------------------===//
- // [Real, Real] -> [Real]
- def Sub : AluOpcode;
- def Add : AluOpcode;
- def Mul : AluOpcode;
- def Rem : Opcode {
- let Types = [NumberTypeClass];
- let HasGroup = 1;
- }
- def Shl : Opcode {
- let Types = [IntegerTypeClass, IntegerTypeClass];
- let HasGroup = 1;
- }
- def Shr : Opcode {
- let Types = [IntegerTypeClass, IntegerTypeClass];
- let HasGroup = 1;
- }
- def BitAnd : IntegerOpcode;
- def BitOr : IntegerOpcode;
- def Div : Opcode {
- let Types = [NumberTypeClass];
- let HasGroup = 1;
- }
- def BitXor : IntegerOpcode;
- //===----------------------------------------------------------------------===//
- // Unary operators.
- //===----------------------------------------------------------------------===//
- // [Real] -> [Real]
- def Inv: Opcode {
- let Types = [BoolTypeClass];
- let HasGroup = 1;
- }
- def Inc: IntegerOpcode;
- def IncPop : IntegerOpcode;
- def Dec: IntegerOpcode;
- def DecPop: IntegerOpcode;
- // [Real] -> [Real]
- def Neg: Opcode {
- let Types = [AluTypeClass];
- let HasGroup = 1;
- }
- // [Real] -> [Real]
- def Comp: Opcode {
- let Types = [NumberTypeClass];
- let HasGroup = 1;
- }
- //===----------------------------------------------------------------------===//
- // Cast.
- //===----------------------------------------------------------------------===//
- // TODO: Expand this to handle casts between more types.
- def FromCastTypeClass : TypeClass {
- let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
- }
- def ToCastTypeClass : TypeClass {
- let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
- }
- def Cast: Opcode {
- let Types = [FromCastTypeClass, ToCastTypeClass];
- let HasGroup = 1;
- }
- //===----------------------------------------------------------------------===//
- // Comparison opcodes.
- //===----------------------------------------------------------------------===//
- class EqualityOpcode : Opcode {
- let Types = [AllTypeClass];
- let HasGroup = 1;
- }
- def EQ : EqualityOpcode;
- def NE : EqualityOpcode;
- class ComparisonOpcode : Opcode {
- let Types = [ComparableTypeClass];
- let HasGroup = 1;
- }
- def LT : ComparisonOpcode;
- def LE : ComparisonOpcode;
- def GT : ComparisonOpcode;
- def GE : ComparisonOpcode;
- //===----------------------------------------------------------------------===//
- // Stack management.
- //===----------------------------------------------------------------------===//
- // [Value] -> []
- def Pop : Opcode {
- let Types = [AllTypeClass];
- let HasGroup = 1;
- }
- // [Value] -> [Value, Value]
- def Dup : Opcode {
- let Types = [AllTypeClass];
- let HasGroup = 1;
- }
|