con.c 8.2 KB

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