epilogue_idioms.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "dcc.h"
  2. #include "epilogue_idioms.h"
  3. /*****************************************************************************
  4. * popStkVars - checks for
  5. * [POP DI]
  6. * [POP SI]
  7. * or [POP SI]
  8. * [POP DI]
  9. ****************************************************************************/
  10. void EpilogIdiom::popStkVars(iICODE pIcode)
  11. {
  12. // TODO : only process SI-DI DI-SI pairings, no SI-SI, DI-DI like it's now
  13. /* Match [POP DI] */
  14. if (pIcode->ic.ll.match(iPOP))
  15. {
  16. if ((m_func->flg & DI_REGVAR) && pIcode->ic.ll.match(rDI))
  17. m_icodes.push_front(pIcode);
  18. else if ((m_func->flg & SI_REGVAR) && pIcode->ic.ll.match(rSI))
  19. m_icodes.push_front(pIcode);
  20. }
  21. ++pIcode;
  22. if(pIcode==m_end)
  23. return;
  24. /* Match [POP SI] */
  25. if (pIcode->ic.ll.match(iPOP))
  26. {
  27. if ((m_func->flg & SI_REGVAR) && pIcode->ic.ll.match(rSI))
  28. m_icodes.push_front(pIcode);
  29. else if ((m_func->flg & DI_REGVAR) && pIcode->ic.ll.match(rDI))
  30. m_icodes.push_front(pIcode);
  31. }
  32. }
  33. /*****************************************************************************
  34. * idiom2 - HLL procedure epilogue; Returns number of instructions matched.
  35. * [POP DI]
  36. * [POP SI]
  37. * MOV SP, BP
  38. * POP BP
  39. * RET(F)
  40. *****************************************************************************/
  41. bool Idiom2::match(iICODE pIcode)
  42. {
  43. iICODE nicode;
  44. if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0
  45. return false;
  46. if ( ((pIcode->ic.ll.flg & I) == I) || not pIcode->ic.ll.match(rSP,rBP))
  47. return false;
  48. if(distance(pIcode,m_end)<3)
  49. return false;
  50. /* Matched MOV SP, BP */
  51. m_icodes.clear();
  52. m_icodes.push_back(pIcode);
  53. /* Get next icode, skip over holes in the icode array */
  54. nicode = pIcode + 1;
  55. while (nicode->ic.ll.flg & NO_CODE && (nicode != m_end))
  56. {
  57. nicode++;
  58. }
  59. if(nicode == m_end)
  60. return false;
  61. if (nicode->ic.ll.match(iPOP,rBP) && ! (nicode->ic.ll.flg & (I | TARGET | CASE)) )
  62. {
  63. m_icodes.push_back(nicode++); // Matched POP BP
  64. /* Match RET(F) */
  65. if ( nicode != m_end &&
  66. !(nicode->ic.ll.flg & (I | TARGET | CASE)) &&
  67. (nicode->ic.ll.match(iRET) || nicode->ic.ll.match(iRETF))
  68. )
  69. {
  70. m_icodes.push_back(nicode); // Matched RET
  71. popStkVars (pIcode-2); // will add optional pop di/si to m_icodes
  72. return true;
  73. }
  74. }
  75. return false;
  76. }
  77. int Idiom2::action()
  78. {
  79. for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
  80. m_icodes[idx]->invalidate();
  81. return 3;
  82. }
  83. /*****************************************************************************
  84. * idiom4 - Pascal calling convention.
  85. * RET(F) immed
  86. * ==> pProc->cbParam = immed
  87. * sets CALL_PASCAL flag
  88. * - Second version: check for optional pop of stack vars
  89. * [POP DI]
  90. * [POP SI]
  91. * POP BP
  92. * RET(F) [immed]
  93. * - Third version: pop stack vars
  94. * [POP DI]
  95. * [POP SI]
  96. * RET(F) [immed]
  97. ****************************************************************************/
  98. bool Idiom4::match(iICODE pIcode)
  99. {
  100. m_param_count = 0;
  101. /* Check for [POP DI]
  102. * [POP SI] */
  103. if(distance(m_func->Icode.begin(),pIcode)>=3)
  104. popStkVars (pIcode-3);
  105. if(pIcode != m_func->Icode.begin())
  106. {
  107. iICODE prev1=pIcode-1;
  108. /* Check for POP BP */
  109. if (prev1->ic.ll.match(iPOP,rBP) && not prev1->ic.ll.anyFlagSet(I) )
  110. m_icodes.push_back(prev1);
  111. else if(prev1!=m_func->Icode.begin())
  112. popStkVars (pIcode-2);
  113. }
  114. /* Check for RET(F) immed */
  115. if (pIcode->ic.ll.flg & I)
  116. {
  117. m_param_count = (int16)pIcode->ic.ll.src.op();
  118. }
  119. }
  120. int Idiom4::action()
  121. {
  122. for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
  123. m_icodes[idx]->invalidate();
  124. if(m_param_count)
  125. {
  126. m_func->cbParam = (int16)m_param_count;
  127. m_func->flg |= CALL_PASCAL;
  128. }
  129. return 0;
  130. }