scon.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. #include "cc.h"
  2. void
  3. evconst(Node *n)
  4. {
  5. Node *l, *r;
  6. int et, isf;
  7. vlong v;
  8. double d;
  9. if(n == Z || n->type == T)
  10. return;
  11. et = n->type->etype;
  12. isf = typefd[et];
  13. l = n->left;
  14. r = n->right;
  15. d = 0;
  16. v = 0;
  17. switch(n->op) {
  18. default:
  19. return;
  20. case ONEG:
  21. if(isf)
  22. d = -l->fconst;
  23. else
  24. v = -l->vconst;
  25. break;
  26. case OCOM:
  27. v = ~l->vconst;
  28. break;
  29. case OCAST:
  30. if(et == TVOID)
  31. return;
  32. et = l->type->etype;
  33. if(isf) {
  34. if(typefd[et])
  35. d = l->fconst;
  36. else
  37. d = l->vconst;
  38. } else {
  39. if(typefd[et])
  40. v = l->fconst;
  41. else
  42. v = convvtox(l->vconst, n->type->etype);
  43. }
  44. break;
  45. case OCONST:
  46. break;
  47. case OADD:
  48. if(isf)
  49. d = l->fconst + r->fconst;
  50. else {
  51. v = l->vconst + r->vconst;
  52. }
  53. break;
  54. case OSUB:
  55. if(isf)
  56. d = l->fconst - r->fconst;
  57. else
  58. v = l->vconst - r->vconst;
  59. break;
  60. case OMUL:
  61. if(isf)
  62. d = l->fconst * r->fconst;
  63. else {
  64. v = l->vconst * r->vconst;
  65. }
  66. break;
  67. case OLMUL:
  68. v = (uvlong)l->vconst * (uvlong)r->vconst;
  69. break;
  70. case ODIV:
  71. if(vconst(r) == 0) {
  72. warn(n, "divide by zero");
  73. return;
  74. }
  75. if(isf)
  76. d = l->fconst / r->fconst;
  77. else
  78. v = l->vconst / r->vconst;
  79. break;
  80. case OLDIV:
  81. if(vconst(r) == 0) {
  82. warn(n, "divide by zero");
  83. return;
  84. }
  85. v = (uvlong)l->vconst / (uvlong)r->vconst;
  86. break;
  87. case OMOD:
  88. if(vconst(r) == 0) {
  89. warn(n, "modulo by zero");
  90. return;
  91. }
  92. v = l->vconst % r->vconst;
  93. break;
  94. case OLMOD:
  95. if(vconst(r) == 0) {
  96. warn(n, "modulo by zero");
  97. return;
  98. }
  99. v = (uvlong)l->vconst % (uvlong)r->vconst;
  100. break;
  101. case OAND:
  102. v = l->vconst & r->vconst;
  103. break;
  104. case OOR:
  105. v = l->vconst | r->vconst;
  106. break;
  107. case OXOR:
  108. v = l->vconst ^ r->vconst;
  109. break;
  110. case OLSHR:
  111. v = (uvlong)l->vconst >> r->vconst;
  112. break;
  113. case OASHR:
  114. v = l->vconst >> r->vconst;
  115. break;
  116. case OASHL:
  117. v = l->vconst << r->vconst;
  118. break;
  119. case OLO:
  120. v = (uvlong)l->vconst < (uvlong)r->vconst;
  121. break;
  122. case OLT:
  123. if(typefd[l->type->etype])
  124. v = l->fconst < r->fconst;
  125. else
  126. v = l->vconst < r->vconst;
  127. break;
  128. case OHI:
  129. v = (uvlong)l->vconst > (uvlong)r->vconst;
  130. break;
  131. case OGT:
  132. if(typefd[l->type->etype])
  133. v = l->fconst > r->fconst;
  134. else
  135. v = l->vconst > r->vconst;
  136. break;
  137. case OLS:
  138. v = (uvlong)l->vconst <= (uvlong)r->vconst;
  139. break;
  140. case OLE:
  141. if(typefd[l->type->etype])
  142. v = l->fconst <= r->fconst;
  143. else
  144. v = l->vconst <= r->vconst;
  145. break;
  146. case OHS:
  147. v = (uvlong)l->vconst >= (uvlong)r->vconst;
  148. break;
  149. case OGE:
  150. if(typefd[l->type->etype])
  151. v = l->fconst >= r->fconst;
  152. else
  153. v = l->vconst >= r->vconst;
  154. break;
  155. case OEQ:
  156. if(typefd[l->type->etype])
  157. v = l->fconst == r->fconst;
  158. else
  159. v = l->vconst == r->vconst;
  160. break;
  161. case ONE:
  162. if(typefd[l->type->etype])
  163. v = l->fconst != r->fconst;
  164. else
  165. v = l->vconst != r->vconst;
  166. break;
  167. case ONOT:
  168. if(typefd[l->type->etype])
  169. v = !l->fconst;
  170. else
  171. v = !l->vconst;
  172. break;
  173. case OANDAND:
  174. if(typefd[l->type->etype])
  175. v = l->fconst && r->fconst;
  176. else
  177. v = l->vconst && r->vconst;
  178. break;
  179. case OOROR:
  180. if(typefd[l->type->etype])
  181. v = l->fconst || r->fconst;
  182. else
  183. v = l->vconst || r->vconst;
  184. break;
  185. }
  186. if(isf) {
  187. n->fconst = d;
  188. } else {
  189. n->vconst = convvtox(v, n->type->etype);
  190. }
  191. n->oldop = n->op;
  192. n->op = OCONST;
  193. }
  194. void
  195. acom(Node *n)
  196. {
  197. Type *t;
  198. Node *l, *r;
  199. int i;
  200. switch(n->op)
  201. {
  202. case ONAME:
  203. case OCONST:
  204. case OSTRING:
  205. case OINDREG:
  206. case OREGISTER:
  207. return;
  208. case ONEG:
  209. l = n->left;
  210. if(addo(n) && addo(l))
  211. break;
  212. acom(l);
  213. return;
  214. case OADD:
  215. case OSUB:
  216. case OMUL:
  217. l = n->left;
  218. r = n->right;
  219. if(addo(n)) {
  220. if(addo(r))
  221. break;
  222. if(addo(l))
  223. break;
  224. }
  225. acom(l);
  226. acom(r);
  227. return;
  228. default:
  229. l = n->left;
  230. r = n->right;
  231. if(l != Z)
  232. acom(l);
  233. if(r != Z)
  234. acom(r);
  235. return;
  236. }
  237. /* bust terms out */
  238. t = n->type;
  239. term[0].mult = 0;
  240. term[0].node = Z;
  241. nterm = 1;
  242. acom1(1, n);
  243. if(debug['m'])
  244. for(i=0; i<nterm; i++) {
  245. print("%d %3lld ", i, term[i].mult);
  246. prtree1(term[i].node, 1, 0);
  247. }
  248. if(nterm < NTERM)
  249. acom2(n, t);
  250. n->type = t;
  251. }
  252. int
  253. acomcmp1(const void *a1, const void *a2)
  254. {
  255. vlong c1, c2;
  256. Term *t1, *t2;
  257. t1 = (Term*)a1;
  258. t2 = (Term*)a2;
  259. c1 = t1->mult;
  260. if(c1 < 0)
  261. c1 = -c1;
  262. c2 = t2->mult;
  263. if(c2 < 0)
  264. c2 = -c2;
  265. if(c1 > c2)
  266. return 1;
  267. if(c1 < c2)
  268. return -1;
  269. c1 = 1;
  270. if(t1->mult < 0)
  271. c1 = 0;
  272. c2 = 1;
  273. if(t2->mult < 0)
  274. c2 = 0;
  275. if(c2 -= c1)
  276. return c2;
  277. if(t2 > t1)
  278. return 1;
  279. return -1;
  280. }
  281. int
  282. acomcmp2(const void *a1, const void *a2)
  283. {
  284. vlong c1, c2;
  285. Term *t1, *t2;
  286. t1 = (Term*)a1;
  287. t2 = (Term*)a2;
  288. c1 = t1->mult;
  289. c2 = t2->mult;
  290. if(c1 > c2)
  291. return 1;
  292. if(c1 < c2)
  293. return -1;
  294. if(t2 > t1)
  295. return 1;
  296. return -1;
  297. }
  298. void
  299. acom2(Node *n, Type *t)
  300. {
  301. Node *l, *r;
  302. Term trm[NTERM];
  303. int et, nt, i, j;
  304. vlong c1, c2;
  305. /*
  306. * copy into automatic
  307. */
  308. c2 = 0;
  309. nt = nterm;
  310. for(i=0; i<nt; i++)
  311. trm[i] = term[i];
  312. /*
  313. * recur on subtrees
  314. */
  315. j = 0;
  316. for(i=1; i<nt; i++) {
  317. c1 = trm[i].mult;
  318. if(c1 == 0)
  319. continue;
  320. l = trm[i].node;
  321. if(l != Z) {
  322. j = 1;
  323. acom(l);
  324. }
  325. }
  326. c1 = trm[0].mult;
  327. if(j == 0) {
  328. n->oldop = n->op;
  329. n->op = OCONST;
  330. n->vconst = c1;
  331. return;
  332. }
  333. et = t->etype;
  334. /*
  335. * prepare constant term,
  336. * combine it with an addressing term
  337. */
  338. if(c1 != 0) {
  339. l = new1(OCONST, Z, Z);
  340. l->type = t;
  341. l->vconst = c1;
  342. trm[0].mult = 1;
  343. for(i=1; i<nt; i++) {
  344. if(trm[i].mult != 1)
  345. continue;
  346. r = trm[i].node;
  347. if(r->op != OADDR)
  348. continue;
  349. r->type = t;
  350. l = new1(OADD, r, l);
  351. l->type = t;
  352. trm[i].mult = 0;
  353. break;
  354. }
  355. trm[0].node = l;
  356. }
  357. /*
  358. * look for factorable terms
  359. * c1*i + c1*c2*j -> c1*(i + c2*j)
  360. */
  361. qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp1);
  362. for(i=nt-1; i>=0; i--) {
  363. c1 = trm[i].mult;
  364. if(c1 < 0)
  365. c1 = -c1;
  366. if(c1 <= 1)
  367. continue;
  368. for(j=i+1; j<nt; j++) {
  369. c2 = trm[j].mult;
  370. if(c2 < 0)
  371. c2 = -c2;
  372. if(c2 <= 1)
  373. continue;
  374. if(c2 % c1)
  375. continue;
  376. r = trm[j].node;
  377. if(r->type->etype != et) {
  378. r = new1(OCAST, r, Z);
  379. r->type = t;
  380. }
  381. c2 = trm[j].mult/trm[i].mult;
  382. if(c2 != 1 && c2 != -1) {
  383. r = new1(OMUL, r, new(OCONST, Z, Z));
  384. r->type = t;
  385. r->right->type = t;
  386. r->right->vconst = c2;
  387. }
  388. l = trm[i].node;
  389. if(l->type->etype != et) {
  390. l = new1(OCAST, l, Z);
  391. l->type = t;
  392. }
  393. r = new1(OADD, l, r);
  394. r->type = t;
  395. if(c2 == -1)
  396. r->op = OSUB;
  397. trm[i].node = r;
  398. trm[j].mult = 0;
  399. }
  400. }
  401. if(debug['m']) {
  402. print("\n");
  403. for(i=0; i<nt; i++) {
  404. print("%d %3lld ", i, trm[i].mult);
  405. prtree1(trm[i].node, 1, 0);
  406. }
  407. }
  408. /*
  409. * put it all back together
  410. */
  411. qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp2);
  412. l = Z;
  413. for(i=nt-1; i>=0; i--) {
  414. c1 = trm[i].mult;
  415. if(c1 == 0)
  416. continue;
  417. r = trm[i].node;
  418. if(r->type->etype != et || r->op == OBIT) {
  419. r = new1(OCAST, r, Z);
  420. r->type = t;
  421. }
  422. if(c1 != 1 && c1 != -1) {
  423. r = new1(OMUL, r, new(OCONST, Z, Z));
  424. r->type = t;
  425. r->right->type = t;
  426. if(c1 < 0) {
  427. r->right->vconst = -c1;
  428. c1 = -1;
  429. } else {
  430. r->right->vconst = c1;
  431. c1 = 1;
  432. }
  433. }
  434. if(l == Z) {
  435. l = r;
  436. c2 = c1;
  437. continue;
  438. }
  439. if(c1 < 0)
  440. if(c2 < 0)
  441. l = new1(OADD, l, r);
  442. else
  443. l = new1(OSUB, l, r);
  444. else
  445. if(c2 < 0) {
  446. l = new1(OSUB, r, l);
  447. c2 = 1;
  448. } else
  449. l = new1(OADD, l, r);
  450. l->type = t;
  451. }
  452. if(c2 < 0) {
  453. r = new1(OCONST, 0, 0);
  454. r->vconst = 0;
  455. r->type = t;
  456. l = new1(OSUB, r, l);
  457. l->type = t;
  458. }
  459. *n = *l;
  460. }
  461. void
  462. acom1(vlong v, Node *n)
  463. {
  464. Node *l, *r;
  465. if(v == 0 || nterm >= NTERM)
  466. return;
  467. if(!addo(n)) {
  468. if(n->op == OCONST)
  469. if(!typefd[n->type->etype]) {
  470. term[0].mult += v*n->vconst;
  471. return;
  472. }
  473. term[nterm].mult = v;
  474. term[nterm].node = n;
  475. nterm++;
  476. return;
  477. }
  478. switch(n->op) {
  479. case OCAST:
  480. acom1(v, n->left);
  481. break;
  482. case ONEG:
  483. acom1(-v, n->left);
  484. break;
  485. case OADD:
  486. acom1(v, n->left);
  487. acom1(v, n->right);
  488. break;
  489. case OSUB:
  490. acom1(v, n->left);
  491. acom1(-v, n->right);
  492. break;
  493. case OMUL:
  494. l = n->left;
  495. r = n->right;
  496. if(l->op == OCONST)
  497. if(!typefd[n->type->etype]) {
  498. acom1(v*l->vconst, r);
  499. break;
  500. }
  501. if(r->op == OCONST)
  502. if(!typefd[n->type->etype]) {
  503. acom1(v*r->vconst, l);
  504. break;
  505. }
  506. break;
  507. default:
  508. diag(n, "not addo");
  509. }
  510. }
  511. int
  512. addo(Node *n)
  513. {
  514. if(n != Z)
  515. if(!typefd[n->type->etype])
  516. if(!typev[n->type->etype])
  517. switch(n->op) {
  518. case OCAST:
  519. if(nilcast(n->left->type, n->type))
  520. return 1;
  521. break;
  522. case ONEG:
  523. case OADD:
  524. case OSUB:
  525. return 1;
  526. case OMUL:
  527. if(n->left->op == OCONST)
  528. return 1;
  529. if(n->right->op == OCONST)
  530. return 1;
  531. }
  532. return 0;
  533. }