simple_disassembler.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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_SIMPLE_DISASSEMBLER_H
  22. #define DEC_SIMPLE_DISASSEMBLER_H
  23. #include "decompiler_disassembler.h"
  24. /**
  25. * Simple disassembler acting as a base for instruction sets only consisting of simple instructions (opcode params...).
  26. */
  27. class SimpleDisassembler : public Disassembler {
  28. protected:
  29. uint32 address_; ///< Variable to maintain the current address.
  30. /**
  31. * Read parameters and associate them with an instruction.
  32. *
  33. * @param inst The instruction to associate the parameters with.
  34. * @param typeString NUL-terminated string describing the type of each parameter.
  35. */
  36. void readParams(InstPtr inst, const char *typeString);
  37. void readParams(InstPtr inst, const char *typeString, const std::vector<std::string>& params);
  38. /**
  39. * Reads data for a single parameter.
  40. *
  41. * @param inst The instruction the parameter will belong to. Used for reference in parameter reading.
  42. * @param type Character describing the type of the parameter.
  43. * @return The read data as a ValuePtr.
  44. */
  45. virtual ValuePtr readParameter(InstPtr inst, std::string type);
  46. public:
  47. /**
  48. * Constructor for SimpleDisassembler.
  49. *
  50. * @param insts Reference to the vector in which disassembled instructions should be placed.
  51. */
  52. SimpleDisassembler(InstVec &insts);
  53. };
  54. #define INC_ADDR this->address_++;
  55. #define ADD_INST(category) this->insts_.push_back(new category());
  56. #define LAST_INST (this->insts_.back())
  57. #define START_OPCODES \
  58. this->address_ = this->address_base_; \
  59. while (this->stream_->Position() != (unsigned int)this->stream_->Size()) { \
  60. uint32 full_opcode = 0; \
  61. uint8 opcode = this->stream_->ReadU8(); \
  62. std::string opcodePrefix; \
  63. switch (opcode) {
  64. #define END_OPCODES \
  65. default: \
  66. throw UnknownOpcodeException(this->address_, opcode);\
  67. } \
  68. INC_ADDR; \
  69. }
  70. #define OPCODE_BASE(val) \
  71. case val: \
  72. full_opcode = (full_opcode << 8) + val;
  73. #define OPCODE_END break;
  74. #define OPCODE_BODY(name, category, stackChange, params, codeGenData) \
  75. ADD_INST(category); \
  76. LAST_INST->_opcode = full_opcode; \
  77. LAST_INST->_address = this->address_; \
  78. LAST_INST->_stackChange = stackChange; \
  79. LAST_INST->_name = opcodePrefix + std::string(name); \
  80. LAST_INST->_codeGenData = codeGenData; \
  81. this->readParams(LAST_INST, params); \
  82. #define OPCODE_MD(val, name, category, stackChange, params, codeGenData) \
  83. OPCODE_BASE(val)\
  84. OPCODE_BODY(name, category, stackChange, params, codeGenData)\
  85. OPCODE_END;
  86. #define OPCODE(val, name, category, stackChange, params) \
  87. OPCODE_MD(val, name, category, stackChange, params, "")
  88. #define START_SUBOPCODE_WITH_PREFIX(val,prefix) \
  89. OPCODE_BASE(val) \
  90. opcodePrefix = prefix + std::string("."); \
  91. opcode = this->stream_->ReadU8(); \
  92. switch (opcode) {
  93. #define START_SUBOPCODE(val) \
  94. OPCODE_BASE(val) \
  95. opcode = this->stream_->ReadU8(); \
  96. switch (opcode) {
  97. #define END_SUBOPCODE \
  98. default: \
  99. throw UnknownSubOpcodeException(this->address_, opcode);\
  100. } \
  101. INC_ADDR; \
  102. OPCODE_END;
  103. #endif