call_idioms.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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()->isLlFlag(I) && m_icodes[1]->ll()->match(iADD,rSP))
  26. {
  27. m_param_count = m_icodes[1]->ll()->src.op();
  28. return true;
  29. }
  30. else if (m_icodes[1]->ll()->match(iMOV,rSP,rBP))
  31. {
  32. m_icodes[0]->ll()->SetLlFlag(REST_STK);
  33. return true;
  34. }
  35. return 0;
  36. }
  37. int Idiom3::action()
  38. {
  39. if (m_icodes[0]->ll()->isLlFlag(I) )
  40. {
  41. m_icodes[0]->ll()->src.proc.proc->cbParam = (int16_t)m_param_count;
  42. m_icodes[0]->ll()->src.proc.cb = m_param_count;
  43. m_icodes[0]->ll()->src.proc.proc->flg |= CALL_C;
  44. }
  45. else
  46. {
  47. printf("Indirect call at idiom3\n");
  48. }
  49. m_icodes[1]->invalidate();
  50. return 2;
  51. }
  52. /*****************************************************************************
  53. * idiom 17 - C calling convention.
  54. * CALL(F) xxxx
  55. * POP reg
  56. * [POP reg] reg in {AX, BX, CX, DX}
  57. * Eg: CALL proc_X
  58. * POP cx
  59. * POP cx (4 bytes of arguments)
  60. * => pProc->cbParam = # pops * 2
  61. * Found in Turbo C when restoring the stack for a procedure that uses the
  62. * C calling convention. Used to restore the stack of 2 or 4 bytes args.
  63. ****************************************************************************/
  64. bool Idiom17::match(iICODE picode)
  65. {
  66. if(distance(picode,m_end)<2)
  67. return false;
  68. m_param_count=0; /* Count on # pops */
  69. m_icodes.clear();
  70. /* Match ADD SP, immed */
  71. for(int i=0; i<2; ++i)
  72. m_icodes.push_back(picode++);
  73. uint8_t regi;
  74. /* Match POP reg */
  75. if (m_icodes[1]->ll()->match(iPOP))
  76. {
  77. int i=0;
  78. regi = m_icodes[1]->ll()->dst.regi;
  79. if ((regi >= rAX) && (regi <= rBX))
  80. i++;
  81. while (picode != m_end && picode->ll()->match(iPOP))
  82. {
  83. if (picode->ll()->dst.regi != regi)
  84. break;
  85. i++;
  86. m_icodes.push_back(picode++);
  87. }
  88. m_param_count = i*2;
  89. }
  90. return m_param_count!=0;
  91. }
  92. int Idiom17::action()
  93. {
  94. if (m_icodes[0]->ll()->isLlFlag(I))
  95. {
  96. m_icodes[0]->ll()->src.proc.proc->cbParam = (int16_t)m_param_count;
  97. m_icodes[0]->ll()->src.proc.cb = m_param_count;
  98. m_icodes[0]->ll()->src.proc.proc->flg |= CALL_C;
  99. for(int idx=1; idx<m_icodes.size(); ++idx)
  100. {
  101. m_icodes[idx]->invalidate();
  102. }
  103. }
  104. // TODO : it's a calculated call
  105. else
  106. {
  107. printf("Indirect call at idiom17\n");
  108. }
  109. return m_icodes.size();
  110. }