mov_idioms.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include "mov_idioms.h"
  2. #include "dcc.h"
  3. #include "msvc_fixes.h"
  4. using namespace std;
  5. /*****************************************************************************
  6. * idiom 14 - Long uint16_t assign
  7. * MOV regL, mem/reg
  8. * XOR regH, regH
  9. * Eg: MOV ax, di
  10. * XOR dx, dx
  11. * => MOV dx:ax, di
  12. * Note: only the following combinations are allowed:
  13. * dx:ax
  14. * cx:bx
  15. * this is to remove the possibility of making errors in situations
  16. * like this:
  17. * MOV dx, offH
  18. * MOV ax, offL
  19. * XOR cx, cx
  20. * Found in Borland Turbo C, used for division of unsigned integer
  21. * operands.
  22. ****************************************************************************/
  23. bool Idiom14::match(iICODE pIcode)
  24. {
  25. if(distance(pIcode,m_end)<2)
  26. return false;
  27. m_icodes[0]=pIcode++;
  28. m_icodes[1]=pIcode++;
  29. LLInst * matched [] {m_icodes[0]->ll(),m_icodes[1]->ll()};
  30. /* Check for regL */
  31. m_regL = matched[0]->m_dst.regi;
  32. if (not matched[0]->testFlags(I) and ((m_regL == rAX) or (m_regL ==rBX)))
  33. {
  34. /* Check for XOR regH, regH */
  35. if (matched[1]->match(iXOR) and not matched[1]->testFlags(I))
  36. {
  37. m_regH = matched[1]->m_dst.regi;
  38. if (m_regH == matched[1]->src().getReg2())
  39. {
  40. if ((m_regL == rAX) and (m_regH == rDX))
  41. return true;
  42. if ((m_regL == rBX) and (m_regH == rCX))
  43. return true;
  44. }
  45. }
  46. }
  47. return false;
  48. }
  49. int Idiom14::action()
  50. {
  51. int idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(m_regH,m_regL), m_icodes[0]);
  52. AstIdent *lhs = AstIdent::LongIdx (idx);
  53. m_icodes[0]->setRegDU( m_regH, eDEF);
  54. Expr *rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
  55. m_icodes[0]->setAsgn(lhs, rhs);
  56. m_icodes[1]->invalidate();
  57. return 2;
  58. }
  59. /*****************************************************************************
  60. * idiom 13 - uint16_t assign
  61. * MOV regL, mem
  62. * MOV regH, 0
  63. * Eg: MOV al, [bp-2]
  64. * MOV ah, 0
  65. * => MOV ax, [bp-2]
  66. * Found in Borland Turbo C, used for multiplication and division of
  67. * uint8_t operands (ie. they need to be extended to words).
  68. ****************************************************************************/
  69. bool Idiom13::match(iICODE pIcode)
  70. {
  71. if(distance(pIcode,m_end)<2)
  72. return false;
  73. m_icodes[0]=pIcode++;
  74. m_icodes[1]=pIcode++;
  75. m_loaded_reg = rUNDEF;
  76. eReg regi;
  77. /* Check for regL */
  78. regi = m_icodes[0]->ll()->m_dst.regi;
  79. if (not m_icodes[0]->ll()->testFlags(I) and (regi >= rAL) and (regi <= rBH))
  80. {
  81. /* Check for MOV regH, 0 */
  82. if (m_icodes[1]->ll()->match(iMOV,I) and (m_icodes[1]->ll()->src().getImm2() == 0))
  83. {
  84. if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
  85. {
  86. m_loaded_reg=(eReg)(regi - rAL + rAX);
  87. return true;
  88. }
  89. }
  90. }
  91. return false;
  92. }
  93. int Idiom13::action()
  94. {
  95. AstIdent *lhs;
  96. Expr *rhs;
  97. eReg regi = m_icodes[0]->ll()->m_dst.regi;
  98. m_icodes[0]->du1.removeDef(regi);
  99. //m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
  100. lhs = new RegisterNode(LLOperand(m_loaded_reg, 0), &m_func->localId);
  101. m_icodes[0]->setRegDU( m_loaded_reg, eDEF);
  102. rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
  103. m_icodes[0]->setAsgn(lhs, rhs);
  104. m_icodes[1]->invalidate();
  105. return 2;
  106. }