icode.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*****************************************************************************
  2. * I-code related definitions
  3. * (C) Cristina Cifuentes
  4. ****************************************************************************/
  5. #pragma once
  6. #include <vector>
  7. #include "Enums.h"
  8. //enum condId;
  9. /* LOW_LEVEL icode flags */
  10. enum eLLFlags
  11. {
  12. B =0x0000001, /* Byte operands (value implicitly used) */
  13. I =0x0000002, /* Immed. source */
  14. NOT_HLL =0x0000004, /* Not HLL inst. */
  15. FLOAT_OP =0x0000008, /* ESC or WAIT */
  16. SEG_IMMED =0x0000010, /* Number is relocated segment value */
  17. IMPURE =0x0000020, /* Instruction modifies code */
  18. WORD_OFF =0x0000040, /* Inst has word offset ie.could be address */
  19. TERMINATES =0x0000080, /* Instruction terminates program */
  20. CASE =0x0000100, /* Label as case part of switch */
  21. SWITCH =0x0000200, /* Treat indirect JMP as switch stmt */
  22. TARGET =0x0000400, /* Jump target */
  23. SYNTHETIC =0x0000800, /* Synthetic jump instruction */
  24. NO_LABEL =0x0001000, /* Immed. jump cannot be linked to a label */
  25. NO_CODE =0x0002000, /* Hole in Icode array */
  26. SYM_USE =0x0004000, /* Instruction uses a symbol */
  27. SYM_DEF =0x0008000, /* Instruction defines a symbol */
  28. NO_SRC =0x0010000, /* Opcode takes no source */
  29. NO_OPS =0x0020000, /* Opcode takes no operands */
  30. IM_OPS =0x0040000, /* Opcode takes implicit operands */
  31. SRC_B =0x0080000, /* Source operand is byte (dest is word) */
  32. #define NO_SRC_B 0xF7FFFF /* Masks off SRC_B */
  33. HLL_LABEL =0x0100000, /* Icode has a high level language label */
  34. IM_DST =0x0200000, /* Implicit DST for opcode (SIGNEX) */
  35. IM_SRC =0x0400000, /* Implicit SRC for opcode (dx:ax) */
  36. IM_TMP_DST =0x0800000, /* Implicit rTMP DST for opcode (DIV/IDIV) */
  37. JMP_ICODE =0x1000000, /* Jmp dest immed.op converted to icode index */
  38. JX_LOOP =0x2000000, /* Cond jump is part of loop conditional exp */
  39. REST_STK =0x4000000 /* Stack needs to be restored after CALL */
  40. };
  41. /* Parser flags */
  42. #define TO_REG 0x000100 /* rm is source */
  43. #define S 0x000200 /* sign extend */
  44. #define OP386 0x000400 /* 386 op-code */
  45. #define NSP 0x000800 /* NOT_HLL if SP is src or dst */
  46. #define ICODEMASK 0xFF00FF /* Masks off parser flags */
  47. /* LOW_LEVEL icode, DU flag bits */
  48. #define Cf 1
  49. #define Sf 2
  50. #define Zf 4
  51. #define Df 8
  52. /* Machine registers */
  53. #define rAX 1 /* These are numbered relative to real 8086 */
  54. #define rCX 2
  55. #define rDX 3
  56. #define rBX 4
  57. #define rSP 5
  58. #define rBP 6
  59. #define rSI 7
  60. #define rDI 8
  61. #define rES 9
  62. #define rCS 10
  63. #define rSS 11
  64. #define rDS 12
  65. #define rAL 13
  66. #define rCL 14
  67. #define rDL 15
  68. #define rBL 16
  69. #define rAH 17
  70. #define rCH 18
  71. #define rDH 19
  72. #define rBH 20
  73. #define rTMP 21 /* temp register for DIV/IDIV/MOD */
  74. #define INDEXBASE 22 /* Indexed modes go from INDEXBASE to
  75. * INDEXBASE+7 */
  76. /* Byte and Word registers */
  77. static const char *const byteReg[9] = {"al", "cl", "dl", "bl",
  78. "ah", "ch", "dh", "bh", "tmp" };
  79. static const char *const wordReg[21] = {"ax", "cx", "dx", "bx", "sp", "bp",
  80. "si", "di", "es", "cs", "ss", "ds",
  81. "", "", "", "", "", "", "", "", "tmp"};
  82. #include "state.h" // State depends on INDEXBASE, but later need STATE
  83. /* Types of icodes */
  84. enum icodeType
  85. {
  86. NOT_SCANNED = 0, /* not even scanned yet */
  87. LOW_LEVEL, /* low-level icode */
  88. HIGH_LEVEL /* high-level icode */
  89. };
  90. /* LOW_LEVEL icode opcodes */
  91. enum llIcode
  92. {
  93. iCBW, /* 0 */
  94. iAAA,
  95. iAAD,
  96. iAAM,
  97. iAAS,
  98. iADC,
  99. iADD,
  100. iAND,
  101. iBOUND,
  102. iCALL,
  103. iCALLF, /* 10 */
  104. iCLC,
  105. iCLD,
  106. iCLI,
  107. iCMC,
  108. iCMP,
  109. iCMPS,
  110. iREPNE_CMPS,
  111. iREPE_CMPS,
  112. iDAA,
  113. iDAS, /* 20 */
  114. iDEC,
  115. iDIV,
  116. iENTER,
  117. iESC,
  118. iHLT,
  119. iIDIV,
  120. iIMUL,
  121. iIN,
  122. iINC,
  123. iINS, /* 30 */
  124. iREP_INS,
  125. iINT,
  126. iIRET,
  127. iJB,
  128. iJBE,
  129. iJAE,
  130. iJA,
  131. iJE,
  132. iJNE,
  133. iJL, /* 40 */
  134. iJGE,
  135. iJLE,
  136. iJG,
  137. iJS,
  138. iJNS,
  139. iJO,
  140. iJNO,
  141. iJP,
  142. iJNP,
  143. iJCXZ, /* 50 */
  144. iJMP,
  145. iJMPF,
  146. iLAHF,
  147. iLDS,
  148. iLEA,
  149. iLEAVE,
  150. iLES,
  151. iLOCK,
  152. iLODS,
  153. iREP_LODS, /* 60 */
  154. iLOOP,
  155. iLOOPE,
  156. iLOOPNE,
  157. iMOV, /* 64 */
  158. iMOVS,
  159. iREP_MOVS,
  160. iMUL, /* 67 */
  161. iNEG,
  162. iNOT,
  163. iOR, /* 70 */
  164. iOUT,
  165. iOUTS,
  166. iREP_OUTS,
  167. iPOP,
  168. iPOPA,
  169. iPOPF,
  170. iPUSH,
  171. iPUSHA,
  172. iPUSHF,
  173. iRCL, /* 80 */
  174. iRCR,
  175. iROL,
  176. iROR,
  177. iRET, /* 84 */
  178. iRETF,
  179. iSAHF,
  180. iSAR,
  181. iSHL,
  182. iSHR,
  183. iSBB, /* 90 */
  184. iSCAS,
  185. iREPNE_SCAS,
  186. iREPE_SCAS,
  187. iSIGNEX,
  188. iSTC,
  189. iSTD,
  190. iSTI,
  191. iSTOS,
  192. iREP_STOS,
  193. iSUB, /* 100 */
  194. iTEST,
  195. iWAIT,
  196. iXCHG,
  197. iXLAT,
  198. iXOR,
  199. iINTO,
  200. iNOP,
  201. iREPNE,
  202. iREPE,
  203. iMOD /* 110 */
  204. };
  205. struct BB;
  206. struct Function;
  207. struct STKFRAME;
  208. /* HIGH_LEVEL icodes opcodes */
  209. typedef enum {
  210. HLI_ASSIGN, /* := */
  211. HLI_CALL, /* Call procedure */
  212. HLI_JCOND, /* Conditional jump */
  213. HLI_RET, /* Return from procedure */
  214. /* pseudo high-level icodes */
  215. HLI_POP, /* Pop expression */
  216. HLI_PUSH, /* Push expression */
  217. } hlIcode;
  218. /* Def/use of flags - low 4 bits represent flags */
  219. struct DU
  220. {
  221. byte d;
  222. byte u;
  223. };
  224. /* Def/Use of registers and stack variables */
  225. struct DU_ICODE
  226. {
  227. dword def; /* For Registers: position in dword is reg index*/
  228. dword lastDefRegi;/* Bit set if last def of this register in BB */
  229. dword use; /* For Registers: position in dword is reg index*/
  230. };
  231. /* Definition-use chain for level 1 (within a basic block) */
  232. #define MAX_REGS_DEF 2 /* 2 regs def'd for long-reg vars */
  233. #define MAX_USES 5
  234. struct DU1
  235. {
  236. Int numRegsDef; /* # registers defined by this inst */
  237. byte regi[MAX_REGS_DEF]; /* registers defined by this inst */
  238. Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
  239. };
  240. /* LOW_LEVEL icode operand record */
  241. struct ICODEMEM
  242. {
  243. byte seg; /* CS, DS, ES, SS */
  244. int16 segValue; /* Value of segment seg during analysis */
  245. byte segOver; /* CS, DS, ES, SS if segment override */
  246. byte regi; /* 0 < regs < INDEXBASE <= index modes */
  247. int16 off; /* memory address offset */
  248. } ;
  249. struct COND_EXPR;
  250. struct HLTYPE
  251. {
  252. hlIcode opcode; /* hlIcode opcode */
  253. union { /* different operands */
  254. struct { /* for HLI_ASSIGN */
  255. COND_EXPR *lhs;
  256. COND_EXPR *rhs;
  257. } asgn;
  258. COND_EXPR *exp; /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
  259. struct { /* for HLI_CALL */
  260. Function *proc;
  261. STKFRAME *args; /* actual arguments */
  262. } call;
  263. } oper; /* operand */
  264. } ;
  265. typedef struct
  266. {
  267. llIcode opcode; /* llIcode instruction */
  268. byte numBytes; /* Number of bytes this instr */
  269. flags32 flg; /* icode flags */
  270. dword label; /* offset in image (20-bit adr) */
  271. ICODEMEM dst; /* destination operand */
  272. ICODEMEM src; /* source operand */
  273. union { /* Source operand if (flg & I) */
  274. dword op; /* idx of immed src op */
  275. struct { /* Call & # actual arg bytes */
  276. Function *proc; /* ^ target proc (for CALL(F))*/
  277. Int cb; /* # actual arg bytes */
  278. } proc;
  279. } immed;
  280. DU flagDU; /* def/use of flags */
  281. struct { /* Case table if op==JMP && !I */
  282. Int numEntries; /* # entries in case table */
  283. dword *entries; /* array of offsets */
  284. } caseTbl;
  285. Int hllLabNum; /* label # for hll codegen */
  286. } LLTYPE;
  287. /* Icode definition: LOW_LEVEL and HIGH_LEVEL */
  288. struct ICODE
  289. {
  290. icodeType type; /* Icode type */
  291. boolT invalid; /* Has no HIGH_LEVEL equivalent */
  292. BB *inBB; /* BB to which this icode belongs */
  293. DU_ICODE du; /* Def/use regs/vars */
  294. DU1 du1; /* du chain 1 */
  295. Int codeIdx; /* Index into cCode.code */
  296. struct IC { /* Different types of icodes */
  297. LLTYPE ll;
  298. HLTYPE hl; /* For HIGH_LEVEL icodes */
  299. };
  300. IC ic;/* intermediate code */
  301. void writeIntComment(char *s);
  302. void setRegDU(byte regi, operDu du_in);
  303. void invalidate();
  304. void newCallHl();
  305. void writeDU(Int idx);
  306. condId idType(opLoc sd);
  307. // HLL setting functions
  308. void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs); // set this icode to be an assign
  309. void setUnary(hlIcode op, COND_EXPR *exp);
  310. void setJCond(COND_EXPR *cexp);
  311. int loc_ip; // used by CICodeRec to number ICODEs
  312. };
  313. // This is the icode array object.
  314. // The bulk of this could well be done with a class library
  315. class CIcodeRec : public std::vector<ICODE>
  316. {
  317. public:
  318. CIcodeRec(); // Constructor
  319. ~CIcodeRec(); // Destructor
  320. ICODE * addIcode(ICODE *pIcode);
  321. ICODE * GetFirstIcode();
  322. // ICODE * GetNextIcode(ICODE * pCurIcode);
  323. boolT IsValid(ICODE * pCurIcode);
  324. int GetNumIcodes();
  325. void SetInBB(int start, int end, BB* pnewBB);
  326. void SetImmediateOp(int ip, dword dw);
  327. void SetLlFlag(int ip, dword flag);
  328. void ClearLlFlag(int ip, dword flag);
  329. dword GetLlFlag(int ip);
  330. void SetLlInvalid(int ip, boolT fInv);
  331. dword GetLlLabel(int ip);
  332. llIcode GetLlOpcode(int ip);
  333. boolT labelSrch(dword target, Int *pIndex);
  334. ICODE * GetIcode(int ip);
  335. };