idiom1.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "idiom1.h"
  2. #include "dcc.h"
  3. #include "msvc_fixes.h"
  4. /*****************************************************************************
  5. * checkStkVars - Checks for PUSH SI
  6. * [PUSH DI]
  7. * or PUSH DI
  8. * [PUSH SI]
  9. * In which case, the stack variable flags are set
  10. ****************************************************************************/
  11. int Idiom1::checkStkVars (iICODE pIcode)
  12. {
  13. /* Look for PUSH SI */
  14. int si_matched=0;
  15. int di_matched=0;
  16. if(pIcode==m_end)
  17. return 0;
  18. if (pIcode->ll()->match(iPUSH,rSI))
  19. {
  20. si_matched = 1;
  21. ++pIcode;
  22. if ((pIcode != m_end) and pIcode->ll()->match(iPUSH,rDI)) // Look for PUSH DI
  23. di_matched = 1;
  24. }
  25. else if (pIcode->ll()->match(iPUSH,rDI))
  26. {
  27. di_matched = 1;
  28. ++pIcode;
  29. if ((pIcode != m_end) and pIcode->ll()->match(iPUSH,rSI)) // Look for PUSH SI
  30. si_matched = 1;
  31. }
  32. m_func->flg |= (si_matched ? SI_REGVAR : 0) | (di_matched ? DI_REGVAR : 0);
  33. return si_matched+di_matched;
  34. }
  35. /*****************************************************************************
  36. * idiom1 - HLL procedure prologue; Returns number of instructions matched.
  37. * PUSH BP ==> ENTER immed, 0
  38. * MOV BP, SP and sets PROC_HLL flag
  39. * [SUB SP, immed]
  40. * [PUSH SI]
  41. * [PUSH DI]
  42. * - Second version: Push stack variables and then save BP
  43. * PUSH BP
  44. * PUSH SI
  45. * [PUSH DI]
  46. * MOV BP, SP
  47. * - Third version: Stack variables
  48. * [PUSH SI]
  49. * [PUSH DI]
  50. ****************************************************************************/
  51. bool Idiom1::match(iICODE picode)
  52. {
  53. //uint8_t type = 0; /* type of variable: 1 = reg-var, 2 = local */
  54. //uint8_t regi; /* register of the MOV */
  55. if(m_func->flg & PROC_HLL)
  56. return false;
  57. if(picode==m_end)
  58. return false;
  59. //int n;
  60. m_icodes.clear();
  61. m_min_off = 0;
  62. /* PUSH BP as first instruction of procedure */
  63. if ( (not picode->ll()->testFlags(I)) and picode->ll()->src().regi == rBP)
  64. {
  65. m_icodes.push_back( picode++ ); // insert iPUSH
  66. if(picode==m_end)
  67. return false;
  68. /* MOV BP, SP as next instruction */
  69. if ( not picode->ll()->testFlags(I | TARGET | CASE) and picode->ll()->match(iMOV ,rBP,rSP) )
  70. {
  71. m_icodes.push_back( picode++ ); // insert iMOV
  72. if(picode==m_end)
  73. return false;
  74. m_min_off = 2;
  75. /* Look for SUB SP, immed */
  76. if (
  77. picode->ll()->testFlags(I | TARGET | CASE) and picode->ll()->match(iSUB,rSP)
  78. )
  79. {
  80. m_icodes.push_back( picode++ ); // insert iSUB
  81. int n = checkStkVars (picode); // find iPUSH si [iPUSH di]
  82. for(int i=0; i<n; ++i)
  83. m_icodes.push_back(picode++); // insert
  84. }
  85. }
  86. /* PUSH SI
  87. * [PUSH DI]
  88. * MOV BP, SP */
  89. else
  90. {
  91. int n = checkStkVars (picode);
  92. if (n > 0)
  93. {
  94. for(int i=0; i<n; ++i)
  95. m_icodes.push_back(picode++);
  96. if(picode == m_end)
  97. return false;
  98. /* Look for MOV BP, SP */
  99. if ( picode != m_end and
  100. not picode->ll()->testFlags(I | TARGET | CASE) and
  101. picode->ll()->match(iMOV,rBP,rSP))
  102. {
  103. m_icodes.push_back(picode);
  104. m_min_off = 2 + (n * 2);
  105. }
  106. else
  107. return false; // Cristina: check this please!
  108. }
  109. else
  110. return false; // Cristina: check this please!
  111. }
  112. }
  113. else // push di [push si] / push si [push di]
  114. {
  115. size_t n = checkStkVars (picode);
  116. for(size_t i=0; i<n; ++i)
  117. m_icodes.push_back(picode++);
  118. }
  119. return !m_icodes.empty();
  120. }
  121. int Idiom1::action()
  122. {
  123. for(iICODE ic : m_icodes)
  124. {
  125. ic->invalidate();
  126. }
  127. m_func->flg |= PROC_HLL;
  128. if(0!=m_min_off)
  129. {
  130. m_func->args.m_minOff = m_min_off;
  131. m_func->flg |= PROC_IS_HLL;
  132. }
  133. return m_icodes.size();
  134. }