call_idioms.cpp 3.1 KB

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