neg_idioms.cpp 3.3 KB

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