hlicode.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  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. std::bitset<32> maskDuReg[] = { 0x00,
  16. 0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */
  17. 0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
  18. 0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */
  19. 0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t 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 HLTYPE::setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
  27. {
  28. set(lhs,rhs);
  29. }
  30. void ICODE::checkHlCall()
  31. {
  32. //assert((ll()->immed.proc.cb != 0)||ll()->immed.proc.proc!=0);
  33. }
  34. /* Places the new HLI_CALL high-level operand in the high-level icode array */
  35. void ICODE::newCallHl()
  36. {
  37. type = HIGH_LEVEL;
  38. hl()->opcode = HLI_CALL;
  39. hl()->call.proc = ll()->src.proc.proc;
  40. hl()->call.args = new STKFRAME;
  41. if (ll()->src.proc.cb != 0)
  42. hl()->call.args->cb = ll()->src.proc.cb;
  43. else if(hl()->call.proc)
  44. hl()->call.args->cb =hl()->call.proc->cbParam;
  45. else
  46. {
  47. printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n");
  48. hl()->call.args->cb = 0;
  49. }
  50. }
  51. /* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode
  52. * array */
  53. void ICODE::setUnary(hlIcode op, COND_EXPR *_exp)
  54. {
  55. type = HIGH_LEVEL;
  56. hl()->set(op,_exp);
  57. }
  58. /* Places the new HLI_JCOND high-level operand in the high-level icode array */
  59. void ICODE::setJCond(COND_EXPR *cexp)
  60. {
  61. type = HIGH_LEVEL;
  62. hl()->set(HLI_JCOND,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.
  71. * If all registers
  72. * of this instruction are unused, the instruction is invalidated (ie. removed)
  73. */
  74. bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
  75. {
  76. int numDefs;
  77. numDefs = du1.numRegsDef;
  78. if (numDefs == thisDefIdx)
  79. {
  80. for ( ; numDefs > 0; numDefs--)
  81. {
  82. if (du1.used(numDefs-1)||(du.lastDefRegi[regi]))
  83. break;
  84. }
  85. }
  86. if (numDefs == 0)
  87. {
  88. invalidate();
  89. return true;
  90. }
  91. HlTypeSupport *p=hl()->get();
  92. if(p and p->removeRegFromLong(regi,locId))
  93. {
  94. du1.numRegsDef--;
  95. du.def &= maskDuReg[regi];
  96. }
  97. return false;
  98. }
  99. HLTYPE LLInst::createCall()
  100. {
  101. HLTYPE res(HLI_CALL);
  102. res.call.proc = src.proc.proc;
  103. res.call.args = new STKFRAME;
  104. if (src.proc.cb != 0)
  105. res.call.args->cb = src.proc.cb;
  106. else if(res.call.proc)
  107. res.call.args->cb =res.call.proc->cbParam;
  108. else
  109. {
  110. printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n");
  111. res.call.args->cb = 0;
  112. }
  113. return res;
  114. }
  115. #if 0
  116. HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
  117. {
  118. HLTYPE res(HLI_INVALID);
  119. if ( testFlags(NOT_HLL) )
  120. return res;
  121. flg = getFlag();
  122. switch (getOpcode())
  123. {
  124. case iADD:
  125. rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
  126. res.setAsgn(lhs, rhs);
  127. break;
  128. case iAND:
  129. rhs = COND_EXPR::boolOp (lhs, rhs, AND);
  130. res.setAsgn(lhs, rhs);
  131. break;
  132. case iCALL:
  133. case iCALLF:
  134. //TODO: this is noop pIcode->checkHlCall();
  135. res=createCall();
  136. break;
  137. case iDEC:
  138. rhs = COND_EXPR::idKte (1, 2);
  139. rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
  140. res.setAsgn(lhs, rhs);
  141. break;
  142. case iDIV:
  143. case iIDIV:/* should be signed div */
  144. rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
  145. if ( ll->testFlags(B) )
  146. {
  147. lhs = COND_EXPR::idReg (rAL, 0, &localId);
  148. pIcode->setRegDU( rAL, eDEF);
  149. }
  150. else
  151. {
  152. lhs = COND_EXPR::idReg (rAX, 0, &localId);
  153. pIcode->setRegDU( rAX, eDEF);
  154. }
  155. res.setAsgn(lhs, rhs);
  156. break;
  157. case iIMUL:
  158. rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
  159. lhs = COND_EXPR::id (*pIcode, LHS_OP, func, i, *pIcode, NONE);
  160. res.setAsgn(lhs, rhs);
  161. break;
  162. case iINC:
  163. rhs = COND_EXPR::idKte (1, 2);
  164. rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
  165. res.setAsgn(lhs, rhs);
  166. break;
  167. case iLEA:
  168. rhs = COND_EXPR::unary (ADDRESSOF, rhs);
  169. res.setAsgn(lhs, rhs);
  170. break;
  171. case iMOD:
  172. rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
  173. if ( ll->testFlags(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. res.setAsgn(lhs, rhs);
  184. break;
  185. case iMOV: res.setAsgn(lhs, rhs);
  186. break;
  187. case iMUL:
  188. rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
  189. lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
  190. res.setAsgn(lhs, rhs);
  191. break;
  192. case iNEG:
  193. rhs = COND_EXPR::unary (NEGATION, lhs);
  194. res.setAsgn(lhs, rhs);
  195. break;
  196. case iNOT:
  197. rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
  198. res.setAsgn(lhs, rhs);
  199. break;
  200. case iOR:
  201. rhs = COND_EXPR::boolOp (lhs, rhs, OR);
  202. res.setAsgn(lhs, rhs);
  203. break;
  204. case iPOP: res.set(HLI_POP, lhs);
  205. break;
  206. case iPUSH: res.set(HLI_PUSH, lhs);
  207. break;
  208. case iRET:
  209. case iRETF:
  210. res.set(HLI_RET, NULL);
  211. break;
  212. case iSHL:
  213. rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
  214. res.setAsgn(lhs, rhs);
  215. break;
  216. case iSAR: /* signed */
  217. case iSHR:
  218. rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
  219. res.setAsgn(lhs, rhs);
  220. break;
  221. case iSIGNEX:
  222. res.setAsgn(lhs, rhs);
  223. break;
  224. case iSUB:
  225. rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
  226. res.setAsgn(lhs, rhs);
  227. break;
  228. case iXCHG:
  229. break;
  230. case iXOR:
  231. rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
  232. res.setAsgn(lhs, rhs);
  233. break;
  234. }
  235. return res;
  236. }
  237. #endif
  238. /* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
  239. * Note: this process should be done before data flow analysis, which
  240. * refines the HIGH_LEVEL icodes. */
  241. void Function::highLevelGen()
  242. {
  243. int numIcode; /* number of icode instructions */
  244. iICODE pIcode; /* ptr to current icode node */
  245. COND_EXPR *lhs, *rhs; /* left- and right-hand side of expression */
  246. uint32_t _flg; /* icode flags */
  247. numIcode = Icode.size();
  248. for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
  249. {
  250. assert(numIcode==Icode.size());
  251. pIcode = i; //Icode.GetIcode(i)
  252. LLInst *ll = pIcode->ll();
  253. if ( ll->testFlags(NOT_HLL) )
  254. pIcode->invalidate();
  255. if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
  256. continue;
  257. _flg = ll->getFlag();
  258. if ((_flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */
  259. if ((_flg & NO_OPS) != NO_OPS) /* if there are opers */
  260. {
  261. if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
  262. rhs = COND_EXPR::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
  263. lhs = COND_EXPR::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
  264. }
  265. switch (ll->getOpcode())
  266. {
  267. case iADD:
  268. rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
  269. pIcode->setAsgn(lhs, rhs);
  270. break;
  271. case iAND:
  272. rhs = COND_EXPR::boolOp (lhs, rhs, AND);
  273. pIcode->setAsgn(lhs, rhs);
  274. break;
  275. case iCALL:
  276. case iCALLF:
  277. pIcode->type = HIGH_LEVEL;
  278. pIcode->hl( ll->createCall() );
  279. break;
  280. case iDEC:
  281. rhs = COND_EXPR::idKte (1, 2);
  282. rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
  283. pIcode->setAsgn(lhs, rhs);
  284. break;
  285. case iDIV:
  286. case iIDIV:/* should be signed div */
  287. rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
  288. if ( ll->testFlags(B) )
  289. {
  290. lhs = COND_EXPR::idReg (rAL, 0, &localId);
  291. pIcode->setRegDU( rAL, eDEF);
  292. }
  293. else
  294. {
  295. lhs = COND_EXPR::idReg (rAX, 0, &localId);
  296. pIcode->setRegDU( rAX, eDEF);
  297. }
  298. pIcode->setAsgn(lhs, rhs);
  299. break;
  300. case iIMUL:
  301. rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
  302. lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE);
  303. pIcode->setAsgn(lhs, rhs);
  304. break;
  305. case iINC:
  306. rhs = COND_EXPR::idKte (1, 2);
  307. rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
  308. pIcode->setAsgn(lhs, rhs);
  309. break;
  310. case iLEA:
  311. rhs = COND_EXPR::unary (ADDRESSOF, rhs);
  312. pIcode->setAsgn(lhs, rhs);
  313. break;
  314. case iMOD:
  315. rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
  316. if ( ll->testFlags(B) )
  317. {
  318. lhs = COND_EXPR::idReg (rAH, 0, &localId);
  319. pIcode->setRegDU( rAH, eDEF);
  320. }
  321. else
  322. {
  323. lhs = COND_EXPR::idReg (rDX, 0, &localId);
  324. pIcode->setRegDU( rDX, eDEF);
  325. }
  326. pIcode->setAsgn(lhs, rhs);
  327. break;
  328. case iMOV: pIcode->setAsgn(lhs, rhs);
  329. break;
  330. case iMUL:
  331. rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
  332. lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE);
  333. pIcode->setAsgn(lhs, rhs);
  334. break;
  335. case iNEG:
  336. rhs = COND_EXPR::unary (NEGATION, lhs);
  337. pIcode->setAsgn(lhs, rhs);
  338. break;
  339. case iNOT:
  340. rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
  341. pIcode->setAsgn(lhs, rhs);
  342. break;
  343. case iOR:
  344. rhs = COND_EXPR::boolOp (lhs, rhs, OR);
  345. pIcode->setAsgn(lhs, rhs);
  346. break;
  347. case iPOP: pIcode->setUnary(HLI_POP, lhs);
  348. break;
  349. case iPUSH: pIcode->setUnary(HLI_PUSH, lhs);
  350. break;
  351. case iRET:
  352. case iRETF: pIcode->setUnary(HLI_RET, NULL);
  353. break;
  354. case iSHL:
  355. rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
  356. pIcode->setAsgn(lhs, rhs);
  357. break;
  358. case iSAR: /* signed */
  359. case iSHR:
  360. rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
  361. pIcode->setAsgn(lhs, rhs);
  362. break;
  363. case iSIGNEX: pIcode->setAsgn(lhs, rhs);
  364. break;
  365. case iSUB:
  366. rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
  367. pIcode->setAsgn(lhs, rhs);
  368. break;
  369. case iXCHG:
  370. break;
  371. case iXOR:
  372. rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
  373. pIcode->setAsgn(lhs, rhs);
  374. break;
  375. }
  376. }
  377. }
  378. /* Modifies the given conditional operator to its inverse. This is used
  379. * in if..then[..else] statements, to reflect the condition that takes the
  380. * then part. */
  381. COND_EXPR *COND_EXPR::inverse () const
  382. {
  383. static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
  384. LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
  385. DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
  386. DUMMY, DBL_OR, DBL_AND};
  387. COND_EXPR *res=0;
  388. if (m_type == BOOLEAN_OP)
  389. {
  390. switch ( op() )
  391. {
  392. case LESS_EQUAL: case LESS: case EQUAL:
  393. case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
  394. res = this->clone();
  395. res->boolExpr.op = invCondOp[op()];
  396. return res;
  397. case AND: case OR: case XOR: case NOT: case ADD:
  398. case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
  399. return COND_EXPR::unary (NEGATION, this->clone());
  400. case DBL_AND: case DBL_OR:
  401. // Binary::Create(invertop,lhs->inverse(),rhs->inverse());
  402. res = this->clone();
  403. res->boolExpr.op = invCondOp[op()];
  404. res->boolExpr.lhs=lhs()->inverse ();
  405. res->boolExpr.rhs=rhs()->inverse ();
  406. return res;
  407. } /* eos */
  408. }
  409. else if (m_type == NEGATION) //TODO: memleak here
  410. {
  411. return expr.unaryExp->clone();
  412. }
  413. return this->clone();
  414. /* other types are left unmodified */
  415. }
  416. /* Returns the string that represents the procedure call of tproc (ie. with
  417. * actual parameters) */
  418. std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc)
  419. {
  420. int i; /* counter of # arguments */
  421. string condExp;
  422. ostringstream ostr;
  423. ostr<<tproc->name<<" (";
  424. for(const STKSYM &sym : args)
  425. {
  426. ostr << walkCondExpr (sym.actual, pproc, numLoc);
  427. if((&sym)!=&(args.back()))
  428. ostr << ", ";
  429. }
  430. ostr << ")";
  431. return ostr.str();
  432. }
  433. /* Displays the output of a HLI_JCOND icode. */
  434. char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
  435. {
  436. assert(h.expr());
  437. memset (buf, ' ', sizeof(buf));
  438. buf[0] = '\0';
  439. strcat (buf, "if ");
  440. COND_EXPR *inverted=h.expr()->inverse();
  441. //inverseCondOp (&h.exp);
  442. std::string e = walkCondExpr (inverted, pProc, numLoc);
  443. delete inverted;
  444. strcat (buf, e.c_str());
  445. strcat (buf, " {\n");
  446. return (buf);
  447. }
  448. /* Displays the inverse output of a HLI_JCOND icode. This is used in the case
  449. * when the THEN clause of an if..then..else is empty. The clause is
  450. * negated and the ELSE clause is used instead. */
  451. char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc)
  452. {
  453. memset (buf, ' ', sizeof(buf));
  454. buf[0] = '\0';
  455. strcat (buf, "if ");
  456. std::string e = walkCondExpr (h.expr(), pProc, numLoc);
  457. strcat (buf, e.c_str());
  458. strcat (buf, " {\n");
  459. return (buf);
  460. }
  461. string AssignType::writeOut(Function *pProc, int *numLoc)
  462. {
  463. ostringstream ostr;
  464. ostr << walkCondExpr (lhs, pProc, numLoc);
  465. ostr << " = ";
  466. ostr << walkCondExpr (rhs, pProc, numLoc);
  467. ostr << ";\n";
  468. return ostr.str();
  469. }
  470. string CallType::writeOut(Function *pProc, int *numLoc)
  471. {
  472. ostringstream ostr;
  473. ostr << writeCall (proc, *args, pProc,numLoc);
  474. ostr << ";\n";
  475. return ostr.str();
  476. }
  477. string ExpType::writeOut(Function *pProc, int *numLoc)
  478. {
  479. return walkCondExpr (v, pProc, numLoc);
  480. }
  481. /* Returns a string with the contents of the current high-level icode.
  482. * Note: this routine does not output the contens of HLI_JCOND icodes. This is
  483. * done in a separate routine to be able to support the removal of
  484. * empty THEN clauses on an if..then..else. */
  485. string HLTYPE::write1HlIcode (Function * pProc, int *numLoc)
  486. {
  487. string e;
  488. ostringstream ostr;
  489. HlTypeSupport *p = get();
  490. switch (opcode)
  491. {
  492. case HLI_ASSIGN:
  493. return p->writeOut(pProc,numLoc);
  494. case HLI_CALL:
  495. return p->writeOut(pProc,numLoc);
  496. case HLI_RET:
  497. e = p->writeOut(pProc,numLoc);
  498. if (! e.empty())
  499. ostr << "return (" << e << ");\n";
  500. break;
  501. case HLI_POP:
  502. ostr << "HLI_POP ";
  503. ostr << p->writeOut(pProc,numLoc);
  504. ostr << "\n";
  505. break;
  506. case HLI_PUSH:
  507. ostr << "HLI_PUSH ";
  508. ostr << p->writeOut(pProc,numLoc);
  509. ostr << "\n";
  510. break;
  511. }
  512. return ostr.str();
  513. }
  514. //TODO: replace all "< (INDEX_BX_SI-1)" with machine_x86::lastReg
  515. //TODO: replace all >= INDEX_BX_SI with machine_x86::isRegExpression
  516. /* Writes the registers/stack variables that are used and defined by this
  517. * instruction. */
  518. void ICODE::writeDU()
  519. {
  520. int my_idx = loc_ip;
  521. {
  522. ostringstream ostr;
  523. Machine_X86::writeBitVector(ostr,du.def);
  524. if (!ostr.str().empty())
  525. printf ("Def (reg) = %s\n", ostr.str().c_str());
  526. }
  527. {
  528. ostringstream ostr;
  529. Machine_X86::writeBitVector(ostr,du.use);
  530. if (!ostr.str().empty())
  531. printf ("Use (reg) = %s\n", ostr.str().c_str());
  532. }
  533. /* Print du1 chain */
  534. printf ("# regs defined = %d\n", du1.numRegsDef);
  535. for (int i = 0; i < MAX_REGS_DEF; i++)
  536. {
  537. if (not du1.used(i))
  538. continue;
  539. printf ("%d: du1[%d][] = ", my_idx, i);
  540. for(auto j : du1.idx[i].uses)
  541. {
  542. printf ("%d ", j->loc_ip);
  543. }
  544. printf ("\n");
  545. }
  546. /* For HLI_CALL, print # parameter bytes */
  547. if (hl()->opcode == HLI_CALL)
  548. printf ("# param bytes = %d\n", hl()->call.args->cb);
  549. printf ("\n");
  550. }