instruction.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /* ScummVM Tools
  2. *
  3. * ScummVM Tools is the legal property of its developers, whose
  4. * names are too numerous to list here. Please refer to the
  5. * COPYRIGHT file distributed with this source distribution.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. */
  21. #ifndef DEC_INSTRUCTION_H
  22. #define DEC_INSTRUCTION_H
  23. #include <string>
  24. #include <vector>
  25. #include <boost/format.hpp>
  26. #include <boost/intrusive_ptr.hpp>
  27. #include "common/scummsys.h"
  28. #include "refcounted.h"
  29. #include "value.h"
  30. #include "wrongtype.h"
  31. class CodeGenerator;
  32. class Engine;
  33. /**
  34. * Changes whether or not to output the stack effect for an instruction.
  35. */
  36. void setOutputStackEffect(bool value);
  37. /**
  38. * Constants for categorizing the different kinds of instructions.
  39. */
  40. const int kBinaryOpInst = 0; ///< Binary operation (e.g. +, &&, etc.), including comparisons.
  41. const int kBoolNegateInst = 1; ///< Boolean negation.
  42. const int kCallInst = 2; ///< Regular function call.
  43. const int kCondJumpInst = 3; ///< Conditional jump.
  44. const int kDupInst = 4; ///< Instruction duplicates the most recent stack entry.
  45. const int kJumpInst = 5; ///< Unconditional jump.
  46. const int kKernelCallInst = 6; ///< Kernel functions.
  47. const int kLoadInst = 7; ///< Load value from memory.
  48. const int kReturnInst = 8; ///< Return from regular function call.
  49. const int kStackInst = 9; ///< Stack allocation or deallocation (altering stack pointer)
  50. const int kStoreInst = 10; ///< Store value in memory.
  51. const int kUnaryOpPreInst = 11; ///< Unary operation (e.g. !) with operator placed before the operator.
  52. const int kUnaryOpPostInst = 12; ///< Unary operation with operator placed after the operator.
  53. const int kFirstCustomInst = kUnaryOpPostInst + 1; ///< First unused key. Add your custom type keys starting with this value.
  54. struct Instruction;
  55. /**
  56. * Pointer to an Instruction.
  57. */
  58. typedef boost::intrusive_ptr<Instruction> InstPtr;
  59. class Function;
  60. /**
  61. * Structure for representing an instruction.
  62. */
  63. struct Instruction : public RefCounted {
  64. public:
  65. uint32 _opcode; ///< The instruction opcode.
  66. uint32 _address; ///< The instruction address.
  67. std::string _name; ///< The instruction name (opcode name).
  68. int16 _stackChange; ///< How much this instruction changes the stack pointer by.
  69. std::vector<ValuePtr> _params; ///< Array of parameters used for the instruction.
  70. std::string _codeGenData; ///< String containing metadata for code generation. See the extended documentation for details.
  71. bool mLabelRequired = false;
  72. /**
  73. * Writes a comment to the script indicating an unimplemented opcode.
  74. *
  75. * @param code_gen[in|out] Code generator. The line will be added to it
  76. * @param owner[in] The name of the class. Unused.
  77. * @param instructions[in] The name of the instruction.
  78. */
  79. static void WriteTodo(CodeGenerator *code_gen, std::string owner, std::string opcode);
  80. /**
  81. * Operator overload to output an Instruction to a std::ostream.
  82. *
  83. * @param output The std::ostream to output to.
  84. * @param inst The Instruction to output.
  85. * @return The std::ostream used for output.
  86. */
  87. friend std::ostream &operator<<(std::ostream &output, const Instruction *inst) {
  88. return inst->Print(output);
  89. }
  90. /**
  91. * Print the instruction to an std::ostream.
  92. *
  93. * @param output The std::ostream to write to.
  94. * @return The std::ostream used for output.
  95. */
  96. virtual std::ostream &Print(std::ostream &output) const;
  97. /**
  98. * Returns whether or not the instruction is a jump of some sort.
  99. *
  100. * @return True if the instruction is a jump, otherwise false.
  101. */
  102. virtual bool isJump() const;
  103. /**
  104. * Returns whether or not the instruction is a conditional jump.
  105. *
  106. * @return True if the instruction is a conditional jump, otherwise false.
  107. */
  108. virtual bool isCondJump() const;
  109. /**
  110. * Returns whether or not the instruction is an unconditional jump.
  111. *
  112. * @return True if the instruction is an unconditional jump, otherwise false.
  113. */
  114. virtual bool IsUncondJump() const;
  115. /**
  116. * Returns whether or not the instruction is a stack operation.
  117. *
  118. * @return True if the instruction is a stack operation, otherwise false.
  119. */
  120. virtual bool isStackOp() const;
  121. /**
  122. * Returns whether or not the instruction is a call to a script function.
  123. *
  124. * @return True if the instruction is a script function call, otherwise false.
  125. */
  126. virtual bool IsFuncCall() const;
  127. /**
  128. * Returns whether or not the instruction is a return statement.
  129. *
  130. * @return True if the instruction is a return statement, otherwise false.
  131. */
  132. virtual bool isReturn() const;
  133. /**
  134. * Returns whether or not the instruction is a call to a kernel function.
  135. *
  136. * @return True if the instruction is a kernel function call, otherwise false.
  137. */
  138. virtual bool isKernelCall() const;
  139. /**
  140. * Returns whether or not the instruction is a load operation.
  141. *
  142. * @return True if the instruction is a load operation, otherwise false.
  143. */
  144. virtual bool isLoad() const;
  145. /**
  146. * Returns whether or not the instruction is a store operation.
  147. *
  148. * @return True if the instruction is a store operation, otherwise false.
  149. */
  150. virtual bool isStore() const;
  151. /**
  152. * Returns the destination address of a jump instruction.
  153. *
  154. * @return Destination address of a jump instruction.
  155. * @throws WrongTypeException if instruction is not a jump.
  156. */
  157. virtual uint32 GetDestAddress() const;
  158. /**
  159. * Process an instruction for code generation.
  160. *
  161. * @param stack The current stack.
  162. * @param engine Pointer to the Engine used for code generation.
  163. * @param codeGen Pointer to the CodeGenerator used for code generation.
  164. */
  165. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) = 0;
  166. };
  167. /**
  168. * Instruction performing a jump.
  169. */
  170. struct JumpInstruction : public Instruction {
  171. };
  172. /**
  173. * Instruction performing a conditional jump.
  174. */
  175. struct CondJumpInstruction : public JumpInstruction {
  176. public:
  177. virtual bool isCondJump() const;
  178. };
  179. /**
  180. * Instruction performing an unconditional jump.
  181. */
  182. struct UncondJumpInstruction : public JumpInstruction {
  183. public:
  184. virtual bool IsUncondJump() const override;
  185. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  186. };
  187. /**
  188. * Instruction performing a stack operation.
  189. */
  190. struct StackInstruction : public Instruction {
  191. public:
  192. virtual bool isStackOp() const;
  193. };
  194. /**
  195. * Instruction performing a script function call.
  196. */
  197. struct CallInstruction : public Instruction {
  198. public:
  199. virtual bool IsFuncCall() const;
  200. };
  201. /**
  202. * Instruction which loads data from memory.
  203. */
  204. struct LoadInstruction : public Instruction {
  205. public:
  206. virtual bool isLoad() const;
  207. };
  208. /**
  209. * Instruction which stores data to memory.
  210. */
  211. struct StoreInstruction : public Instruction {
  212. public:
  213. virtual bool isStore() const;
  214. };
  215. /**
  216. * Instruction duplicating the topmost stack value.
  217. */
  218. struct DupInstruction : public Instruction {
  219. };
  220. /**
  221. * Instruction performing boolean negation.
  222. */
  223. struct BoolNegateInstruction : public Instruction {
  224. };
  225. /**
  226. * Instruction performing a binary operation.
  227. */
  228. struct BinaryOpInstruction : public Instruction {
  229. };
  230. /**
  231. * Instruction performing a unary operation.
  232. */
  233. struct UnaryOpInstruction : public Instruction {
  234. };
  235. /**
  236. * Instruction performing a kernel function call.
  237. */
  238. struct KernelCallInstruction : public Instruction {
  239. public:
  240. virtual bool isKernelCall() const;
  241. };
  242. /**
  243. * Default implementation for stack-based instruction duplicating the topmost stack value.
  244. */
  245. struct DupStackInstruction : public DupInstruction {
  246. public:
  247. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  248. };
  249. /**
  250. * Default implementation for stack-based instruction performing boolean negation.
  251. */
  252. struct BoolNegateStackInstruction : public BoolNegateInstruction {
  253. public:
  254. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  255. };
  256. /**
  257. * Default implementation for stack-based instruction performing a binary operation.
  258. */
  259. struct BinaryOpStackInstruction : public BinaryOpInstruction {
  260. public:
  261. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  262. };
  263. /**
  264. * Instruction which returns from a function.
  265. */
  266. struct ReturnInstruction : public Instruction {
  267. public:
  268. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  269. virtual bool isReturn() const;
  270. };
  271. /**
  272. * Default implementation for stack-based instruction performing a unary operation, with a prefixed operator.
  273. */
  274. struct UnaryOpPrefixStackInstruction : public UnaryOpInstruction {
  275. public:
  276. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  277. };
  278. /**
  279. * Default implementation for stack-based instruction performing a unary operation, with a postfixed operator.
  280. */
  281. struct UnaryOpPostfixStackInstruction : public UnaryOpInstruction {
  282. public:
  283. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  284. };
  285. /**
  286. * Default implementation for stack-based instruction performing a kernel function call.
  287. */
  288. struct KernelCallStackInstruction : public Instruction {
  289. public:
  290. virtual void ProcessInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  291. };
  292. /**
  293. * Type representing a vector of InstPtrs.
  294. */
  295. typedef std::vector<InstPtr> InstVec;
  296. /**
  297. * Type representing an iterator over InstPtrs.
  298. */
  299. typedef InstVec::iterator InstIterator;
  300. /**
  301. * Type representing a const_iterator over InstPtrs.
  302. */
  303. typedef InstVec::const_iterator ConstInstIterator;
  304. #endif