mov_idioms.cpp 3.4 KB

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