xor_idioms.cpp 4.2 KB

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