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