neg_idioms.cpp 3.3 KB

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