Opcodes.td 13 KB

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