hlicode.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /*
  2. * File: hlIcode.c
  3. * Purpose: High-level icode routines
  4. * Date: September-October 1993
  5. * (C) Cristina Cifuentes
  6. */
  7. #include <cassert>
  8. #include <string.h>
  9. #include <string>
  10. #include <sstream>
  11. #include "dcc.h"
  12. using namespace std;
  13. #define ICODE_DELTA 25
  14. /* Masks off bits set by duReg[] */
  15. dword maskDuReg[] = { 0x00,
  16. 0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* word regs */
  17. 0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
  18. 0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */
  19. 0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* byte regs */
  20. 0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
  21. 0xEFFFFF, /* tmp reg */
  22. 0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
  23. 0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
  24. static char buf[lineSize]; /* Line buffer for hl icode output */
  25. /* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
  26. void ICODE::setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
  27. {
  28. type = HIGH_LEVEL;
  29. ic.hl.opcode = HLI_ASSIGN;
  30. assert(ic.hl.oper.asgn.lhs==0); //prevent memory leaks
  31. assert(ic.hl.oper.asgn.rhs==0); //prevent memory leaks
  32. ic.hl.oper.asgn.lhs = lhs;
  33. ic.hl.oper.asgn.rhs = rhs;
  34. }
  35. /* Places the new HLI_CALL high-level operand in the high-level icode array */
  36. void ICODE::newCallHl()
  37. {
  38. type = HIGH_LEVEL;
  39. ic.hl.opcode = HLI_CALL;
  40. ic.hl.oper.call.proc = ic.ll.immed.proc.proc;
  41. ic.hl.oper.call.args = new STKFRAME;
  42. if (ic.ll.immed.proc.cb != 0)
  43. ic.hl.oper.call.args->cb = ic.ll.immed.proc.cb;
  44. else
  45. ic.hl.oper.call.args->cb =ic.hl.oper.call.proc->cbParam;
  46. }
  47. /* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode
  48. * array */
  49. void ICODE::setUnary(hlIcode op, COND_EXPR *exp)
  50. {
  51. assert(ic.hl.oper.exp==0);
  52. type = HIGH_LEVEL;
  53. ic.hl.opcode = op;
  54. ic.hl.oper.exp = exp;
  55. }
  56. /* Places the new HLI_JCOND high-level operand in the high-level icode array */
  57. void ICODE::setJCond(COND_EXPR *cexp)
  58. {
  59. assert(ic.hl.oper.exp==0);
  60. type = HIGH_LEVEL;
  61. ic.hl.opcode = HLI_JCOND;
  62. ic.hl.oper.exp = cexp;
  63. }
  64. /* Sets the invalid field to TRUE as this low-level icode is no longer valid,
  65. * it has been replaced by a high-level icode. */
  66. void ICODE ::invalidate()
  67. {
  68. invalid = TRUE;
  69. }
  70. /* Removes the defined register regi from the lhs subtree. If all registers
  71. * of this instruction are unused, the instruction is invalidated (ie.
  72. * removed) */
  73. boolT ICODE::removeDefRegi (byte regi, Int thisDefIdx, LOCAL_ID *locId)
  74. {
  75. Int numDefs;
  76. numDefs = du1.numRegsDef;
  77. if (numDefs == thisDefIdx)
  78. for ( ; numDefs > 0; numDefs--)
  79. {
  80. if ((du1.idx[numDefs-1][0] != 0)||(du.lastDefRegi))
  81. break;
  82. }
  83. if (numDefs == 0)
  84. {
  85. invalidate();
  86. return true;
  87. }
  88. else
  89. {
  90. switch (ic.hl.opcode) {
  91. case HLI_ASSIGN:
  92. removeRegFromLong (regi, locId,ic.hl.oper.asgn.lhs);
  93. du1.numRegsDef--;
  94. du.def &= maskDuReg[regi];
  95. break;
  96. case HLI_POP:
  97. case HLI_PUSH:
  98. removeRegFromLong (regi, locId, ic.hl.oper.exp);
  99. du1.numRegsDef--;
  100. du.def &= maskDuReg[regi];
  101. break;
  102. }
  103. return false;
  104. }
  105. }
  106. /* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
  107. * Note: this process should be done before data flow analysis, which
  108. * refines the HIGH_LEVEL icodes. */
  109. void Function::highLevelGen()
  110. { Int i, /* idx into icode array */
  111. numIcode; /* number of icode instructions */
  112. ICODE * pIcode; /* ptr to current icode node */
  113. COND_EXPR *lhs, *rhs; /* left- and right-hand side of expression */
  114. flags32 flg; /* icode flags */
  115. numIcode = Icode.GetNumIcodes();
  116. for (i = 0; i < numIcode; i++)
  117. {
  118. pIcode = Icode.GetIcode(i);
  119. if ((pIcode->ic.ll.flg & NOT_HLL) == NOT_HLL)
  120. pIcode->invalidate();
  121. if ((pIcode->type == LOW_LEVEL) && (pIcode->invalid == FALSE))
  122. {
  123. flg = pIcode->ic.ll.flg;
  124. if ((flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */
  125. if ((flg & NO_OPS) != NO_OPS) /* if there are opers */
  126. {
  127. if ((flg & NO_SRC) != NO_SRC) /* if there is src op */
  128. rhs = COND_EXPR::id (pIcode, SRC, this, i, pIcode, NONE);
  129. lhs = COND_EXPR::id (pIcode, DST, this, i, pIcode, NONE);
  130. }
  131. switch (pIcode->ic.ll.opcode) {
  132. case iADD: rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
  133. pIcode->setAsgn(lhs, rhs);
  134. break;
  135. case iAND: rhs = COND_EXPR::boolOp (lhs, rhs, AND);
  136. pIcode->setAsgn(lhs, rhs);
  137. break;
  138. case iCALL:
  139. case iCALLF: pIcode->newCallHl();
  140. break;
  141. case iDEC:
  142. rhs = COND_EXPR::idKte (1, 2);
  143. rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
  144. pIcode->setAsgn(lhs, rhs);
  145. break;
  146. case iDIV:
  147. case iIDIV:/* should be signed div */
  148. rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
  149. if (pIcode->ic.ll.flg & B)
  150. {
  151. lhs = COND_EXPR::idReg (rAL, 0, &localId);
  152. pIcode->setRegDU( rAL, eDEF);
  153. }
  154. else
  155. {
  156. lhs = COND_EXPR::idReg (rAX, 0, &localId);
  157. pIcode->setRegDU( rAX, eDEF);
  158. }
  159. pIcode->setAsgn(lhs, rhs);
  160. break;
  161. case iIMUL: rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
  162. lhs = COND_EXPR::id (pIcode, LHS_OP, this, i, pIcode, NONE);
  163. pIcode->setAsgn(lhs, rhs);
  164. break;
  165. case iINC: rhs = COND_EXPR::idKte (1, 2);
  166. rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
  167. pIcode->setAsgn(lhs, rhs);
  168. break;
  169. case iLEA: rhs = COND_EXPR::unary (ADDRESSOF, rhs);
  170. pIcode->setAsgn(lhs, rhs);
  171. break;
  172. case iMOD: rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
  173. if (pIcode->ic.ll.flg & B)
  174. {
  175. lhs = COND_EXPR::idReg (rAH, 0, &localId);
  176. pIcode->setRegDU( rAH, eDEF);
  177. }
  178. else
  179. {
  180. lhs = COND_EXPR::idReg (rDX, 0, &localId);
  181. pIcode->setRegDU( rDX, eDEF);
  182. }
  183. pIcode->setAsgn(lhs, rhs);
  184. break;
  185. case iMOV: pIcode->setAsgn(lhs, rhs);
  186. break;
  187. case iMUL: rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
  188. lhs = COND_EXPR::id (pIcode, LHS_OP, this, i, pIcode, NONE);
  189. pIcode->setAsgn(lhs, rhs);
  190. break;
  191. case iNEG: rhs = COND_EXPR::unary (NEGATION, lhs);
  192. pIcode->setAsgn(lhs, rhs);
  193. break;
  194. case iNOT: rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
  195. pIcode->setAsgn(lhs, rhs);
  196. break;
  197. case iOR: rhs = COND_EXPR::boolOp (lhs, rhs, OR);
  198. pIcode->setAsgn(lhs, rhs);
  199. break;
  200. case iPOP: pIcode->setUnary(HLI_POP, lhs);
  201. break;
  202. case iPUSH: pIcode->setUnary(HLI_PUSH, lhs);
  203. break;
  204. case iRET:
  205. case iRETF: pIcode->setUnary(HLI_RET, NULL);
  206. break;
  207. case iSHL: rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
  208. pIcode->setAsgn(lhs, rhs);
  209. break;
  210. case iSAR: /* signed */
  211. case iSHR: rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
  212. pIcode->setAsgn(lhs, rhs);
  213. break;
  214. case iSIGNEX: pIcode->setAsgn(lhs, rhs);
  215. break;
  216. case iSUB: rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
  217. pIcode->setAsgn(lhs, rhs);
  218. break;
  219. case iXCHG:
  220. break;
  221. case iXOR: rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
  222. pIcode->setAsgn(lhs, rhs);
  223. break;
  224. }
  225. }
  226. }
  227. }
  228. /* Modifies the given conditional operator to its inverse. This is used
  229. * in if..then[..else] statements, to reflect the condition that takes the
  230. * then part. */
  231. void inverseCondOp (COND_EXPR **exp)
  232. {
  233. static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
  234. LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
  235. DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
  236. DUMMY, DBL_OR, DBL_AND};
  237. if (*exp == NULL)
  238. return;
  239. if ((*exp)->type == BOOLEAN_OP)
  240. {
  241. switch ((*exp)->expr.boolExpr.op)
  242. {
  243. case LESS_EQUAL: case LESS: case EQUAL:
  244. case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
  245. (*exp)->expr.boolExpr.op = invCondOp[(*exp)->expr.boolExpr.op];
  246. break;
  247. case AND: case OR: case XOR: case NOT: case ADD:
  248. case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
  249. *exp = COND_EXPR::unary (NEGATION, *exp);
  250. break;
  251. case DBL_AND: case DBL_OR:
  252. (*exp)->expr.boolExpr.op = invCondOp[(*exp)->expr.boolExpr.op];
  253. inverseCondOp (&(*exp)->expr.boolExpr.lhs);
  254. inverseCondOp (&(*exp)->expr.boolExpr.rhs);
  255. break;
  256. } /* eos */
  257. }
  258. else if ((*exp)->type == NEGATION) //TODO: memleak here
  259. *exp = (*exp)->expr.unaryExp;
  260. /* other types are left unmodified */
  261. }
  262. /* Returns the string that represents the procedure call of tproc (ie. with
  263. * actual parameters) */
  264. std::string writeCall (Function * tproc, STKFRAME * args, Function * pproc, Int *numLoc)
  265. {
  266. Int i; /* counter of # arguments */
  267. string condExp;
  268. ostringstream s;
  269. s<<tproc->name<<" (";
  270. for (i = 0; i < args->sym.size(); i++)
  271. {
  272. s << walkCondExpr (args->sym[i].actual, pproc, numLoc);
  273. if (i < (args->sym.size() - 1))
  274. s << ", ";
  275. }
  276. s << ")";
  277. return s.str();
  278. }
  279. /* Displays the output of a HLI_JCOND icode. */
  280. char *writeJcond (HLTYPE h, Function * pProc, Int *numLoc)
  281. {
  282. memset (buf, ' ', sizeof(buf));
  283. buf[0] = '\0';
  284. strcat (buf, "if ");
  285. inverseCondOp (&h.oper.exp);
  286. std::string e = walkCondExpr (h.oper.exp, pProc, numLoc);
  287. strcat (buf, e.c_str());
  288. strcat (buf, " {\n");
  289. return (buf);
  290. }
  291. /* Displays the inverse output of a HLI_JCOND icode. This is used in the case
  292. * when the THEN clause of an if..then..else is empty. The clause is
  293. * negated and the ELSE clause is used instead. */
  294. char *writeJcondInv (HLTYPE h, Function * pProc, Int *numLoc)
  295. {
  296. memset (buf, ' ', sizeof(buf));
  297. buf[0] = '\0';
  298. strcat (buf, "if ");
  299. std::string e = walkCondExpr (h.oper.exp, pProc, numLoc);
  300. strcat (buf, e.c_str());
  301. strcat (buf, " {\n");
  302. return (buf);
  303. }
  304. /* Returns a string with the contents of the current high-level icode.
  305. * Note: this routine does not output the contens of HLI_JCOND icodes. This is
  306. * done in a separate routine to be able to support the removal of
  307. * empty THEN clauses on an if..then..else. */
  308. char *write1HlIcode (HLTYPE h, Function * pProc, Int *numLoc)
  309. {
  310. std::string e;
  311. memset (buf, ' ', sizeof(buf));
  312. buf[0] = '\0';
  313. switch (h.opcode) {
  314. case HLI_ASSIGN:
  315. e = walkCondExpr (h.oper.asgn.lhs, pProc, numLoc);
  316. strcat (buf, e.c_str());
  317. strcat (buf, " = ");
  318. e = walkCondExpr (h.oper.asgn.rhs, pProc, numLoc);
  319. strcat (buf, e.c_str());
  320. strcat (buf, ";\n");
  321. break;
  322. case HLI_CALL:
  323. e = writeCall (h.oper.call.proc, h.oper.call.args, pProc,
  324. numLoc);
  325. strcat (buf, e.c_str());
  326. strcat (buf, ";\n");
  327. break;
  328. case HLI_RET:
  329. e = walkCondExpr (h.oper.exp, pProc, numLoc);
  330. if (! e.empty())
  331. {
  332. strcat (buf, "return (");
  333. strcat (buf, e.c_str());
  334. strcat (buf, ");\n");
  335. }
  336. break;
  337. case HLI_POP:
  338. strcat (buf, "HLI_POP ");
  339. e = walkCondExpr (h.oper.exp, pProc, numLoc);
  340. strcat (buf, e.c_str());
  341. strcat (buf, "\n");
  342. break;
  343. case HLI_PUSH: strcat (buf, "HLI_PUSH ");
  344. e = walkCondExpr (h.oper.exp, pProc, numLoc);
  345. strcat (buf, e.c_str());
  346. strcat (buf, "\n");
  347. break;
  348. }
  349. return (buf);
  350. }
  351. Int power2 (Int i)
  352. /* Returns the value of 2 to the power of i */
  353. {
  354. if (i == 0)
  355. return (1);
  356. return (2 << (i-1));
  357. }
  358. /* Writes the registers/stack variables that are used and defined by this
  359. * instruction. */
  360. void ICODE::writeDU(Int idx)
  361. {
  362. static char buf[100];
  363. Int i, j;
  364. memset (buf, ' ', sizeof(buf));
  365. buf[0] = '\0';
  366. for (i = 0; i < (INDEXBASE-1); i++)
  367. {
  368. if ((du.def & power2(i)) != 0)
  369. {
  370. strcat (buf, allRegs[i]);
  371. strcat (buf, " ");
  372. }
  373. }
  374. if (buf[0] != '\0')
  375. printf ("Def (reg) = %s\n", buf);
  376. memset (buf, ' ', sizeof(buf));
  377. buf[0] = '\0';
  378. for (i = 0; i < INDEXBASE; i++)
  379. {
  380. if ((du.use & power2(i)) != 0)
  381. {
  382. strcat (buf, allRegs[i]);
  383. strcat (buf, " ");
  384. }
  385. }
  386. if (buf[0] != '\0')
  387. printf ("Use (reg) = %s\n", buf);
  388. /* Print du1 chain */
  389. printf ("# regs defined = %d\n", du1.numRegsDef);
  390. for (i = 0; i < MAX_REGS_DEF; i++)
  391. {
  392. if (du1.idx[i][0] != 0)
  393. {
  394. printf ("%d: du1[%d][] = ", idx, i);
  395. for (j = 0; j < MAX_USES; j++)
  396. {
  397. if (du1.idx[i][j] == 0)
  398. break;
  399. printf ("%d ", du1.idx[i][j]);
  400. }
  401. printf ("\n");
  402. }
  403. }
  404. /* For HLI_CALL, print # parameter bytes */
  405. if (ic.hl.opcode == HLI_CALL)
  406. printf ("# param bytes = %d\n", ic.hl.oper.call.args->cb);
  407. printf ("\n");
  408. }
  409. /* Frees the storage allocated to h->hlIcode */
  410. void freeHlIcode (ICODE * icode, Int numIcodes)
  411. {
  412. Int i;
  413. HLTYPE h;
  414. for (i = 0; i < numIcodes; i++)
  415. {
  416. h = icode[i].ic.hl;
  417. switch (h.opcode)
  418. {
  419. case HLI_ASSIGN:
  420. h.oper.asgn.lhs->release();
  421. h.oper.asgn.rhs->release();
  422. break;
  423. case HLI_POP:
  424. case HLI_PUSH:
  425. case HLI_JCOND:
  426. h.oper.exp->release();
  427. break;
  428. }
  429. }
  430. }