locident.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * File: locIdent.h
  3. * Purpose: High-level local identifier definitions
  4. * Date: October 1993
  5. * (C) Cristina Cifuentes
  6. */
  7. #pragma once
  8. #include "msvc_fixes.h"
  9. #include "types.h"
  10. #include "Enums.h"
  11. #include "machine_x86.h"
  12. #include <QtCore/QString>
  13. #include <stdint.h>
  14. #include <vector>
  15. #include <list>
  16. #include <set>
  17. #include <algorithm>
  18. /* Type definition */
  19. // this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
  20. // TODO: why ?
  21. struct Expr;
  22. struct AstIdent;
  23. struct ICODE;
  24. struct LLInst;
  25. typedef std::list<ICODE>::iterator iICODE;
  26. struct IDX_ARRAY : public std::vector<iICODE>
  27. {
  28. bool inList(iICODE idx) const
  29. {
  30. return std::find(begin(),end(),idx)!=end();
  31. }
  32. };
  33. enum frameType
  34. {
  35. STK_FRAME, /* For stack vars */
  36. REG_FRAME, /* For register variables */
  37. GLB_FRAME /* For globals */
  38. };
  39. struct BWGLB_TYPE
  40. {
  41. int16_t seg; /* segment value */
  42. int16_t off; /* offset */
  43. eReg regi; /* optional indexed register */
  44. } ;
  45. /* For TYPE_LONG_(UN)SIGN on the stack */
  46. struct LONG_STKID_TYPE
  47. {
  48. int offH; /* high offset from BP */
  49. int offL; /* low offset from BP */
  50. LONG_STKID_TYPE(int h,int l) : offH(h),offL(l) {}
  51. };
  52. /* For TYPE_LONG_(UN)SIGN registers */
  53. struct LONGID_TYPE
  54. {
  55. protected:
  56. eReg m_h; /* high register */
  57. eReg m_l; /* low register */
  58. public:
  59. void set(eReg highpart,eReg lowpart)
  60. {
  61. m_h = highpart;
  62. m_l = lowpart;
  63. }
  64. eReg l() const { return m_l; }
  65. eReg h() const { return m_h; }
  66. bool srcDstRegMatch(iICODE a,iICODE b) const;
  67. LONGID_TYPE() {} // uninitializing constructor to help valgrind catch uninit accesses
  68. LONGID_TYPE(eReg h,eReg l) : m_h(h),m_l(l) {}
  69. };
  70. struct LONGGLB_TYPE /* For TYPE_LONG_(UN)SIGN globals */
  71. {
  72. int16_t seg; /* segment value */
  73. int16_t offH; /* offset high */
  74. int16_t offL; /* offset low */
  75. uint8_t regi; /* optional indexed register */
  76. LONGGLB_TYPE(int16_t _seg,int16_t _H,int16_t _L,int8_t _reg=0)
  77. {
  78. seg=_seg;
  79. offH=_H;
  80. offL=_L;
  81. regi=_reg;
  82. }
  83. };
  84. /* ID, LOCAL_ID */
  85. struct ID
  86. {
  87. protected:
  88. LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
  89. public:
  90. hlType type; /* Probable type */
  91. IDX_ARRAY idx; /* Index into icode array (REG_FRAME only) */
  92. frameType loc; /* Frame location */
  93. bool illegal; /* Boolean: not a valid field any more */
  94. bool hasMacro; /* Identifier requires a macro */
  95. char macro[10]; /* Macro for this identifier */
  96. QString name; /* Identifier's name */
  97. union ID_UNION { /* Different types of identifiers */
  98. friend struct ID;
  99. protected:
  100. LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
  101. public:
  102. eReg regi; /* For TYPE_BYTE(WORD)_(UN)SIGN registers */
  103. struct { /* For TYPE_BYTE(WORD)_(UN)SIGN on the stack */
  104. uint8_t regOff; /* register offset (if any) */
  105. int off; /* offset from BP */
  106. } bwId;
  107. BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
  108. LONGGLB_TYPE longGlb;
  109. struct { /* For TYPE_LONG_(UN)SIGN constants */
  110. uint32_t h; /* high uint16_t */
  111. uint32_t l; /* low uint16_t */
  112. } longKte;
  113. ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
  114. } id;
  115. LONGID_TYPE & longId() {assert(isLong() and loc==REG_FRAME); return m_longId;}
  116. const LONGID_TYPE & longId() const {assert(isLong() and loc==REG_FRAME); return m_longId;}
  117. LONG_STKID_TYPE & longStkId() {assert(isLong() and loc==STK_FRAME); return id.longStkId;}
  118. const LONG_STKID_TYPE & longStkId() const {assert(isLong() and loc==STK_FRAME); return id.longStkId;}
  119. ID();
  120. ID(hlType t, frameType f);
  121. ID(hlType t, const LONGID_TYPE &s);
  122. ID(hlType t, const LONG_STKID_TYPE &s);
  123. ID(hlType t, const LONGGLB_TYPE &s);
  124. bool isSigned() const { return (type==TYPE_BYTE_SIGN) or (type==TYPE_WORD_SIGN) or (type==TYPE_LONG_SIGN);}
  125. uint16_t typeBitsize() const
  126. {
  127. return TypeContainer::typeSize(type)*8;
  128. }
  129. bool isLong() const { return (type==TYPE_LONG_UNSIGN) or (type==TYPE_LONG_SIGN); }
  130. void setLocalName(int i)
  131. {
  132. char buf[32];
  133. sprintf (buf, "loc%d", i);
  134. name=buf;
  135. }
  136. bool isLongRegisterPair() const { return (loc == REG_FRAME) and isLong();}
  137. eReg getPairedRegister(eReg first) const;
  138. };
  139. struct LOCAL_ID
  140. {
  141. std::vector<ID> id_arr;
  142. protected:
  143. int newLongIdx(int16_t seg, int16_t offH, int16_t offL, uint8_t regi, hlType t);
  144. int newLongGlb(int16_t seg, int16_t offH, int16_t offL, hlType t);
  145. int newLongStk(hlType t, int offH, int offL);
  146. public:
  147. LOCAL_ID()
  148. {
  149. id_arr.reserve(256);
  150. }
  151. // interface to allow range based iteration
  152. std::vector<ID>::iterator begin() {return id_arr.begin();}
  153. std::vector<ID>::iterator end() {return id_arr.end();}
  154. int newByteWordReg(hlType t, eReg regi);
  155. int newByteWordStk(hlType t, int off, uint8_t regOff);
  156. int newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t);
  157. int newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_);
  158. int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off);
  159. int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
  160. void newIdent(hlType t, frameType f);
  161. void flagByteWordId(int off);
  162. void propLongId(uint8_t regL, uint8_t regH, const QString & name);
  163. size_t csym() const {return id_arr.size();}
  164. void newRegArg(ICODE & picode, ICODE & ticode) const;
  165. void processTargetIcode(ICODE & picode, int &numHlIcodes, ICODE & ticode, bool isLong) const;
  166. void forwardSubs(Expr *lhs, Expr *rhs, ICODE & picode, ICODE & ticode, int &numHlIcodes) const;
  167. AstIdent *createId(const ID *retVal, iICODE ix_);
  168. eReg getPairedRegisterAt(int idx,eReg first) const;
  169. };