neg_idioms.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. default:
  47. fprintf(stderr,"Idiom11::match unhandled type %d\n",type);
  48. }
  49. return false;
  50. }
  51. int Idiom11::action()
  52. {
  53. COND_EXPR *lhs,*rhs;
  54. lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
  55. rhs = COND_EXPR::unary (NEGATION, lhs);
  56. m_icodes[0]->setAsgn(lhs, rhs);
  57. m_icodes[1]->invalidate();
  58. m_icodes[2]->invalidate();
  59. return 3;
  60. }
  61. /*****************************************************************************
  62. * idiom 16: Bitwise negation
  63. * NEG reg
  64. * SBB reg, reg
  65. * INC reg
  66. * => ASGN reg, !reg
  67. * Eg: NEG ax
  68. * SBB ax, ax
  69. * INC ax
  70. * => ax = !ax
  71. * Found in Borland Turbo C when negating bitwise.
  72. ****************************************************************************/
  73. bool Idiom16::match (iICODE picode)
  74. {
  75. //const char *matchstring="(oNEG rR) (oSBB rR rR) (oINC rR)";
  76. if(distance(picode,m_end)<3)
  77. return false;
  78. for(int i=0; i<3; ++i)
  79. m_icodes[i]=picode++;
  80. uint8_t regi = m_icodes[0]->ll()->dst.regi;
  81. if ((regi >= rAX) && (regi < INDEX_BX_SI))
  82. {
  83. if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
  84. if ((m_icodes[1]->ll()->dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
  85. m_icodes[1]->ll()->match((eReg)regi) &&
  86. m_icodes[2]->ll()->match((eReg)regi))
  87. return true;
  88. }
  89. return false;
  90. }
  91. int Idiom16::action()
  92. {
  93. COND_EXPR *lhs,*rhs;
  94. lhs = COND_EXPR::idReg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
  95. rhs = COND_EXPR::unary (NEGATION, lhs->clone());
  96. m_icodes[0]->setAsgn(lhs, rhs);
  97. m_icodes[1]->invalidate();
  98. m_icodes[2]->invalidate();
  99. return 3;
  100. }