neg_idioms.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "dcc.h"
  2. #include "neg_idioms.h"
  3. using namespace std;
  4. /*****************************************************************************
  5. * idiom11 - Negate long integer
  6. * NEG regH
  7. * NEG regL
  8. * SBB regH, 0
  9. * Eg: NEG dx
  10. * NEG ax
  11. * SBB dx, 0
  12. * => dx:ax = - dx:ax
  13. * Found in Borland Turbo C.
  14. ****************************************************************************/
  15. bool Idiom11::match (iICODE picode)
  16. {
  17. const char *matchstring="(oNEG rH) (oNEG rL) (SBB \rH i0)";
  18. condId type; /* type of argument */
  19. if(distance(picode,m_end)<3)
  20. return false;
  21. for(int i=0; i<3; ++i)
  22. m_icodes[i]=picode++;
  23. type = m_icodes[0]->ll()->idType(DST);
  24. if(type==CONSTANT || type == OTHER)
  25. return false;
  26. /* Check NEG reg/mem
  27. * SBB reg/mem, 0*/
  28. if (not m_icodes[1]->ll()->match(iNEG) or not m_icodes[2]->ll()->match(iSBB))
  29. return false;
  30. switch (type)
  31. {
  32. case GLOB_VAR:
  33. if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) &&
  34. (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off))
  35. return true;
  36. break;
  37. case REGISTER:
  38. if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi)
  39. return true;
  40. break;
  41. case PARAM:
  42. case LOCAL_VAR:
  43. if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)
  44. return true;
  45. break;
  46. }
  47. return false;
  48. }
  49. int Idiom11::action()
  50. {
  51. COND_EXPR *lhs,*rhs;
  52. lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
  53. rhs = COND_EXPR::unary (NEGATION, lhs);
  54. m_icodes[0]->setAsgn(lhs, rhs);
  55. m_icodes[1]->invalidate();
  56. m_icodes[2]->invalidate();
  57. return 3;
  58. }
  59. /*****************************************************************************
  60. * idiom 16: Bitwise negation
  61. * NEG reg
  62. * SBB reg, reg
  63. * INC reg
  64. * => ASGN reg, !reg
  65. * Eg: NEG ax
  66. * SBB ax, ax
  67. * INC ax
  68. * => ax = !ax
  69. * Found in Borland Turbo C when negating bitwise.
  70. ****************************************************************************/
  71. bool Idiom16::match (iICODE picode)
  72. {
  73. const char *matchstring="(oNEG rR) (oSBB rR rR) (oINC rR)";
  74. if(distance(picode,m_end)<3)
  75. return false;
  76. for(int i=0; i<3; ++i)
  77. m_icodes[i]=picode++;
  78. uint8_t regi = m_icodes[0]->ll()->dst.regi;
  79. if ((regi >= rAX) && (regi < INDEX_BX_SI))
  80. {
  81. if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
  82. if ((m_icodes[1]->ll()->dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
  83. m_icodes[1]->ll()->match((eReg)regi) &&
  84. m_icodes[2]->ll()->match((eReg)regi))
  85. return true;
  86. }
  87. return false;
  88. }
  89. int Idiom16::action()
  90. {
  91. COND_EXPR *lhs,*rhs;
  92. lhs = COND_EXPR::idReg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
  93. rhs = COND_EXPR::unary (NEGATION, lhs->clone());
  94. m_icodes[0]->setAsgn(lhs, rhs);
  95. m_icodes[1]->invalidate();
  96. m_icodes[2]->invalidate();
  97. return 3;
  98. }