icode.h 15 KB

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