icode.h 11 KB

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