scon.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  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->op = OCONST;
  192. }
  193. void
  194. acom(Node *n)
  195. {
  196. Type *t;
  197. Node *l, *r;
  198. int i;
  199. switch(n->op)
  200. {
  201. case ONAME:
  202. case OCONST:
  203. case OSTRING:
  204. case OINDREG:
  205. case OREGISTER:
  206. return;
  207. case ONEG:
  208. l = n->left;
  209. if(addo(n) && addo(l))
  210. break;
  211. acom(l);
  212. return;
  213. case OADD:
  214. case OSUB:
  215. case OMUL:
  216. l = n->left;
  217. r = n->right;
  218. if(addo(n)) {
  219. if(addo(r))
  220. break;
  221. if(addo(l))
  222. break;
  223. }
  224. acom(l);
  225. acom(r);
  226. return;
  227. default:
  228. l = n->left;
  229. r = n->right;
  230. if(l != Z)
  231. acom(l);
  232. if(r != Z)
  233. acom(r);
  234. return;
  235. }
  236. /* bust terms out */
  237. t = n->type;
  238. term[0].mult = 0;
  239. term[0].node = Z;
  240. nterm = 1;
  241. acom1(1, n);
  242. if(debug['m'])
  243. for(i=0; i<nterm; i++) {
  244. print("%d %3lld ", i, term[i].mult);
  245. prtree1(term[i].node, 1, 0);
  246. }
  247. if(nterm < NTERM)
  248. acom2(n, t);
  249. n->type = t;
  250. }
  251. int
  252. acomcmp1(const void *a1, const void *a2)
  253. {
  254. vlong c1, c2;
  255. Term *t1, *t2;
  256. t1 = (Term*)a1;
  257. t2 = (Term*)a2;
  258. c1 = t1->mult;
  259. if(c1 < 0)
  260. c1 = -c1;
  261. c2 = t2->mult;
  262. if(c2 < 0)
  263. c2 = -c2;
  264. if(c1 > c2)
  265. return 1;
  266. if(c1 < c2)
  267. return -1;
  268. c1 = 1;
  269. if(t1->mult < 0)
  270. c1 = 0;
  271. c2 = 1;
  272. if(t2->mult < 0)
  273. c2 = 0;
  274. if(c2 -= c1)
  275. return c2;
  276. if(t2 > t1)
  277. return 1;
  278. return -1;
  279. }
  280. int
  281. acomcmp2(const void *a1, const void *a2)
  282. {
  283. vlong c1, c2;
  284. Term *t1, *t2;
  285. t1 = (Term*)a1;
  286. t2 = (Term*)a2;
  287. c1 = t1->mult;
  288. c2 = t2->mult;
  289. if(c1 > c2)
  290. return 1;
  291. if(c1 < c2)
  292. return -1;
  293. if(t2 > t1)
  294. return 1;
  295. return -1;
  296. }
  297. void
  298. acom2(Node *n, Type *t)
  299. {
  300. Node *l, *r;
  301. Term trm[NTERM];
  302. int et, nt, i, j;
  303. vlong c1, c2;
  304. /*
  305. * copy into automatic
  306. */
  307. c2 = 0;
  308. nt = nterm;
  309. for(i=0; i<nt; i++)
  310. trm[i] = term[i];
  311. /*
  312. * recur on subtrees
  313. */
  314. j = 0;
  315. for(i=1; i<nt; i++) {
  316. c1 = trm[i].mult;
  317. if(c1 == 0)
  318. continue;
  319. l = trm[i].node;
  320. if(l != Z) {
  321. j = 1;
  322. acom(l);
  323. }
  324. }
  325. c1 = trm[0].mult;
  326. if(j == 0) {
  327. n->op = OCONST;
  328. n->vconst = c1;
  329. return;
  330. }
  331. et = t->etype;
  332. /*
  333. * prepare constant term,
  334. * combine it with an addressing term
  335. */
  336. if(c1 != 0) {
  337. l = new1(OCONST, Z, Z);
  338. l->type = t;
  339. l->vconst = c1;
  340. trm[0].mult = 1;
  341. for(i=1; i<nt; i++) {
  342. if(trm[i].mult != 1)
  343. continue;
  344. r = trm[i].node;
  345. if(r->op != OADDR)
  346. continue;
  347. r->type = t;
  348. l = new1(OADD, r, l);
  349. l->type = t;
  350. trm[i].mult = 0;
  351. break;
  352. }
  353. trm[0].node = l;
  354. }
  355. /*
  356. * look for factorable terms
  357. * c1*i + c1*c2*j -> c1*(i + c2*j)
  358. */
  359. qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp1);
  360. for(i=nt-1; i>=0; i--) {
  361. c1 = trm[i].mult;
  362. if(c1 < 0)
  363. c1 = -c1;
  364. if(c1 <= 1)
  365. continue;
  366. for(j=i+1; j<nt; j++) {
  367. c2 = trm[j].mult;
  368. if(c2 < 0)
  369. c2 = -c2;
  370. if(c2 <= 1)
  371. continue;
  372. if(c2 % c1)
  373. continue;
  374. r = trm[j].node;
  375. if(r->type->etype != et) {
  376. r = new1(OCAST, r, Z);
  377. r->type = t;
  378. }
  379. c2 = trm[j].mult/trm[i].mult;
  380. if(c2 != 1 && c2 != -1) {
  381. r = new1(OMUL, r, new(OCONST, Z, Z));
  382. r->type = t;
  383. r->right->type = t;
  384. r->right->vconst = c2;
  385. }
  386. l = trm[i].node;
  387. if(l->type->etype != et) {
  388. l = new1(OCAST, l, Z);
  389. l->type = t;
  390. }
  391. r = new1(OADD, l, r);
  392. r->type = t;
  393. if(c2 == -1)
  394. r->op = OSUB;
  395. trm[i].node = r;
  396. trm[j].mult = 0;
  397. }
  398. }
  399. if(debug['m']) {
  400. print("\n");
  401. for(i=0; i<nt; i++) {
  402. print("%d %3lld ", i, trm[i].mult);
  403. prtree1(trm[i].node, 1, 0);
  404. }
  405. }
  406. /*
  407. * put it all back together
  408. */
  409. qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp2);
  410. l = Z;
  411. for(i=nt-1; i>=0; i--) {
  412. c1 = trm[i].mult;
  413. if(c1 == 0)
  414. continue;
  415. r = trm[i].node;
  416. if(r->type->etype != et || r->op == OBIT) {
  417. r = new1(OCAST, r, Z);
  418. r->type = t;
  419. }
  420. if(c1 != 1 && c1 != -1) {
  421. r = new1(OMUL, r, new(OCONST, Z, Z));
  422. r->type = t;
  423. r->right->type = t;
  424. if(c1 < 0) {
  425. r->right->vconst = -c1;
  426. c1 = -1;
  427. } else {
  428. r->right->vconst = c1;
  429. c1 = 1;
  430. }
  431. }
  432. if(l == Z) {
  433. l = r;
  434. c2 = c1;
  435. continue;
  436. }
  437. if(c1 < 0)
  438. if(c2 < 0)
  439. l = new1(OADD, l, r);
  440. else
  441. l = new1(OSUB, l, r);
  442. else
  443. if(c2 < 0) {
  444. l = new1(OSUB, r, l);
  445. c2 = 1;
  446. } else
  447. l = new1(OADD, l, r);
  448. l->type = t;
  449. }
  450. if(c2 < 0) {
  451. r = new1(OCONST, 0, 0);
  452. r->vconst = 0;
  453. r->type = t;
  454. l = new1(OSUB, r, l);
  455. l->type = t;
  456. }
  457. *n = *l;
  458. }
  459. void
  460. acom1(vlong v, Node *n)
  461. {
  462. Node *l, *r;
  463. if(v == 0 || nterm >= NTERM)
  464. return;
  465. if(!addo(n)) {
  466. if(n->op == OCONST)
  467. if(!typefd[n->type->etype]) {
  468. term[0].mult += v*n->vconst;
  469. return;
  470. }
  471. term[nterm].mult = v;
  472. term[nterm].node = n;
  473. nterm++;
  474. return;
  475. }
  476. switch(n->op) {
  477. case OCAST:
  478. acom1(v, n->left);
  479. break;
  480. case ONEG:
  481. acom1(-v, n->left);
  482. break;
  483. case OADD:
  484. acom1(v, n->left);
  485. acom1(v, n->right);
  486. break;
  487. case OSUB:
  488. acom1(v, n->left);
  489. acom1(-v, n->right);
  490. break;
  491. case OMUL:
  492. l = n->left;
  493. r = n->right;
  494. if(l->op == OCONST)
  495. if(!typefd[n->type->etype]) {
  496. acom1(v*l->vconst, r);
  497. break;
  498. }
  499. if(r->op == OCONST)
  500. if(!typefd[n->type->etype]) {
  501. acom1(v*r->vconst, l);
  502. break;
  503. }
  504. break;
  505. default:
  506. diag(n, "not addo");
  507. }
  508. }
  509. int
  510. addo(Node *n)
  511. {
  512. if(n != Z)
  513. if(!typefd[n->type->etype])
  514. if(!typev[n->type->etype])
  515. switch(n->op) {
  516. case OCAST:
  517. if(nilcast(n->left->type, n->type))
  518. return 1;
  519. break;
  520. case ONEG:
  521. case OADD:
  522. case OSUB:
  523. return 1;
  524. case OMUL:
  525. if(n->left->op == OCONST)
  526. return 1;
  527. if(n->right->op == OCONST)
  528. return 1;
  529. }
  530. return 0;
  531. }