call_idioms.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "call_idioms.h"
  2. #include "dcc.h"
  3. #include "msvc_fixes.h"
  4. using namespace std;
  5. /*****************************************************************************
  6. * idiom3 - C calling convention.
  7. * CALL(F) proc_X
  8. * ADD SP, immed
  9. * Eg: CALL proc_X
  10. * ADD SP, 6
  11. * => pProc->cbParam = immed
  12. * Special case: when the call is at the end of the procedure,
  13. * sometimes the stack gets restored by a MOV sp, bp.
  14. * Need to flag the procedure in these cases.
  15. * Used by compilers to restore the stack when invoking a procedure using
  16. * the C calling convention.
  17. ****************************************************************************/
  18. bool Idiom3::match(iICODE picode)
  19. {
  20. if(distance(picode,m_end)<2)
  21. return false;
  22. m_param_count=0;
  23. /* Match ADD SP, immed */
  24. for(int i=0; i<2; ++i)
  25. m_icodes[i] = picode++;
  26. if ( m_icodes[1]->ll()->testFlags(I) and m_icodes[1]->ll()->match(iADD,rSP))
  27. {
  28. m_param_count = m_icodes[1]->ll()->src().getImm2();
  29. return true;
  30. }
  31. else if (m_icodes[1]->ll()->match(iMOV,rSP,rBP))
  32. {
  33. m_icodes[0]->ll()->setFlags(REST_STK);
  34. return true;
  35. }
  36. return 0;
  37. }
  38. int Idiom3::action()
  39. {
  40. if (m_icodes[0]->ll()->testFlags(I) )
  41. {
  42. m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::eCdecl);
  43. }
  44. else
  45. {
  46. printf("Indirect call at idiom3\n");
  47. }
  48. m_icodes[1]->invalidate();
  49. return 2;
  50. }
  51. /*****************************************************************************
  52. * idiom 17 - C calling convention.
  53. * CALL(F) xxxx
  54. * POP reg
  55. * [POP reg] reg in {AX, BX, CX, DX}
  56. * Eg: CALL proc_X
  57. * POP cx
  58. * POP cx (4 bytes of arguments)
  59. * => pProc->cbParam = # pops * 2
  60. * Found in Turbo C when restoring the stack for a procedure that uses the
  61. * C calling convention. Used to restore the stack of 2 or 4 bytes args.
  62. ****************************************************************************/
  63. bool Idiom17::match(iICODE picode)
  64. {
  65. if(distance(picode,m_end)<2)
  66. return false;
  67. m_param_count=0; /* Count on # pops */
  68. m_icodes.clear();
  69. /* Match ADD SP, immed */
  70. for(int i=0; i<2; ++i)
  71. m_icodes.push_back(picode++);
  72. uint8_t regi;
  73. /* Match POP reg */
  74. if (m_icodes[1]->ll()->match(iPOP))
  75. {
  76. int i=0;
  77. regi = m_icodes[1]->ll()->m_dst.regi;
  78. if ((regi >= rAX) and (regi <= rBX))
  79. i++;
  80. while (picode != m_end and picode->ll()->match(iPOP))
  81. {
  82. if (picode->ll()->m_dst.regi != regi)
  83. break;
  84. i++;
  85. m_icodes.push_back(picode++);
  86. }
  87. m_param_count = i*2;
  88. }
  89. return m_param_count!=0;
  90. }
  91. int Idiom17::action()
  92. {
  93. if (m_icodes[0]->ll()->testFlags(I))
  94. {
  95. m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::eCdecl);
  96. for(size_t idx=1; idx<m_icodes.size(); ++idx)
  97. {
  98. m_icodes[idx]->invalidate();
  99. }
  100. }
  101. // TODO : it's a calculated call
  102. else
  103. {
  104. printf("Indirect call at idiom17\n");
  105. }
  106. return m_icodes.size();
  107. }