machine_x86.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "machine_x86.h"
  2. #include "msvc_fixes.h"
  3. #include "icode.h"
  4. #include <QtCore/QTextStream>
  5. #include <cassert>
  6. // Index registers **** temp solution
  7. static const QString regNames[] = {
  8. "undef",
  9. "ax", "cx", "dx", "bx",
  10. "sp", "bp", "si", "di",
  11. "es", "cs", "ss", "ds",
  12. "al", "cl", "dl", "bl",
  13. "ah", "ch", "dh", "bh",
  14. "tmp","tmp2",
  15. "bx+si", "bx+di", "bp+si", "bp+di",
  16. "si", "di", "bp", "bx"
  17. };
  18. /* uint8_t and uint16_t registers */
  19. Machine_X86::Machine_X86()
  20. {
  21. static_assert((sizeof(regNames)/sizeof(QString))==LAST_REG,
  22. "Reg count not equal number of strings");
  23. }
  24. const QString &Machine_X86::regName(eReg r)
  25. {
  26. assert(r<(sizeof(regNames)/sizeof(QString)));
  27. return regNames[r];
  28. }
  29. static const QString szOps[] =
  30. {
  31. "CBW", "AAA", "AAD", "AAM", "AAS", "ADC", "ADD", "AND",
  32. "BOUND","CALL", "CALL", "CLC", "CLD", "CLI", "CMC", "CMP",
  33. "CMPS", "REPNE CMPS","REPE CMPS","DAA", "DAS", "DEC", "DIV", "ENTER",
  34. "ESC", "HLT", "IDIV", "IMUL", "IN", "INC", "INS", "REP INS",
  35. "INT", "IRET", "JB", "JBE", "JAE", "JA", "JE", "JNE",
  36. "JL", "JGE", "JLE", "JG", "JS", "JNS", "JO", "JNO",
  37. "JP", "JNP", "JCXZ", "JMP", "JMP", "LAHF", "LDS", "LEA",
  38. "LEAVE","LES", "LOCK", "LODS", "REP LODS", "LOOP", "LOOPE","LOOPNE",
  39. "MOV", "MOVS", "REP MOVS", "MUL", "NEG", "NOT", "OR", "OUT",
  40. "OUTS", "REP OUTS", "POP", "POPA", "POPF", "PUSH", "PUSHA","PUSHF",
  41. "RCL", "RCR", "ROL", "ROR", "RET", "RETF", "SAHF", "SAR",
  42. "SHL", "SHR", "SBB", "SCAS", "REPNE SCAS","REPE SCAS", "CWD", "STC",
  43. "STD", "STI", "STOS", "REP STOS", "SUB", "TEST", "WAIT", "XCHG",
  44. "XLAT", "XOR", "INTO", "NOP", "REPNE", "REPE", "MOD"
  45. };
  46. /* The following opcodes are for mod != 3 */
  47. static const QString szFlops1[] =
  48. {
  49. /* 0 1 2 3 4 5 6 7 */
  50. "FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
  51. "FLD", "???", "FST", "???", "FLDENV","FLDCW", "FSTENV","FSTSW", /* 08 */
  52. "FIADD", "FIMUL", "FICOM","FICOMP","FISUB", "FISUBR","FIDIV", "FIDIVR", /* 10 */
  53. "FILD", "???", "FIST", "FISTP", "???", "???", "???", "FSTP", /* 18 */
  54. "FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 20 */
  55. "FLD", "FLD", "FST", "FSTP", "FRESTOR","???", "FSAVE", "FSTSW", /* 28 */
  56. "FIADD", "FIMUL", "FICOM","FICOMP","FISUB", "FISUBR","FIDIV", "FIDIVR", /* 30 */
  57. "FILD", "???", "FIST", "FISTP", "FBLD", "???", "FBSTP", "FISTP" /* 38 */
  58. };
  59. /* The following opcodes are for mod == 3 */
  60. static const QString szFlops2[] =
  61. {
  62. /* 0 1 2 3 4 5 6 7 */
  63. "FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
  64. "FLD", "FXCH", "FNOP", "???", "", "", "", "", /* 08 */
  65. "FIADD", "FIMUL", "FICOM","FICOMP","FISUB", "", "FIDIV", "FIDIVR", /* 10 */
  66. "FILD", "???", "FIST", "FISTP", "???", "???", "???", "FSTP", /* 18 */
  67. "FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 20 */
  68. "FFREE", "FSTP", "FST", "???", "FUCOM", "FUCOMP","???", "???", /* 28 */
  69. "FADDP", "FMULP", "FICOM","", "FSUBRP","FISUBR","FDIVRP","FDIVP", /* 30 */
  70. "FILD", "???", "FIST", "FISTP", "", "???", "FBSTP", "FISTP" /* 38 */
  71. };
  72. const QString &Machine_X86::opcodeName(unsigned r)
  73. {
  74. assert(r<(sizeof(szOps)/sizeof(QString)));
  75. return szOps[r];
  76. }
  77. const QString &Machine_X86::floatOpName(unsigned r)
  78. {
  79. if(r>=(sizeof(szFlops1)/sizeof(QString)))
  80. {
  81. r-= (sizeof(szFlops1)/sizeof(QString));
  82. assert(r<(sizeof(szFlops2)/sizeof(QString)));
  83. return szFlops2[r];
  84. }
  85. return szFlops1[r];
  86. }
  87. bool Machine_X86::physicalReg(eReg r)
  88. {
  89. return (r>=rAX) and (r<rTMP);
  90. }
  91. bool Machine_X86::isMemOff(eReg r)
  92. {
  93. return r == 0 or r >= INDEX_BX_SI;
  94. }
  95. //TODO: Move these to Machine_X86
  96. eReg Machine_X86::subRegH(eReg reg)
  97. {
  98. return eReg((int)reg + (int)rAH-(int)rAX);
  99. }
  100. eReg Machine_X86::subRegL(eReg reg)
  101. {
  102. return eReg((int)reg + (int)rAL-(int)rAX);
  103. }
  104. bool Machine_X86::isSubRegisterOf(eReg reg,eReg parent)
  105. {
  106. if ((parent < rAX) or (parent > rBX))
  107. return false; // only AX -> BX are coverede by subregisters
  108. return ((reg==subRegH(parent)) or (reg == subRegL(parent)));
  109. }
  110. bool Machine_X86::hasSubregisters(eReg reg)
  111. {
  112. return ((reg >= rAX) and (reg <= rBX));
  113. }
  114. bool Machine_X86::isPartOfComposite(eReg reg)
  115. {
  116. return ((reg >= rAL) and (reg <= rBH));
  117. }
  118. eReg Machine_X86::compositeParent(eReg reg)
  119. {
  120. switch(reg)
  121. {
  122. case rAL: case rAH: return rAX;
  123. case rCL: case rCH: return rCX;
  124. case rDL: case rDH: return rDX;
  125. case rBL: case rBH: return rBX;
  126. default:
  127. return rUNDEF;
  128. }
  129. return rUNDEF;
  130. }
  131. void Machine_X86::writeRegVector (QTextStream &ostr,const LivenessSet &regi)
  132. {
  133. int j;
  134. for (j = rAX; j < INDEX_BX_SI; j++)
  135. {
  136. if (regi.testReg(j))
  137. ostr << regName(eReg(j))<<" ";
  138. }
  139. }