instruction.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. #include "instruction.h"
  22. #include "decompiler_codegen.h"
  23. #include "decompiler_engine.h"
  24. bool outputStackEffect = true;
  25. void setOutputStackEffect(bool value) {
  26. outputStackEffect = value;
  27. }
  28. bool Instruction::isJump() const {
  29. return isCondJump() || isUncondJump();
  30. }
  31. bool Instruction::isCondJump() const {
  32. return false;
  33. }
  34. bool Instruction::isUncondJump() const {
  35. return false;
  36. }
  37. bool Instruction::isStackOp() const {
  38. return false;
  39. }
  40. bool Instruction::isFuncCall() const {
  41. return false;
  42. }
  43. bool Instruction::isReturn() const {
  44. return false;
  45. }
  46. bool Instruction::isKernelCall() const {
  47. return false;
  48. }
  49. bool Instruction::isLoad() const {
  50. return false;
  51. }
  52. bool Instruction::isStore() const {
  53. return false;
  54. }
  55. uint32 Instruction::getDestAddress() const {
  56. throw WrongTypeException();
  57. }
  58. std::ostream &Instruction::print(std::ostream &output) const {
  59. output << boost::format("%08x: %s") % _address % _name;
  60. std::vector<ValuePtr>::const_iterator param;
  61. for (param = _params.begin(); param != _params.end(); ++param) {
  62. if (param != _params.begin())
  63. output << ",";
  64. output << " " << *param;
  65. }
  66. if (outputStackEffect)
  67. output << boost::format(" (%d)") % _stackChange;
  68. return output;
  69. }
  70. bool CondJumpInstruction::isCondJump() const {
  71. return true;
  72. }
  73. bool UncondJumpInstruction::isUncondJump() const {
  74. return true;
  75. }
  76. void UncondJumpInstruction::processInst(Function&, ValueStack&, Engine*, CodeGenerator*) {
  77. }
  78. bool StackInstruction::isStackOp() const {
  79. return true;
  80. }
  81. bool CallInstruction::isFuncCall() const {
  82. return true;
  83. }
  84. bool LoadInstruction::isLoad() const {
  85. return true;
  86. }
  87. bool StoreInstruction::isStore() const {
  88. return true;
  89. }
  90. void DupStackInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator *codeGen) {
  91. std::stringstream s;
  92. ValuePtr p = stack.pop()->dup(s);
  93. if (s.str().length() > 0)
  94. codeGen->addOutputLine(s.str());
  95. stack.push(p);
  96. stack.push(p);
  97. }
  98. void BoolNegateStackInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator*) {
  99. stack.push(stack.pop()->negate());
  100. }
  101. void BinaryOpStackInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator *codeGen) {
  102. ValuePtr op1 = stack.pop();
  103. ValuePtr op2 = stack.pop();
  104. if (codeGen->_binOrder == kFIFOArgOrder)
  105. stack.push(new BinaryOpValue(op2, op1, _codeGenData));
  106. else if (codeGen->_binOrder == kLIFOArgOrder)
  107. stack.push(new BinaryOpValue(op1, op2, _codeGenData));
  108. }
  109. bool ReturnInstruction::isReturn() const {
  110. return true;
  111. }
  112. void ReturnInstruction::processInst(Function&, ValueStack&, Engine*, CodeGenerator *codeGen) {
  113. codeGen->addOutputLine("return;");
  114. }
  115. void UnaryOpPrefixStackInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator*) {
  116. stack.push(new UnaryOpValue(stack.pop(), _codeGenData, false));
  117. }
  118. void UnaryOpPostfixStackInstruction::processInst(Function& , ValueStack &stack, Engine*, CodeGenerator*) {
  119. stack.push(new UnaryOpValue(stack.pop(), _codeGenData, true));
  120. }
  121. void KernelCallStackInstruction::processInst(Function&, ValueStack &stack, Engine*, CodeGenerator *codeGen) {
  122. codeGen->_argList.clear();
  123. bool returnsValue = (_codeGenData.find("r") == 0);
  124. std::string metadata = (!returnsValue ? _codeGenData : _codeGenData.substr(1));
  125. for (size_t i = 0; i < metadata.length(); i++)
  126. codeGen->processSpecialMetadata(this, metadata[i], i);
  127. stack.push(new CallValue(_name, codeGen->_argList));
  128. if (!returnsValue) {
  129. std::stringstream stream;
  130. stream << stack.pop() << ";";
  131. codeGen->addOutputLine(stream.str());
  132. }
  133. }
  134. bool KernelCallInstruction::isKernelCall() const {
  135. return true;
  136. }