scon.c 8.6 KB

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