OPTIMIZE.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:25k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /*
  23.  * this module combines constants at compile time.  Integer constants
  24.  * will get combined slightly better than floating point ones
  25.  */
  26. #include        <stdio.h>
  27. #include        "expr.h"
  28. #include        "c.h"
  29. int maxinttype(ENODE *ep1, ENODE *ep2)
  30. {
  31. int type1=ep1->nodetype;
  32. int type2 = ep2->nodetype;
  33. if (type1 == en_lucon || type2 == en_lucon)
  34. return en_lucon;
  35. if (type1 == en_lcon || type2 == en_lcon)
  36. return en_lcon;
  37. if (type1 == en_iucon || type2 == en_iucon)
  38. return en_iucon;
  39. if (type1 == en_icon || type2 == en_icon)
  40. return en_icon;
  41. return en_ccon;
  42. }
  43. int maxfloattype(ENODE *ep1, ENODE *ep2)
  44. {
  45. int type1=ep1->nodetype;
  46. int type2 = ep2->nodetype;
  47. if (type1 == en_lrcon || type2 == en_lrcon)
  48. return en_lrcon;
  49. if (type1 == en_rcon || type2 == en_rcon)
  50. return en_rcon;
  51. return en_fcon;
  52. }
  53. int getmode(ENODE *ep1,ENODE *ep2)
  54. /*
  55.  * get the constant mode of a pair of nodes
  56.  * 0 = Neither node is a constant
  57.  * 1 = icon,icon
  58.  * 2 = icon,rcon
  59.  * 3 = rcon,icon
  60.  * 4 = rcon,rcon
  61.  * 5 = icon,nothing
  62.  * 6 = rcon,nothing
  63.  * 7 = nothing,icon
  64.  * 8 = nothing,rcon
  65.  */
  66. {
  67. int mode = 0;
  68. if (isintconst(ep1->nodetype) )
  69. if (ep2)  {
  70. if (isintconst(ep2->nodetype))
  71. mode = 1;
  72. else  if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2->nodetype == en_fcon)
  73. mode = 2;
  74. else mode = 5;
  75. }
  76. else
  77. mode = 5;
  78. else if (ep1->nodetype == en_rcon || ep1->nodetype == en_lrcon || ep1->nodetype == en_fcon)
  79. if (ep2)  {
  80. if (isintconst(ep2->nodetype))
  81. mode = 3;
  82. else  if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2->nodetype == en_fcon)
  83. mode = 4;
  84. else mode = 6;
  85. }
  86. else
  87. mode = 6;
  88. else if (ep2)
  89. if (isintconst(ep2->nodetype))
  90. mode = 7;
  91. else  if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2->nodetype == en_fcon)
  92. mode = 8;
  93. return(mode);
  94. }
  95. void dooper(ENODE ** node, int mode)
  96. /*
  97.  *      dooper will execute a constant operation in a node and
  98.  *      modify the node to be the result of the operation.
  99.  * It will also cast integers to floating point values when
  100.  * necessary
  101.  */                             
  102. {     ENODE    *ep,*ep1,*ep2;
  103.       ep = *node;
  104. ep1 = ep->v.p[0];
  105. ep2 = ep->v.p[1];
  106. if (mode ==5) {
  107. if (floatrecurse(ep2)) {
  108. ep1->v.f = ep1->v.i;
  109. ep1->nodetype = en_rcon;
  110. }
  111. return;
  112. }
  113. else if (mode == 7) {
  114. if (floatrecurse(ep1)) {
  115. ep2->v.f = ep2->v.i;
  116. ep2->nodetype = en_rcon;
  117. }
  118. return;
  119. }
  120. else if (mode == 6 || mode == 8)
  121. return;
  122. else
  123.         switch( ep->nodetype ) {
  124.                 case en_add:
  125.   switch (mode) {
  126. case 1:
  127.                          ep->nodetype = maxinttype(ep1,ep2);
  128.                          ep->v.i = ep1->v.i + ep2->v.i;
  129. break;
  130. case 2:
  131.                          ep->nodetype = maxfloattype(ep1,ep2);
  132.                          ep->v.f = ep1->v.i + ep2->v.f;
  133. break;
  134. case 3:
  135.                          ep->nodetype = maxfloattype(ep1,ep2);
  136.                          ep->v.f = ep1->v.f + ep2->v.i;
  137. break;
  138. case 4:
  139.                          ep->nodetype = maxfloattype(ep1,ep2);
  140.                          ep->v.f = ep1->v.f + ep2->v.f;
  141. break;
  142.                         }
  143. break;
  144.                 case en_sub:
  145.   switch (mode) {
  146. case 1:
  147.                          ep->nodetype = maxinttype(ep1,ep2);
  148.                          ep->v.i = ep1->v.i - ep2->v.i;
  149. break;
  150. case 2:
  151.                          ep->nodetype = maxfloattype(ep1,ep2);
  152.                          ep->v.f = ep1->v.i - ep2->v.f;
  153. break;
  154. case 3:
  155.                          ep->nodetype = maxfloattype(ep1,ep2);
  156.                          ep->v.f = ep1->v.f - ep2->v.i;
  157. break;
  158. case 4:
  159.                          ep->nodetype = maxfloattype(ep1,ep2);
  160.                          ep->v.f = ep1->v.f - ep2->v.f;
  161. break;
  162. }
  163.                         break;
  164. case en_pmul:
  165. case en_umul:
  166.                 case en_mul:
  167.   switch (mode) {
  168. case 1:
  169.                          ep->nodetype = maxinttype(ep1,ep2);
  170.                          ep->v.i = ep1->v.i * ep2->v.i;
  171. break;
  172. case 2:
  173.                          ep->nodetype = maxfloattype(ep1,ep2);
  174.                          ep->v.f = ep1->v.i * ep2->v.f;
  175. break;
  176. case 3:
  177.                          ep->nodetype = maxfloattype(ep1,ep2);
  178.                          ep->v.f = ep1->v.f * ep2->v.i;
  179. break;
  180. case 4:
  181.                          ep->nodetype = maxfloattype(ep1,ep2);
  182.                          ep->v.f = ep1->v.f * ep2->v.f;
  183. break;
  184. }
  185.                         break;
  186. case en_pdiv:
  187.                 case en_div:
  188.                 case en_udiv:
  189.   switch (mode) {
  190. case 1:
  191.                          ep->nodetype = maxinttype(ep1,ep2);
  192.                          ep->v.i = ep1->v.i / ep2->v.i;
  193. break;
  194. case 2:
  195.                          ep->nodetype = maxfloattype(ep1,ep2);
  196.                          ep->v.f = ep1->v.i / ep2->v.f;
  197. break;
  198. case 3:
  199.                          ep->nodetype = maxfloattype(ep1,ep2);
  200.                          ep->v.f = ep1->v.f / ep2->v.i;
  201. break;
  202. case 4:
  203.                          ep->nodetype = maxfloattype(ep1,ep2);
  204.                          ep->v.f = ep1->v.f / ep2->v.f;
  205. break;
  206. }
  207.                         break;
  208. case en_mod:
  209.                          ep->nodetype = maxinttype(ep1,ep2);
  210. ep->v.i = ep1->v.i % ep2->v.i;
  211. break;
  212.                 case en_lsh:
  213. case en_alsh:
  214.                          ep->nodetype = maxinttype(ep1,ep2);
  215.                         ep->v.i = ep1->v.i << ep2->v.i;
  216.                         break;
  217.                 case en_rsh:
  218. case en_arsh:
  219.                          ep->nodetype = maxinttype(ep1,ep2);
  220.                         ep->v.i = ep1->v.i >> ep2->v.i;
  221.                         break;
  222.                 case en_and:
  223.                          ep->nodetype = maxinttype(ep1,ep2);
  224.                         ep->v.i = ep1->v.i & ep2->v.i;
  225.                         break;
  226.                 case en_or:
  227.                          ep->nodetype = maxinttype(ep1,ep2);
  228.                         ep->v.i = ep1->v.i | ep2->v.i;
  229.                         break;
  230.                 case en_xor:
  231.                          ep->nodetype = maxinttype(ep1,ep2);
  232.                         ep->v.i = ep1->v.i ^ ep2->v.i;
  233.                         break;
  234.                 }
  235. }
  236. /*
  237.  * this stuff has been superceded by a lookup table
  238.  * I'll fix it eventually
  239.  */
  240. long     pwrof2(int i)
  241. /*
  242.  *      return which power of two i is or -1.
  243.  */
  244. {       long     p, q;
  245.         q = 2;
  246.         p = 1;
  247.         while( q > 0 )
  248.                 {
  249.                 if( q == i )
  250.                         return p;
  251.                 q <<= 1;
  252.                 ++p;
  253.                 }
  254.         return -1;
  255. }
  256. long     mod_mask(int i)
  257. /*
  258.  *      make a mod mask for a power of two.
  259.  */
  260. {       long     m;
  261.         m = 0;
  262.         while( i-- )
  263.                 m = (m << 1) | 1;
  264.         return m;
  265. }
  266. void opt0(ENODE ** node)
  267. /*
  268.  *      opt0 - delete useless expressions and combine constants.
  269.  *
  270.  *      opt0 will delete expressions such as x + 0, x - 0, x * 0,
  271.  *      x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to
  272.  *      by node and combine obvious constant operations. It cannot
  273.  *      combine name and label constants but will combine icon type
  274.  *      nodes.
  275.  */
  276. {       ENODE    *ep;
  277.         int             sc,mode,val;
  278. double dval;
  279.         ep = *node;
  280.         if( ep == 0 )
  281.                 return;
  282.         switch( (*node)->nodetype ) {
  283.                 case en_b_ref:
  284.                 case en_w_ref:          /* optimize unary node */
  285.                 case en_ub_ref:
  286.                 case en_uw_ref:          /* optimize unary node */
  287.                 case en_l_ref:
  288. case en_ul_ref:
  289. case en_floatref: case en_doubleref: case en_longdoubleref:
  290. case en_cb: case en_cub:
  291. case en_cw: case en_cuw:
  292. case en_cl: case en_cul:
  293. case en_cf: case en_cd: case en_cp: case en_bits: case en_cld:
  294. case en_ainc:
  295. case en_adec:
  296. case en_not:
  297. case en_compl:
  298.                         opt0( &((*node)->v.p[0]));
  299.                         return;
  300.                 case en_uminus:
  301.                         opt0( &(ep->v.p[0]));
  302.                         if( isintconst(ep->v.p[0]->nodetype))
  303.                                 {
  304.                                 ep->nodetype = ep->v.p[0]->nodetype;
  305.                                 ep->v.i = -ep->v.p[0]->v.i;
  306.                                 }
  307.                         else if( ep->v.p[0]->nodetype == en_rcon || ep->v.p[0]->nodetype == en_fcon || ep->v.p[0]->nodetype == en_lrcon)
  308.                                 {
  309.                                 ep->nodetype = ep->v.p[0]->nodetype;
  310.                                 ep->v.i = -ep->v.p[0]->v.f;
  311.                                 }
  312.                         return;
  313.                 case en_add:
  314.                 case en_sub:
  315.                         opt0(&(ep->v.p[0]));
  316.                         opt0(&(ep->v.p[1]));
  317. mode = getmode(ep->v.p[0],ep->v.p[1]);
  318. switch (mode) {
  319. case 1: case 2: case 3: case 4:
  320. dooper(node,mode);
  321. break;
  322. case 5:
  323. if (ep->v.p[0]->v.i == 0) {
  324. if (ep->nodetype == en_sub) {
  325. *node = makenode(en_uminus,ep->v.p[1],0);
  326. }
  327. else *node = ep->v.p[1];
  328. }
  329. else dooper(node,mode);
  330. break;
  331. case 6:
  332. if (ep->v.p[0]->v.f == 0) {
  333. if (ep->nodetype == en_sub) {
  334. *node = ep->v.p[1];
  335. ep->v.p[1]->v.f = - ep->v.p[1]->v.f;
  336. }
  337. else *node = ep->v.p[1];
  338. }
  339. else dooper(node,mode);
  340. break;
  341.   case 7:
  342. if (ep->v.p[1]->v.i == 0) {
  343. *node = ep->v.p[0];
  344. }
  345. else dooper(node,mode);
  346. break;
  347. case 8:
  348. if (ep->v.p[1]->v.f == 0) {
  349. *node = ep->v.p[0];
  350. }
  351. else dooper(node,mode);
  352. break;
  353. }
  354.                         return;
  355.                 case en_mul:
  356. case en_umul:
  357. case en_pmul:
  358. case en_asmul: case en_asumul:
  359.                         opt0(&(ep->v.p[0]));
  360.                         opt0(&(ep->v.p[1]));
  361. mode = getmode(ep->v.p[0],ep->v.p[1]);
  362. switch(mode) {
  363. case 1: case 2: case 3: case 4:
  364. dooper(node,mode);
  365. break;
  366. case 5:
  367. if (!floatrecurse(ep->v.p[1])) {
  368.                                 sc = pwrof2(ep->v.p[0]->v.i);
  369.                                 if( sc != -1 )
  370.                                         {
  371. ENODE *temp = ep->v.p[0];
  372. ep->v.p[0 ] = ep->v.p[1];
  373. ep->v.p[1] = temp;
  374.                                         ep->v.p[1]->v.i = sc;
  375. switch(ep->nodetype) {
  376. case en_mul:
  377. ep->nodetype = en_alsh;
  378. break;
  379. case en_asmul:
  380. ep->nodetype = en_asalsh;
  381. break;
  382. case en_umul:
  383. case en_pmul:
  384. ep->nodetype = en_lsh;
  385. break;
  386. case en_asumul:
  387. ep->nodetype = en_aslsh;
  388. break;
  389. }
  390. break;
  391.                                         }
  392.                             }
  393. val = ep->v.p[0]->v.i;
  394. if (val == 0)
  395. *node = ep->v.p[0];
  396. else if (val == 1)
  397. *node = ep->v.p[1];
  398. else if (val == -1)
  399. *node = makenode(en_uminus,(char *)ep->v.p[1],0);
  400. else dooper(node,mode);
  401. break;
  402. case 6:
  403. dval = ep->v.p[0]->v.f;
  404. if (dval == 0)
  405. *node = ep->v.p[0];
  406. else if (dval == 1)
  407. *node = ep->v.p[1];
  408. else if (dval == -1)
  409. *node = makenode(en_uminus,(char *)ep->v.p[1],0);
  410. else dooper(node,mode);
  411. break;
  412. case 7:
  413. if (!floatrecurse(ep->v.p[0])) {
  414.                                 sc = pwrof2(ep->v.p[1]->v.i);
  415.                                 if( sc != -1 )
  416.                                         {
  417.                                         ep->v.p[1]->v.i = sc;
  418. switch(ep->nodetype) {
  419. case en_mul:
  420. ep->nodetype = en_alsh;
  421. break;
  422. case en_asmul:
  423. ep->nodetype = en_asalsh;
  424. break;
  425. case en_umul:
  426. case en_pmul:
  427. ep->nodetype = en_lsh;
  428. break;
  429. case en_asumul:
  430. ep->nodetype = en_aslsh;
  431. break;
  432. }
  433. break;
  434.                                         }
  435.                             }
  436. val = ep->v.p[1]->v.i;
  437. if (val == 0)
  438. *node = ep->v.p[1];
  439. else if (val == 1)
  440. *node = ep->v.p[0];
  441. else if (val == -1)
  442. *node = makenode(en_uminus,(char *)ep->v.p[0],0);
  443. else dooper(node,mode);
  444. break;
  445. case 8:
  446. dval = ep->v.p[1]->v.f;
  447. if (dval == 0)
  448. *node = ep->v.p[1];
  449. else if (dval == 1)
  450. *node = ep->v.p[0];
  451. else if (dval == -1)
  452. *node = makenode(en_uminus,(char *)ep->v.p[0],0);
  453. else dooper(node,mode);
  454. break;
  455. }
  456.                         break;
  457. case en_pdiv:
  458.                 case en_div:
  459. case en_udiv:
  460. case en_asdiv:
  461. case en_asudiv:
  462.                         opt0(&(ep->v.p[0]));
  463.                         opt0(&(ep->v.p[1]));
  464. mode = getmode(ep->v.p[0],ep->v.p[1]);
  465. switch(mode) {
  466. case 1:
  467. case 2:
  468. case 3:
  469. case 4: 
  470. dooper(node,mode);
  471. break;
  472. case 5:
  473. if (ep->v.p[0]->v.i == 0)
  474. *node = ep->v.p[0];
  475. else
  476. dooper(node,mode);
  477. break;
  478. case 6:
  479. if (ep->v.p[0]->v.f == 0)
  480. *node = ep->v.p[0];
  481. else
  482. dooper(node,mode);
  483. break;
  484. case 7:
  485. if (!floatrecurse(ep->v.p[0])) {
  486.                                 sc = pwrof2(ep->v.p[1]->v.i);
  487.                                 if( sc != -1 )
  488.                                         {
  489.                                         ep->v.p[1]->v.i = sc;
  490. switch(ep->nodetype) {
  491. case en_div:
  492. ep->nodetype = en_arsh;
  493. break;
  494. case en_asdiv:
  495. ep->nodetype = en_asarsh;
  496. break;
  497. case en_udiv:
  498. case en_pdiv:
  499. ep->nodetype = en_rsh;
  500. break;
  501. case en_asudiv:
  502. ep->nodetype = en_asrsh;
  503. break;
  504. }
  505. break;
  506.                                         }
  507.                             }
  508. val = ep->v.p[1]->v.i;
  509. if (val == 1)
  510. *node = ep->v.p[0];
  511. else if (val == -1)
  512. *node = makenode(en_uminus,(char *)ep->v.p[0],0);
  513. else dooper(node,mode);
  514. break;
  515. case 8:
  516. dval = ep->v.p[1]->v.f;
  517. if (dval == 1)
  518. *node = ep->v.p[0];
  519. else if (dval == -1)
  520. *node = makenode(en_uminus,(char *)ep->v.p[0],0);
  521. else dooper(node,mode);
  522. break;
  523. }
  524.                         break;
  525.                 case en_mod:
  526. case en_umod:
  527. case en_asmod: case en_asumod:
  528.                         opt0(&(ep->v.p[0]));
  529.                         opt0(&(ep->v.p[1]));
  530. mode = getmode(ep->v.p[0],ep->v.p[1]);
  531. switch(mode) {
  532. case 7:
  533. if (!floatrecurse(ep->v.p[0])) {
  534.                                 sc = pwrof2(ep->v.p[1]->v.i);
  535.                                 if( sc != -1 )
  536.                                         {
  537.                                         ep->v.p[1]->v.i = mod_mask(sc);
  538. if (ep->nodetype == en_asmod || ep->nodetype == en_asumod)
  539.                                          ep->nodetype = en_asand;
  540. else
  541.                                          ep->nodetype = en_and;
  542. break;
  543.                                         }
  544.                                 }
  545. case 1:
  546. case 2:
  547. case 3:
  548. case 4: 
  549. case 5: case 6: case 8:
  550. dooper(node,mode);
  551. }
  552.                         break;
  553.                 case en_and:    case en_or:
  554.                 case en_xor:    case en_rsh:
  555.                 case en_lsh:    case en_arsh: case en_alsh:
  556.                         opt0(&(ep->v.p[0]));
  557.                         opt0(&(ep->v.p[1]));
  558.                         if( isintconst(ep->v.p[0]->nodetype) &&
  559.                                 isintconst(ep->v.p[1]->nodetype) )
  560.                                 dooper(node,getmode(ep->v.p[0],ep->v.p[1]));
  561.                         break;
  562.                 case en_land:   case en_lor:
  563. case en_lt: case en_le:
  564. case en_ugt: case en_uge: case en_ult: case en_ule:
  565. case en_gt: case en_ge:
  566. case en_eq: case en_ne:
  567. case en_asalsh: case en_asarsh:
  568.                 case en_asand:  case en_asor:  case en_asxor:
  569.                 case en_asadd:  case en_assub:
  570.                 case en_asrsh:
  571.                 case en_aslsh:  case en_cond:
  572.                 case en_fcall:  case en_void: case en_trapcall: case en_intcall:
  573. case en_pfcall: case en_pfcallb:
  574.                 case en_assign: case en_moveblock: case en_stackblock: case en_callblock:
  575. case en_fcallb: case en_refassign: case en_pcallblock:
  576.                         opt0(&(ep->v.p[0]));
  577.                         opt0(&(ep->v.p[1]));
  578.                         break;
  579.                 }
  580. }
  581. long     xfold2(ENODE * node)
  582. /*
  583.  *      xfold2 will remove constant nodes and return the values to
  584.  *      the calling routines.
  585.  */
  586. {       long     i;
  587.         if( node == 0 )
  588.                 return 0;
  589.         switch( node->nodetype )
  590.                 {
  591.                 case en_icon:
  592. case en_lcon:
  593. case en_iucon:
  594. case en_lucon:
  595. case en_ccon:
  596.                         i = node->v.i;
  597.                         node->v.i = 0;
  598.                         return i;
  599.                 case en_add:
  600.                         return xfold2(node->v.p[0]) + xfold2(node->v.p[1]);
  601.                 case en_sub:
  602.                         return xfold2(node->v.p[0]) - xfold2(node->v.p[1]);
  603. case en_or:
  604.                         return xfold2(node->v.p[0]) | xfold2(node->v.p[1]);
  605. case en_xor:
  606.                         return xfold2(node->v.p[0]) ^ xfold2(node->v.p[1]);
  607.                 case en_uminus:
  608.                         return - xfold2(node->v.p[0]);
  609.                 case en_mul:
  610. case en_pmul:
  611. case en_umul:
  612.                 case en_lsh:
  613. case en_alsh:
  614. case en_asalsh: case en_asarsh: case en_arsh:
  615.                 case en_rsh:    case en_div:  case en_pdiv:
  616.                 case en_mod:    case en_asadd:
  617.                 case en_assub:  case en_asmul:
  618.                 case en_asdiv:  case en_asmod:
  619.                 case en_land: case en_lor:
  620.                 case en_asand: case en_and:
  621.                 case en_asor:   case en_void:  case en_asxor:
  622. case en_pfcall: case en_pfcallb:
  623.                 case en_fcall:  case en_assign: case en_moveblock: case en_trapcall:
  624. case en_stackblock: case en_intcall: case en_callblock: case en_fcallb:
  625. case en_asumul: case en_asudiv: case en_asumod: case en_refassign:
  626. case en_udiv: case en_pcallblock:
  627.                         fold_const2(&node->v.p[0]);
  628.                         fold_const2(&node->v.p[1]);
  629.                         return 0;
  630.                 case en_b_ref:  case en_w_ref:
  631.                 case en_ub_ref:  case en_uw_ref:
  632.                 case en_l_ref:  case en_compl: case en_ul_ref:
  633. case en_floatref: case en_doubleref: case en_longdoubleref:
  634.                 case en_not: case en_bits:
  635.                         fold_const2(&node->v.p[0]);
  636.                         return 0;
  637.                 }
  638.         return 0;
  639. }
  640. void fold_const2(ENODE ** node)
  641. /*
  642.  *      reorganize an expression for optimal constant grouping.
  643.  */
  644. {       ENODE    *ep;
  645.         long   i;
  646.         ep = *node;
  647.         if( ep == 0 )
  648.                 return;
  649. switch (ep->nodetype) {
  650. case en_add:
  651. if (ep->v.p[0]->nodetype == en_cp && isintconst(ep->v.p[0]->v.p[0]->nodetype)) {
  652. ep->v.p[0]->v.p[0]->v.i += xfold2(ep->v.p[1]);
  653. return;
  654. }
  655. else if (ep->v.p[1]->nodetype == en_cp && isintconst(ep->v.p[1]->v.p[0]->nodetype)) {
  656. ep->v.p[1]->v.p[0]->v.i += xfold2(ep->v.p[1]);
  657. return;
  658. }
  659.                 else if( isintconst(ep->v.p[0]->nodetype))
  660.                         {
  661.                         ep->v.p[0]->v.i += xfold2(ep->v.p[1]);
  662.                         return;
  663.                         }
  664.                 else if( isintconst(ep->v.p[1]->nodetype))
  665.                         {
  666.                         ep->v.p[1]->v.i += xfold2(ep->v.p[0]);
  667.                         return;
  668.                         }
  669. break;
  670. case en_sub:
  671. if (ep->v.p[0]->nodetype == en_cp && isintconst(ep->v.p[0]->v.p[0]->nodetype == en_icon)) {
  672. ep->v.p[0]->v.p[0]->v.i -= xfold2(ep->v.p[1]);
  673. return;
  674. }
  675. else if (ep->v.p[1]->nodetype == en_cp && isintconst(ep->v.p[1]->v.p[0]->nodetype)) {
  676. ep->v.p[1]->v.p[0]->v.i -= xfold2(ep->v.p[1]);
  677. return;
  678. }
  679.                 else if( isintconst(ep->v.p[0]->nodetype))
  680.                         {
  681.                         ep->v.p[0]->v.i -= xfold2(ep->v.p[1]);
  682.                         return;
  683.                         }
  684.                 else if( isintconst(ep->v.p[1]->nodetype))
  685.                         {
  686.                         ep->v.p[1]->v.i -= xfold2(ep->v.p[0]);
  687.                         return;
  688.                         }
  689. break;
  690. case en_or:
  691.                 if(isintconst( ep->v.p[0]->nodetype) )
  692.                         {
  693.                         ep->v.p[0]->v.i |= xfold2(ep->v.p[1]);
  694.                         return;
  695.                         }
  696.                 else if(isintconst( ep->v.p[1]->nodetype) )
  697.                         {
  698.                         ep->v.p[1]->v.i |= xfold2(ep->v.p[0]);
  699.                         return;
  700.                         }
  701. break;
  702. case en_xor:
  703.                 if( isintconst(ep->v.p[0]->nodetype))
  704.                         {
  705.                         ep->v.p[0]->v.i ^= xfold2(ep->v.p[1]);
  706.                         return;
  707.                         }
  708.                 else if( isintconst(ep->v.p[1]->nodetype))
  709.                         {
  710.                         ep->v.p[1]->v.i ^= xfold2(ep->v.p[0]);
  711.                         return;
  712.                         }
  713. break;
  714. }
  715.         i = xfold2(ep);
  716.         if( i != 0 ) {
  717. ep = xalloc(sizeof(ENODE));
  718. ep->nodetype = en_icon;
  719. ep->v.i = i;
  720.                  ep = makenode(en_add,ep,*node);
  721.                 *node = ep;
  722.         }
  723. }
  724. void opt4(ENODE ** node)
  725. /*
  726.  *      apply all constant optimizations.
  727.  */
  728. {
  729. opt0(node);
  730.         fold_const2(node);
  731.         opt0(node);
  732. }