xor_idioms.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "dcc.h"
  2. #include "xor_idioms.h"
  3. using namespace std;
  4. /*****************************************************************************
  5. * idiom21 - Assign long kte with high part zero
  6. * XOR regH, regH
  7. * MOV regL, kte
  8. * => regH:regL = kte
  9. * Eg: XOR dx, dx
  10. * MOV ax, 3
  11. * => dx:ax = 3
  12. * Note: only the following valid combinations are available:
  13. * dx:ax
  14. * cx:bx
  15. * Found in Borland Turbo C code.
  16. ****************************************************************************/
  17. bool Idiom21::match (iICODE picode)
  18. {
  19. LLOperand *dst, *src;
  20. if(distance(picode,m_end)<2)
  21. return false;
  22. m_icodes[0]=picode++;
  23. m_icodes[1]=picode++;
  24. if (not m_icodes[1]->ll()->testFlags(I))
  25. return false;
  26. dst = &m_icodes[0]->ll()->dst;
  27. src = &m_icodes[0]->ll()->src();
  28. if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
  29. {
  30. if ((dst->getReg2() == rDX) && m_icodes[1]->ll()->match(rAX))
  31. return true;
  32. if ((dst->getReg2() == rCX) && m_icodes[1]->ll()->match(rBX))
  33. return true;
  34. }
  35. return false;
  36. }
  37. int Idiom21::action()
  38. {
  39. Expr *rhs;
  40. AstIdent *lhs;
  41. lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
  42. rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
  43. m_icodes[0]->setAsgn(lhs, rhs);
  44. m_icodes[0]->du.use = 0; /* clear register used in iXOR */
  45. m_icodes[1]->invalidate();
  46. return 2;
  47. }
  48. /*****************************************************************************
  49. * idiom7 - Assign zero
  50. * XOR reg/stackOff, reg/stackOff
  51. * Eg: XOR ax, ax
  52. * => ax = 0
  53. * Found in Borland Turbo C and Microsoft C code.
  54. ****************************************************************************/
  55. bool Idiom7::match(iICODE picode)
  56. {
  57. if(picode==m_end)
  58. return false;
  59. const LLOperand *dst, *src;
  60. m_icode=picode;
  61. dst = &picode->ll()->dst;
  62. src = &picode->ll()->src();
  63. if (dst->regi == 0) /* global variable */
  64. {
  65. if ((dst->segValue == src->segValue) && (dst->off == src->off))
  66. return true;
  67. }
  68. else if (dst->regi < INDEX_BX_SI) /* register */
  69. {
  70. if (dst->regi == src->regi)
  71. return true;
  72. }
  73. else if ((dst->off) && (dst->seg == rSS) && (dst->regi == INDEX_BP)) /* offset from BP */
  74. {
  75. if ((dst->off == src->off) && (dst->seg == src->seg) && (dst->regi == src->regi))
  76. return true;
  77. }
  78. return false;
  79. }
  80. int Idiom7::action()
  81. {
  82. Expr *lhs;
  83. lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
  84. m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
  85. m_icode->du.use = 0; /* clear register used in iXOR */
  86. m_icode->ll()->setFlags(I);
  87. return 1;
  88. }
  89. /*****************************************************************************
  90. * idiom10 - Jump if not equal to 0
  91. * OR reg, reg
  92. * JNE labX
  93. * Eg: OR ax, ax
  94. * JNE labX
  95. * => CMP reg 0
  96. * JNE labX
  97. * This instruction is NOT converted into the equivalent high-level
  98. * instruction "HLI_JCOND (reg != 0) labX" because we do not know yet if
  99. * it forms part of a long register conditional test. It is therefore
  100. * modified to simplify the analysis.
  101. * Found in Borland Turbo C.
  102. ****************************************************************************/
  103. bool Idiom10::match(iICODE pIcode)
  104. {
  105. if(distance(pIcode,m_end)<2)
  106. return false;
  107. m_icodes[0]=pIcode++;
  108. m_icodes[1]=pIcode++;
  109. /* Check OR reg, reg */
  110. if (not m_icodes[0]->ll()->testFlags(I) &&
  111. m_icodes[0]->ll()->src().isReg() &&
  112. (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->dst.getReg2()))
  113. if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
  114. {
  115. return true;
  116. }
  117. return false;
  118. }
  119. int Idiom10::action()
  120. {
  121. m_icodes[0]->ll()->set(iCMP,I);
  122. m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
  123. m_icodes[0]->du.def = 0;
  124. m_icodes[0]->du1.numRegsDef = 0;
  125. return 2;
  126. }