PageRenderTime 47ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/misc/pascal/insn16/popt/pcopt.c

https://github.com/markangelo/PX4NuttX
C | 906 lines | 735 code | 106 blank | 65 comment | 218 complexity | 7e89157bc965a85525cc05c8799d2ae9 MD5 | raw file
Possible License(s): GPL-2.0, 0BSD
  1. /**********************************************************************
  2. * pcopt.c
  3. * Constant Expression Optimizations
  4. *
  5. * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
  6. * Author: Gregory Nutt <gnutt@nuttx.org>
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. * 3. Neither the name NuttX nor the names of its contributors may be
  19. * used to endorse or promote products derived from this software
  20. * without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  28. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  29. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  30. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  32. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. **********************************************************************/
  36. /**********************************************************************
  37. * Included Files
  38. **********************************************************************/
  39. #include <stdint.h>
  40. #include <stdio.h>
  41. #include "keywords.h"
  42. #include "pdefs.h"
  43. #include "pinsn16.h"
  44. #include "paslib.h"
  45. #include "popt.h"
  46. #include "polocal.h"
  47. #include "pcopt.h"
  48. /**********************************************************************/
  49. int16_t unaryOptimize(void)
  50. {
  51. int16_t nchanges = 0;
  52. register uint16_t temp;
  53. register int16_t i;
  54. TRACE(stderr, "[unaryOptimize]");
  55. /* At least two pcodes are need to perform unary optimizations */
  56. i = 0;
  57. while (i < nops-1)
  58. {
  59. /* Check for a constant value being pushed onto the stack */
  60. if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB))
  61. {
  62. /* Turn the oPUSHB into an oPUSH op (temporarily) */
  63. if (pptr[i]->op == oPUSHB)
  64. {
  65. pptr[i]->op = oPUSH;
  66. pptr[i]->arg2 = pptr[i]->arg1;
  67. pptr[i]->arg1 = 0;
  68. } /* end if */
  69. switch (pptr[i+1]->op)
  70. {
  71. /* Delete unary operators on constants */
  72. case oNEG :
  73. pptr[i]->arg2 = -(pptr[i]->arg2);
  74. deletePcode(i+1);
  75. nchanges++;
  76. break;
  77. case oABS :
  78. if (signExtend16(pptr[i]->arg2) < 0)
  79. pptr[i]->arg2 = -signExtend16(pptr[i]->arg2);
  80. deletePcode(i+1);
  81. nchanges++;
  82. break;
  83. case oINC :
  84. (pptr[i]->arg2)++;
  85. deletePcode(i+1);
  86. nchanges++;
  87. break;
  88. case oDEC :
  89. (pptr[i]->arg2)--;
  90. deletePcode(i+1);
  91. nchanges++;
  92. break;
  93. case oNOT :
  94. pptr[i]->arg2 = ~(pptr[i]->arg2);
  95. deletePcode(i+1);
  96. nchanges++;
  97. break;
  98. /* Simplify binary operations on constants */
  99. case oADD :
  100. if (pptr[i]->arg2 == 0)
  101. {
  102. deletePcodePair(i, (i+1));
  103. nchanges++;
  104. } /* end if */
  105. else if (pptr[i]->arg2 == 1)
  106. {
  107. pptr[i+1]->op = oINC;
  108. deletePcode(i);
  109. nchanges++;
  110. } /* end else if */
  111. else if (pptr[i]->arg2 == (uint16_t)-1)
  112. {
  113. pptr[i+1]->op = oDEC;
  114. deletePcode(i);
  115. nchanges++;
  116. } /* end else if */
  117. else i++;
  118. break;
  119. case oSUB :
  120. if (pptr[i]->arg2 == 0)
  121. {
  122. deletePcodePair(i, (i+1));
  123. nchanges++;
  124. } /* end if */
  125. else if (pptr[i]->arg2 == 1)
  126. {
  127. pptr[i+1]->op = oDEC;
  128. deletePcode(i);
  129. nchanges++;
  130. } /* end else if */
  131. else if (pptr[i]->arg2 == (uint16_t)-1)
  132. {
  133. pptr[i+1]->op = oINC;
  134. deletePcode(i);
  135. nchanges++;
  136. } /* end else if */
  137. else i++;
  138. break;
  139. case oMUL :
  140. case oDIV :
  141. temp = 0;
  142. switch (pptr[i]->arg2)
  143. {
  144. case 1 :
  145. deletePcodePair(i, (i+1));
  146. nchanges++;
  147. break;
  148. case 16384 : temp++;
  149. case 8192 : temp++;
  150. case 4096 : temp++;
  151. case 2048 : temp++;
  152. case 1024 : temp++;
  153. case 512 : temp++;
  154. case 256 : temp++;
  155. case 128 : temp++;
  156. case 64 : temp++;
  157. case 32 : temp++;
  158. case 16 : temp++;
  159. case 8 : temp++;
  160. case 4 : temp++;
  161. case 2 : temp++;
  162. pptr[i]->arg2 = temp;
  163. if (pptr[i+1]->op == oMUL)
  164. pptr[i+1]->op = oSLL;
  165. else
  166. pptr[i+1]->op = oSRA;
  167. nchanges++;
  168. i++;
  169. break;
  170. default :
  171. i++;
  172. break;
  173. } /* end switch */
  174. break;
  175. case oSLL :
  176. case oSRL :
  177. case oSRA :
  178. case oOR :
  179. if (pptr[i]->arg2 == 0)
  180. {
  181. deletePcodePair(i, (i+1));
  182. nchanges++;
  183. } /* end if */
  184. else i++;
  185. break;
  186. case oAND :
  187. if (pptr[i]->arg2 == 0xffff)
  188. {
  189. deletePcodePair(i, (i+1));
  190. nchanges++;
  191. } /* end if */
  192. else i++;
  193. break;
  194. /* Delete comparisons of constants to zero */
  195. case oEQUZ :
  196. if (pptr[i]->arg2 == 0) pptr[i]->arg2 = -1;
  197. else pptr[i]->arg2 = 0;
  198. deletePcode(i+1);
  199. nchanges++;
  200. break;
  201. case oNEQZ :
  202. if (pptr[i]->arg2 != 0)
  203. pptr[i]->arg2 = -1;
  204. else
  205. pptr[i]->arg2 = 0;
  206. deletePcode(i+1);
  207. nchanges++;
  208. break;
  209. case oLTZ :
  210. if (signExtend16(pptr[i]->arg2) < 0)
  211. pptr[i]->arg2 = -1;
  212. else
  213. pptr[i]->arg2 = 0;
  214. deletePcode(i+1);
  215. nchanges++;
  216. break;
  217. case oGTEZ :
  218. if (signExtend16(pptr[i]->arg2) >= 0)
  219. pptr[i]->arg2 = -1;
  220. else
  221. pptr[i]->arg2 = 0;
  222. deletePcode(i+1);
  223. nchanges++;
  224. break;
  225. case oGTZ :
  226. if (pptr[i]->arg2 > 0) pptr[i]->arg2 = -1;
  227. else pptr[i]->arg2 = 0;
  228. deletePcode(i+1);
  229. nchanges++;
  230. break;
  231. case oLTEZ :
  232. if (pptr[i]->arg2 <= 0) pptr[i]->arg2 = -1;
  233. else pptr[i]->arg2 = 0;
  234. deletePcode(i+1);
  235. nchanges++;
  236. break;
  237. /* Simplify comparisons with certain constants */
  238. case oEQU :
  239. if (pptr[i]->arg2 == 0)
  240. {
  241. pptr[i+1]->op = oEQUZ;
  242. deletePcode(i);
  243. nchanges++;
  244. } /* end if */
  245. else if (pptr[i]->arg2 == 1)
  246. {
  247. pptr[i]->op = oDEC;
  248. pptr[i]->arg2 = 0;
  249. pptr[i+1]->op = oEQUZ;
  250. nchanges++;
  251. } /* end else if */
  252. else if (signExtend16(pptr[i]->arg2) == -1)
  253. {
  254. pptr[i]->op = oINC;
  255. pptr[i]->arg2 = 0;
  256. pptr[i+1]->op = oEQUZ;
  257. nchanges++;
  258. } /* end else if */
  259. else i++;
  260. break;
  261. case oNEQ :
  262. if (pptr[i]->arg2 == 0)
  263. {
  264. pptr[i+1]->op = oNEQZ;
  265. deletePcode(i);
  266. nchanges++;
  267. } /* end if */
  268. else if (pptr[i]->arg2 == 1)
  269. {
  270. pptr[i]->op = oDEC;
  271. pptr[i]->arg2 = 0;
  272. pptr[i+1]->op = oNEQZ;
  273. nchanges++;
  274. } /* end else if */
  275. else if (signExtend16(pptr[i]->arg2) == -1)
  276. {
  277. pptr[i]->op = oINC;
  278. pptr[i]->arg2 = 0;
  279. pptr[i+1]->op = oNEQZ;
  280. nchanges++;
  281. } /* end else if */
  282. else i++;
  283. break;
  284. case oLT :
  285. if (pptr[i]->arg2 == 0)
  286. {
  287. pptr[i+1]->op = oLTZ;
  288. deletePcode(i);
  289. nchanges++;
  290. } /* end if */
  291. else if (pptr[i]->arg2 == 1)
  292. {
  293. pptr[i]->op = oDEC;
  294. pptr[i]->arg2 = 0;
  295. pptr[i+1]->op = oLTZ;
  296. nchanges++;
  297. } /* end else if */
  298. else if (signExtend16(pptr[i]->arg2) == -1)
  299. {
  300. pptr[i]->op = oINC;
  301. pptr[i]->arg2 = 0;
  302. pptr[i+1]->op = oLTZ;
  303. nchanges++;
  304. } /* end else if */
  305. else i++;
  306. break;
  307. case oGTE :
  308. if (pptr[i]->arg2 == 0)
  309. {
  310. pptr[i+1]->op = oGTEZ;
  311. deletePcode(i);
  312. nchanges++;
  313. } /* end if */
  314. else if (pptr[i]->arg2 == 1)
  315. {
  316. pptr[i]->op = oDEC;
  317. pptr[i]->arg2 = 0;
  318. pptr[i+1]->op = oGTEZ;
  319. nchanges++;
  320. } /* end else if */
  321. else if (signExtend16(pptr[i]->arg2) == -1)
  322. {
  323. pptr[i]->op = oINC;
  324. pptr[i]->arg2 = 0;
  325. pptr[i+1]->op = oGTEZ;
  326. nchanges++;
  327. } /* end else if */
  328. else i++;
  329. break;
  330. case oGT :
  331. if (pptr[i]->arg2 == 0)
  332. {
  333. pptr[i+1]->op = oGTZ;
  334. deletePcode(i);
  335. nchanges++;
  336. } /* end if */
  337. else if (pptr[i]->arg2 == 1)
  338. {
  339. pptr[i]->op = oDEC;
  340. pptr[i]->arg2 = 0;
  341. pptr[i+1]->op = oGTZ;
  342. nchanges++;
  343. } /* end else if */
  344. else if (signExtend16(pptr[i]->arg2) == -1)
  345. {
  346. pptr[i]->op = oINC;
  347. pptr[i]->arg2 = 0;
  348. pptr[i+1]->op = oGTZ;
  349. nchanges++;
  350. } /* end else if */
  351. else i++;
  352. break;
  353. case oLTE :
  354. if (pptr[i]->arg2 == 0)
  355. {
  356. pptr[i+1]->op = oLTEZ;
  357. deletePcode(i);
  358. nchanges++;
  359. } /* end if */
  360. else if (pptr[i]->arg2 == 1)
  361. {
  362. pptr[i]->op = oDEC;
  363. pptr[i]->arg2 = 0;
  364. pptr[i+1]->op = oLTEZ;
  365. nchanges++;
  366. } /* end else if */
  367. else if (signExtend16(pptr[i]->arg2) == -1)
  368. {
  369. pptr[i]->op = oINC;
  370. pptr[i]->arg2 = 0;
  371. pptr[i+1]->op = oLTEZ;
  372. nchanges++;
  373. } /* end else if */
  374. else i++;
  375. break;
  376. /* Simplify or delete condition branches on constants */
  377. case oJEQUZ :
  378. if (pptr[i]->arg2 == 0)
  379. {
  380. pptr[i+1]->op = oJMP;
  381. deletePcode(i);
  382. } /* end if */
  383. else
  384. deletePcodePair(i, (i+1));
  385. nchanges++;
  386. break;
  387. case oJNEQZ :
  388. if (pptr[i]->arg2 != 0)
  389. {
  390. pptr[i+1]->op = oJMP;
  391. deletePcode(i);
  392. } /* end if */
  393. else
  394. deletePcodePair(i, (i+1));
  395. nchanges++;
  396. break;
  397. case oJLTZ :
  398. if (signExtend16(pptr[i]->arg2) < 0)
  399. {
  400. pptr[i+1]->op = oJMP;
  401. deletePcode(i);
  402. } /* end if */
  403. else
  404. deletePcodePair(i, (i+1));
  405. nchanges++;
  406. break;
  407. case oJGTEZ :
  408. if (signExtend16(pptr[i]->arg2) >= 0)
  409. {
  410. pptr[i+1]->op = oJMP;
  411. deletePcode(i);
  412. } /* end if */
  413. else
  414. deletePcodePair(i, (i+1));
  415. nchanges++;
  416. break;
  417. case oJGTZ :
  418. if (pptr[i]->arg2 > 0)
  419. {
  420. pptr[i+1]->op = oJMP;
  421. deletePcode(i);
  422. } /* end if */
  423. else
  424. deletePcodePair(i, (i+1));
  425. nchanges++;
  426. break;
  427. case oJLTEZ :
  428. if (pptr[i]->arg2 <= 0)
  429. {
  430. pptr[i+1]->op = oJMP;
  431. deletePcode(i);
  432. } /* end if */
  433. else
  434. deletePcodePair(i, (i+1));
  435. nchanges++;
  436. break;
  437. default :
  438. i++;
  439. break;
  440. } /* end switch */
  441. /* If the oPUSH instruction is still there, see if we can now */
  442. /* represent it with an oPUSHB instruction */
  443. if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
  444. {
  445. pptr[i]->op = oPUSHB;
  446. pptr[i]->arg1 = pptr[i]->arg2;
  447. pptr[i]->arg2 = 0;
  448. } /* end if */
  449. } /* end if */
  450. /* Delete multiple modifications of DSEG pointer */
  451. else if (pptr[i]->op == oINDS)
  452. {
  453. if (pptr[i+1]->op == oINDS)
  454. {
  455. pptr[i]->arg2 += pptr[i+1]->arg2;
  456. deletePcode(i+1);
  457. } /* end if */
  458. else i++;
  459. } /* end else if */
  460. else i++;
  461. } /* end while */
  462. return (nchanges);
  463. } /* end unaryOptimize */
  464. /**********************************************************************/
  465. int16_t binaryOptimize(void)
  466. {
  467. int16_t nchanges = 0;
  468. register int16_t stmp16;
  469. register int16_t i;
  470. TRACE(stderr, "[binaryOptimize]");
  471. /* At least two pcodes are needed to perform the following binary */
  472. /* operator optimizations */
  473. i = 0;
  474. while (i < nops-2)
  475. {
  476. if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB))
  477. {
  478. if ((pptr[i+1]->op == oPUSH) || (pptr[i+1]->op == oPUSHB))
  479. {
  480. /* Turn the oPUSHBs into an oPUSHs op (temporarily) */
  481. if (pptr[i]->op == oPUSHB)
  482. {
  483. pptr[i]->op = oPUSH;
  484. pptr[i]->arg2 = pptr[i]->arg1;
  485. pptr[i]->arg1 = 0;
  486. } /* end if */
  487. if (pptr[i+1]->op == oPUSHB)
  488. {
  489. pptr[i+1]->op = oPUSH;
  490. pptr[i+1]->arg2 = pptr[i+1]->arg1;
  491. pptr[i+1]->arg1 = 0;
  492. } /* end if */
  493. switch (pptr[i+2]->op)
  494. {
  495. case oADD :
  496. pptr[i]->arg2 += pptr[i+1]->arg2;
  497. deletePcodePair((i+1), (i+2));
  498. nchanges++;
  499. break;
  500. case oSUB :
  501. pptr[i]->arg2 -= pptr[i+1]->arg2;
  502. deletePcodePair((i+1), (i+2));
  503. nchanges++;
  504. break;
  505. case oMUL :
  506. pptr[i]->arg2 *= pptr[i+1]->arg2;
  507. deletePcodePair((i+1), (i+2));
  508. nchanges++;
  509. break;
  510. case oDIV :
  511. stmp16 = pptr[i]->arg2 / signExtend16(pptr[i+1]->arg2);
  512. pptr[i]->arg2 = stmp16;
  513. deletePcodePair((i+1), (i+2));
  514. nchanges++;
  515. break;
  516. case oMOD :
  517. pptr[i]->arg2 %= pptr[i+1]->arg2;
  518. deletePcodePair((i+1), (i+2));
  519. nchanges++;
  520. break;
  521. case oSLL :
  522. pptr[i]->arg2 <<= pptr[i+1]->arg2;
  523. deletePcodePair((i+1), (i+2));
  524. nchanges++;
  525. break;
  526. case oSRL :
  527. pptr[i]->arg2 >>= pptr[i+1]->arg2;
  528. deletePcodePair((i+1), (i+2));
  529. nchanges++;
  530. break;
  531. case oSRA :
  532. stmp16 = (((int16_t)pptr[i]->arg2) >> pptr[i+1]->arg2);
  533. pptr[i]->arg2 = (uint16_t)stmp16;
  534. deletePcodePair((i+1), (i+2));
  535. nchanges++;
  536. break;
  537. case oOR :
  538. pptr[i]->arg2 |= pptr[i+1]->arg2;
  539. deletePcodePair((i+1), (i+2));
  540. nchanges++;
  541. break;
  542. case oAND :
  543. pptr[i]->arg2 &= pptr[i+1]->arg2;
  544. deletePcodePair((i+1), (i+2));
  545. nchanges++;
  546. break;
  547. case oEQU :
  548. if (pptr[i]->arg2 == pptr[i+1]->arg2) pptr[i]->arg2 = -1;
  549. else pptr[i]->arg2 = 0;
  550. deletePcodePair((i+1), (i+2));
  551. nchanges++;
  552. break;
  553. case oNEQ :
  554. if ((int16_t)pptr[i]->arg2 != (int16_t)pptr[i+1]->arg2)
  555. pptr[i]->arg2 = -1;
  556. else
  557. pptr[i]->arg2 = 0;
  558. deletePcodePair((i+1), (i+2));
  559. nchanges++;
  560. break;
  561. case oLT :
  562. if ((int16_t)pptr[i]->arg2 < (int16_t)pptr[i+1]->arg2)
  563. pptr[i]->arg2 = -1;
  564. else
  565. pptr[i]->arg2 = 0;
  566. deletePcodePair((i+1), (i+2));
  567. nchanges++;
  568. break;
  569. case oGTE :
  570. if ((int16_t)pptr[i]->arg2 >= (int16_t)pptr[i+1]->arg2)
  571. pptr[i]->arg2 = -1;
  572. else
  573. pptr[i]->arg2 = 0;
  574. deletePcodePair((i+1), (i+2));
  575. nchanges++;
  576. break;
  577. case oGT :
  578. if ((int16_t)pptr[i]->arg2 > (int16_t)pptr[i+1]->arg2)
  579. pptr[i]->arg2 = -1;
  580. else
  581. pptr[i]->arg2 = 0;
  582. deletePcodePair((i+1), (i+2));
  583. nchanges++;
  584. break;
  585. case oLTE :
  586. if ((int16_t)pptr[i]->arg2 <= (int16_t)pptr[i+1]->arg2)
  587. pptr[i]->arg2 = -1;
  588. else
  589. pptr[i]->arg2 = 0;
  590. deletePcodePair((i+1), (i+2));
  591. nchanges++;
  592. break;
  593. default :
  594. i++;
  595. break;
  596. } /* end switch */
  597. /* If the oPUSH instruction is still there, see if we can now */
  598. /* represent it with an oPUSHB instruction */
  599. if (pptr[i] && (pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
  600. {
  601. pptr[i]->op = oPUSHB;
  602. pptr[i]->arg1 = pptr[i]->arg2;
  603. pptr[i]->arg2 = 0;
  604. } /* end if */
  605. if (pptr[i+1] && (pptr[i+1]->op == oPUSH) && (pptr[i+1]->arg2 < 256))
  606. {
  607. pptr[i+1]->op = oPUSHB;
  608. pptr[i+1]->arg1 = pptr[i+1]->arg2;
  609. pptr[i+1]->arg2 = 0;
  610. } /* end if */
  611. } /* end if */
  612. /* A single (constant) pcode is sufficient to perform the */
  613. /* following binary operator optimizations */
  614. else if ((pptr[i+1]->op == oLDSH) || (pptr[i+1]->op == oLDSB) ||
  615. (pptr[i+1]->op == oLAS) || (pptr[i+1]->op == oLAC))
  616. {
  617. /* Turn the oPUSHB into a oPUSH op (temporarily) */
  618. if (pptr[i]->op == oPUSHB)
  619. {
  620. pptr[i]->op = oPUSH;
  621. pptr[i]->arg2 = pptr[i]->arg1;
  622. pptr[i]->arg1 = 0;
  623. } /* end if */
  624. switch (pptr[i+2]->op)
  625. {
  626. case oADD :
  627. if (pptr[i]->arg2 == 0)
  628. {
  629. deletePcodePair(i, (i+2));
  630. nchanges++;
  631. } /* end if */
  632. else if (pptr[i]->arg2 == 1)
  633. {
  634. pptr[i+2]->op = oINC;
  635. deletePcode(i);
  636. nchanges++;
  637. } /* end else if */
  638. else if (pptr[i]->arg2 == (uint16_t)-1)
  639. {
  640. pptr[i+2]->op = oDEC;
  641. deletePcode(i);
  642. nchanges++;
  643. } /* end else if */
  644. else i++;
  645. break;
  646. case oSUB :
  647. if (pptr[i]->arg2 == 0)
  648. {
  649. pptr[i]->op = oNEG;
  650. deletePcode(i);
  651. nchanges++;
  652. } /* end if */
  653. else i++;
  654. break;
  655. case oMUL :
  656. stmp16 = 0;
  657. switch (pptr[i]->arg2)
  658. {
  659. case 1 :
  660. deletePcodePair(i, (i+2));
  661. nchanges++;
  662. break;
  663. case 16384 : stmp16++;
  664. case 8192 : stmp16++;
  665. case 4096 : stmp16++;
  666. case 2048 : stmp16++;
  667. case 1024 : stmp16++;
  668. case 512 : stmp16++;
  669. case 256 : stmp16++;
  670. case 128 : stmp16++;
  671. case 64 : stmp16++;
  672. case 32 : stmp16++;
  673. case 16 : stmp16++;
  674. case 8 : stmp16++;
  675. case 4 : stmp16++;
  676. case 2 : stmp16++;
  677. pptr[i]->op = pptr[i+1]->op;
  678. pptr[i]->arg1 = pptr[i+1]->arg1;
  679. pptr[i]->arg2 = pptr[i+1]->arg2;
  680. pptr[i+1]->op = oPUSH;
  681. pptr[i+1]->arg1 = 0;
  682. pptr[i+1]->arg2 = stmp16;
  683. pptr[i+2]->op = oSLL;
  684. nchanges++;
  685. i++;
  686. break;
  687. default :
  688. i++;
  689. break;
  690. } /* end switch */
  691. break;
  692. case oOR :
  693. if (pptr[i]->arg2 == 0)
  694. {
  695. deletePcodePair(i, (i+2));
  696. nchanges++;
  697. } /* end if */
  698. else i++;
  699. break;
  700. case oAND :
  701. if (pptr[i]->arg2 == 0xffff)
  702. {
  703. deletePcodePair(i, (i+2));
  704. nchanges++;
  705. } /* end if */
  706. else i++;
  707. break;
  708. case oEQU :
  709. if (pptr[i]->arg2 == 0)
  710. {
  711. pptr[i+2]->op = oEQUZ;
  712. deletePcode(i);
  713. nchanges++;
  714. } /* end if */
  715. else i++;
  716. break;
  717. case oNEQ :
  718. if (pptr[i]->arg2 == 0)
  719. {
  720. pptr[i+2]->op = oNEQZ;
  721. deletePcode(i);
  722. nchanges++;
  723. } /* end if */
  724. else i++;
  725. break;
  726. case oLT :
  727. if (pptr[i]->arg2 == 0)
  728. {
  729. pptr[i+2]->op = oGTEZ;
  730. deletePcode(i);
  731. nchanges++;
  732. } /* end if */
  733. else i++;
  734. break;
  735. case oGTE :
  736. if (pptr[i]->arg2 == 0)
  737. {
  738. pptr[i+2]->op = oLTZ;
  739. deletePcode(i);
  740. nchanges++;
  741. } /* end if */
  742. else i++;
  743. break;
  744. case oGT :
  745. if (pptr[i]->arg2 == 0)
  746. {
  747. pptr[i+2]->op = oLTEZ;
  748. deletePcode(i);
  749. nchanges++;
  750. } /* end if */
  751. else i++;
  752. break;
  753. case oLTE :
  754. if (pptr[i]->arg2 == 0)
  755. {
  756. pptr[i+2]->op = oGTZ;
  757. deletePcode(i);
  758. nchanges++;
  759. } /* end if */
  760. else i++;
  761. break;
  762. default :
  763. i++;
  764. break;
  765. } /* end switch */
  766. /* If the oPUSH instruction is still there, see if we can now */
  767. /* represent it with an oPUSHB instruction */
  768. if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
  769. {
  770. pptr[i]->op = oPUSHB;
  771. pptr[i]->arg1 = pptr[i]->arg2;
  772. pptr[i]->arg2 = 0;
  773. } /* end if */
  774. } /* end else if */
  775. else i++;
  776. } /* end if */
  777. /* Misc improvements on binary operators */
  778. else if (pptr[i]->op == oNEG)
  779. {
  780. /* Negation followed by add is subtraction */
  781. if (pptr[i+1]->op == oADD)
  782. {
  783. pptr[i+1]->op = oSUB;
  784. deletePcode(i);
  785. nchanges++;
  786. }
  787. /* Negation followed by subtraction is addition */
  788. else if (pptr[i]->op == oSUB)
  789. {
  790. pptr[i+1]->op = oADD;
  791. deletePcode(i);
  792. nchanges++;
  793. }
  794. else i++;
  795. }
  796. else i++;
  797. } /* end while */
  798. return (nchanges);
  799. } /* end binaryOptimize */
  800. /**********************************************************************/