hlicode.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  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,
  163. NONE);
  164. pIcode->setAsgn(lhs, rhs);
  165. break;
  166. case iINC: rhs = COND_EXPR::idKte (1, 2);
  167. rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
  168. pIcode->setAsgn(lhs, rhs);
  169. break;
  170. case iLEA: rhs = COND_EXPR::unary (ADDRESSOF, rhs);
  171. pIcode->setAsgn(lhs, rhs);
  172. break;
  173. case iMOD: rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
  174. if (pIcode->ic.ll.flg & B)
  175. {
  176. lhs = COND_EXPR::idReg (rAH, 0, &localId);
  177. pIcode->setRegDU( rAH, eDEF);
  178. }
  179. else
  180. {
  181. lhs = COND_EXPR::idReg (rDX, 0, &localId);
  182. pIcode->setRegDU( rDX, eDEF);
  183. }
  184. pIcode->setAsgn(lhs, rhs);
  185. break;
  186. case iMOV: pIcode->setAsgn(lhs, rhs);
  187. break;
  188. case iMUL: rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
  189. lhs = COND_EXPR::id (pIcode, LHS_OP, this, i, pIcode,
  190. NONE);
  191. pIcode->setAsgn(lhs, rhs);
  192. break;
  193. case iNEG: rhs = COND_EXPR::unary (NEGATION, lhs);
  194. pIcode->setAsgn(lhs, rhs);
  195. break;
  196. case iNOT: rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
  197. pIcode->setAsgn(lhs, rhs);
  198. break;
  199. case iOR: rhs = COND_EXPR::boolOp (lhs, rhs, OR);
  200. pIcode->setAsgn(lhs, rhs);
  201. break;
  202. case iPOP: pIcode->setUnary(HLI_POP, lhs);
  203. break;
  204. case iPUSH: pIcode->setUnary(HLI_PUSH, lhs);
  205. break;
  206. case iRET:
  207. case iRETF: pIcode->setUnary(HLI_RET, NULL);
  208. break;
  209. case iSHL: rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
  210. pIcode->setAsgn(lhs, rhs);
  211. break;
  212. case iSAR: /* signed */
  213. case iSHR: rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
  214. pIcode->setAsgn(lhs, rhs);
  215. break;
  216. case iSIGNEX: pIcode->setAsgn(lhs, rhs);
  217. break;
  218. case iSUB: rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
  219. pIcode->setAsgn(lhs, rhs);
  220. break;
  221. case iXCHG:
  222. break;
  223. case iXOR: rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
  224. pIcode->setAsgn(lhs, rhs);
  225. break;
  226. }
  227. }
  228. }
  229. }
  230. /* Modifies the given conditional operator to its inverse. This is used
  231. * in if..then[..else] statements, to reflect the condition that takes the
  232. * then part. */
  233. void inverseCondOp (COND_EXPR **exp)
  234. {
  235. static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
  236. LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
  237. DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
  238. DUMMY, DBL_OR, DBL_AND};
  239. if (*exp == NULL)
  240. return;
  241. if ((*exp)->type == BOOLEAN_OP)
  242. {
  243. switch ((*exp)->expr.boolExpr.op)
  244. {
  245. case LESS_EQUAL: case LESS: case EQUAL:
  246. case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
  247. (*exp)->expr.boolExpr.op = invCondOp[(*exp)->expr.boolExpr.op];
  248. break;
  249. case AND: case OR: case XOR: case NOT: case ADD:
  250. case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
  251. *exp = COND_EXPR::unary (NEGATION, *exp);
  252. break;
  253. case DBL_AND: case DBL_OR:
  254. (*exp)->expr.boolExpr.op = invCondOp[(*exp)->expr.boolExpr.op];
  255. inverseCondOp (&(*exp)->expr.boolExpr.lhs);
  256. inverseCondOp (&(*exp)->expr.boolExpr.rhs);
  257. break;
  258. } /* eos */
  259. }
  260. else if ((*exp)->type == NEGATION) //TODO: memleak here
  261. *exp = (*exp)->expr.unaryExp;
  262. /* other types are left unmodified */
  263. }
  264. /* Returns the string that represents the procedure call of tproc (ie. with
  265. * actual parameters) */
  266. std::string writeCall (Function * tproc, STKFRAME * args, Function * pproc, Int *numLoc)
  267. {
  268. Int i; /* counter of # arguments */
  269. string condExp;
  270. ostringstream s;
  271. s<<tproc->name<<" (";
  272. for (i = 0; i < args->sym.size(); i++)
  273. {
  274. s << walkCondExpr (args->sym[i].actual, pproc, numLoc);
  275. if (i < (args->sym.size() - 1))
  276. s << ", ";
  277. }
  278. s << ")";
  279. return s.str();
  280. }
  281. /* Displays the output of a HLI_JCOND icode. */
  282. char *writeJcond (HLTYPE h, Function * pProc, Int *numLoc)
  283. {
  284. memset (buf, ' ', sizeof(buf));
  285. buf[0] = '\0';
  286. strcat (buf, "if ");
  287. inverseCondOp (&h.oper.exp);
  288. std::string e = walkCondExpr (h.oper.exp, pProc, numLoc);
  289. strcat (buf, e.c_str());
  290. strcat (buf, " {\n");
  291. return (buf);
  292. }
  293. /* Displays the inverse output of a HLI_JCOND icode. This is used in the case
  294. * when the THEN clause of an if..then..else is empty. The clause is
  295. * negated and the ELSE clause is used instead. */
  296. char *writeJcondInv (HLTYPE h, Function * pProc, Int *numLoc)
  297. {
  298. memset (buf, ' ', sizeof(buf));
  299. buf[0] = '\0';
  300. strcat (buf, "if ");
  301. std::string e = walkCondExpr (h.oper.exp, pProc, numLoc);
  302. strcat (buf, e.c_str());
  303. strcat (buf, " {\n");
  304. return (buf);
  305. }
  306. /* Returns a string with the contents of the current high-level icode.
  307. * Note: this routine does not output the contens of HLI_JCOND icodes. This is
  308. * done in a separate routine to be able to support the removal of
  309. * empty THEN clauses on an if..then..else. */
  310. char *write1HlIcode (HLTYPE h, Function * pProc, Int *numLoc)
  311. {
  312. std::string e;
  313. memset (buf, ' ', sizeof(buf));
  314. buf[0] = '\0';
  315. switch (h.opcode) {
  316. case HLI_ASSIGN:
  317. e = walkCondExpr (h.oper.asgn.lhs, pProc, numLoc);
  318. strcat (buf, e.c_str());
  319. strcat (buf, " = ");
  320. e = walkCondExpr (h.oper.asgn.rhs, pProc, numLoc);
  321. strcat (buf, e.c_str());
  322. strcat (buf, ";\n");
  323. break;
  324. case HLI_CALL:
  325. e = writeCall (h.oper.call.proc, h.oper.call.args, pProc,
  326. numLoc);
  327. strcat (buf, e.c_str());
  328. strcat (buf, ";\n");
  329. break;
  330. case HLI_RET:
  331. e = walkCondExpr (h.oper.exp, pProc, numLoc);
  332. if (! e.empty())
  333. {
  334. strcat (buf, "return (");
  335. strcat (buf, e.c_str());
  336. strcat (buf, ");\n");
  337. }
  338. break;
  339. case HLI_POP:
  340. strcat (buf, "HLI_POP ");
  341. e = walkCondExpr (h.oper.exp, pProc, numLoc);
  342. strcat (buf, e.c_str());
  343. strcat (buf, "\n");
  344. break;
  345. case HLI_PUSH: strcat (buf, "HLI_PUSH ");
  346. e = walkCondExpr (h.oper.exp, pProc, numLoc);
  347. strcat (buf, e.c_str());
  348. strcat (buf, "\n");
  349. break;
  350. }
  351. return (buf);
  352. }
  353. Int power2 (Int i)
  354. /* Returns the value of 2 to the power of i */
  355. {
  356. if (i == 0)
  357. return (1);
  358. return (2 << (i-1));
  359. }
  360. /* Writes the registers/stack variables that are used and defined by this
  361. * instruction. */
  362. void ICODE::writeDU(Int idx)
  363. {
  364. static char buf[100];
  365. Int i, j;
  366. memset (buf, ' ', sizeof(buf));
  367. buf[0] = '\0';
  368. for (i = 0; i < (INDEXBASE-1); i++)
  369. {
  370. if ((du.def & power2(i)) != 0)
  371. {
  372. strcat (buf, allRegs[i]);
  373. strcat (buf, " ");
  374. }
  375. }
  376. if (buf[0] != '\0')
  377. printf ("Def (reg) = %s\n", buf);
  378. memset (buf, ' ', sizeof(buf));
  379. buf[0] = '\0';
  380. for (i = 0; i < INDEXBASE; i++)
  381. {
  382. if ((du.use & power2(i)) != 0)
  383. {
  384. strcat (buf, allRegs[i]);
  385. strcat (buf, " ");
  386. }
  387. }
  388. if (buf[0] != '\0')
  389. printf ("Use (reg) = %s\n", buf);
  390. /* Print du1 chain */
  391. printf ("# regs defined = %d\n", du1.numRegsDef);
  392. for (i = 0; i < MAX_REGS_DEF; i++)
  393. {
  394. if (du1.idx[i][0] != 0)
  395. {
  396. printf ("%d: du1[%d][] = ", idx, i);
  397. for (j = 0; j < MAX_USES; j++)
  398. {
  399. if (du1.idx[i][j] == 0)
  400. break;
  401. printf ("%d ", du1.idx[i][j]);
  402. }
  403. printf ("\n");
  404. }
  405. }
  406. /* For HLI_CALL, print # parameter bytes */
  407. if (ic.hl.opcode == HLI_CALL)
  408. printf ("# param bytes = %d\n", ic.hl.oper.call.args->cb);
  409. printf ("\n");
  410. }
  411. /* Frees the storage allocated to h->hlIcode */
  412. void freeHlIcode (ICODE * icode, Int numIcodes)
  413. {
  414. Int i;
  415. HLTYPE h;
  416. for (i = 0; i < numIcodes; i++)
  417. {
  418. h = icode[i].ic.hl;
  419. switch (h.opcode)
  420. {
  421. case HLI_ASSIGN:
  422. h.oper.asgn.lhs->release();
  423. h.oper.asgn.rhs->release();
  424. break;
  425. case HLI_POP:
  426. case HLI_PUSH:
  427. case HLI_JCOND:
  428. h.oper.exp->release();
  429. break;
  430. }
  431. }
  432. }