idiom1.cpp 4.2 KB

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