sgen.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. #include "gc.h"
  2. void
  3. codgen(Node *n, Node *nn)
  4. {
  5. Prog *sp;
  6. argoff = 0;
  7. inargs = 0;
  8. for(;; nn = nn->left) {
  9. if(nn == Z) {
  10. diag(Z, "cant find function name");
  11. return;
  12. }
  13. if(nn->op == ONAME)
  14. break;
  15. }
  16. nearln = nn->lineno;
  17. gpseudo(ATEXT, nn->sym, D_CONST, stkoff);
  18. sp = p;
  19. retok = 0;
  20. gen(n);
  21. if(!retok)
  22. if(thisfn->link->etype != TVOID)
  23. warn(Z, "no return at end of function: %s", nn->sym->name);
  24. noretval(3);
  25. gbranch(ORETURN);
  26. if(!debug['N'] || debug['R'] || debug['P'])
  27. regopt(sp);
  28. }
  29. void
  30. gen(Node *n)
  31. {
  32. Node *l;
  33. Prog *sp, *spc, *spb;
  34. Case *cn;
  35. long sbc, scc;
  36. int snbreak;
  37. int g, o;
  38. loop:
  39. if(n == Z)
  40. return;
  41. nearln = n->lineno;
  42. o = n->op;
  43. if(debug['G'])
  44. if(o != OLIST)
  45. print("%L %O\n", nearln, o);
  46. retok = 0;
  47. switch(o) {
  48. default:
  49. complex(n);
  50. doinc(n, PRE);
  51. cgen(n, D_NONE, n);
  52. doinc(n, POST);
  53. break;
  54. case OLIST:
  55. gen(n->left);
  56. rloop:
  57. n = n->right;
  58. goto loop;
  59. case ORETURN:
  60. retok = 1;
  61. complex(n);
  62. if(n->type == T)
  63. break;
  64. l = n->left;
  65. if(l == Z) {
  66. noretval(3);
  67. gbranch(ORETURN);
  68. break;
  69. }
  70. doinc(l, PRE);
  71. if(typesuv[n->type->etype]) {
  72. sugen(l, D_TREE, nodret, n->type->width);
  73. doinc(l, POST);
  74. noretval(3);
  75. gbranch(ORETURN);
  76. break;
  77. }
  78. g = regalloc(n->type, regret(n->type));
  79. cgen(l, g, n);
  80. doinc(l, POST);
  81. if(typefd[n->type->etype])
  82. noretval(1);
  83. else
  84. noretval(2);
  85. gbranch(ORETURN);
  86. regfree(g);
  87. break;
  88. case OLABEL:
  89. l = n->left;
  90. if(l) {
  91. l->xoffset = pc;
  92. if(l->label)
  93. patch(l->label, pc);
  94. }
  95. gbranch(OGOTO); /* prevent self reference in reg */
  96. patch(p, pc);
  97. goto rloop;
  98. case OGOTO:
  99. retok = 1;
  100. n = n->left;
  101. if(n == Z)
  102. return;
  103. if(n->complex == 0) {
  104. diag(Z, "label undefined: %s", n->sym->name);
  105. return;
  106. }
  107. gbranch(OGOTO);
  108. if(n->xoffset) {
  109. patch(p, n->xoffset);
  110. return;
  111. }
  112. if(n->label)
  113. patch(n->label, pc-1);
  114. n->label = p;
  115. return;
  116. case OCASE:
  117. l = n->left;
  118. if(cases == C)
  119. diag(n, "case/default outside a switch");
  120. if(l == Z) {
  121. cas();
  122. cases->val = 0;
  123. cases->def = 1;
  124. cases->label = pc;
  125. setsp();;
  126. goto rloop;
  127. }
  128. complex(l);
  129. if(l->type == T)
  130. goto rloop;
  131. if(l->op == OCONST)
  132. if(typechl[l->type->etype]) {
  133. cas();
  134. cases->val = l->vconst;
  135. cases->def = 0;
  136. cases->label = pc;
  137. setsp();
  138. goto rloop;
  139. }
  140. diag(n, "case expression must be integer constant");
  141. goto rloop;
  142. case OSWITCH:
  143. l = n->left;
  144. complex(l);
  145. doinc(l, PRE);
  146. if(l->type == T)
  147. break;
  148. if(!typechl[l->type->etype]) {
  149. diag(n, "switch expression must be integer");
  150. break;
  151. }
  152. g = regalloc(types[TLONG], D_NONE);
  153. n->type = types[TLONG];
  154. cgen(l, g, n);
  155. regfree(g);
  156. doinc(l, POST);
  157. setsp();
  158. gbranch(OGOTO); /* entry */
  159. sp = p;
  160. cn = cases;
  161. cases = C;
  162. cas();
  163. sbc = breakpc;
  164. breakpc = pc;
  165. snbreak = nbreak;
  166. nbreak = 0;
  167. gbranch(OGOTO);
  168. spb = p;
  169. gen(n->right);
  170. gbranch(OGOTO);
  171. patch(p, breakpc);
  172. nbreak++;
  173. patch(sp, pc);
  174. doswit(g, l);
  175. patch(spb, pc);
  176. cases = cn;
  177. breakpc = sbc;
  178. nbreak = snbreak;
  179. setsp();
  180. break;
  181. case OWHILE:
  182. case ODWHILE:
  183. l = n->left;
  184. gbranch(OGOTO); /* entry */
  185. sp = p;
  186. scc = continpc;
  187. continpc = pc;
  188. gbranch(OGOTO);
  189. spc = p;
  190. sbc = breakpc;
  191. breakpc = pc;
  192. snbreak = nbreak;
  193. nbreak = 0;
  194. gbranch(OGOTO);
  195. spb = p;
  196. patch(spc, pc);
  197. if(n->op == OWHILE)
  198. patch(sp, pc);
  199. bcomplex(l); /* test */
  200. patch(p, breakpc);
  201. if(l->op != OCONST || vconst(l) == 0)
  202. nbreak++;
  203. if(n->op == ODWHILE)
  204. patch(sp, pc);
  205. gen(n->right); /* body */
  206. gbranch(OGOTO);
  207. patch(p, continpc);
  208. patch(spb, pc);
  209. continpc = scc;
  210. breakpc = sbc;
  211. if(nbreak == 0)
  212. retok = 1;
  213. nbreak = snbreak;
  214. break;
  215. case OFOR:
  216. l = n->left;
  217. gen(l->right->left); /* init */
  218. gbranch(OGOTO); /* entry */
  219. sp = p;
  220. scc = continpc;
  221. continpc = pc;
  222. gbranch(OGOTO);
  223. spc = p;
  224. sbc = breakpc;
  225. breakpc = pc;
  226. snbreak = nbreak;
  227. nbreak = 0;
  228. gbranch(OGOTO);
  229. spb = p;
  230. patch(spc, pc);
  231. gen(l->right->right); /* inc */
  232. patch(sp, pc);
  233. if(l->left != Z) { /* test */
  234. bcomplex(l->left);
  235. patch(p, breakpc);
  236. if(l->left->op != OCONST || vconst(l->left) == 0)
  237. nbreak++;
  238. }
  239. gen(n->right); /* body */
  240. gbranch(OGOTO);
  241. patch(p, continpc);
  242. patch(spb, pc);
  243. continpc = scc;
  244. breakpc = sbc;
  245. if(nbreak == 0)
  246. retok = 1;
  247. nbreak = snbreak;
  248. break;
  249. case OCONTINUE:
  250. if(continpc < 0) {
  251. diag(n, "continue not in a loop");
  252. break;
  253. }
  254. gbranch(OGOTO);
  255. patch(p, continpc);
  256. break;
  257. case OBREAK:
  258. if(breakpc < 0) {
  259. diag(n, "break not in a loop");
  260. break;
  261. }
  262. gbranch(OGOTO);
  263. patch(p, breakpc);
  264. nbreak++;
  265. break;
  266. case OIF:
  267. l = n->left;
  268. bcomplex(l);
  269. sp = p;
  270. if(n->right->left != Z)
  271. gen(n->right->left);
  272. if(n->right->right != Z) {
  273. gbranch(OGOTO);
  274. patch(sp, pc);
  275. sp = p;
  276. gen(n->right->right);
  277. }
  278. patch(sp, pc);
  279. break;
  280. case OSET:
  281. case OUSED:
  282. usedset(n->left, o);
  283. break;
  284. }
  285. }
  286. void
  287. usedset(Node *n, int o)
  288. {
  289. if(n->op == OLIST) {
  290. usedset(n->left, o);
  291. usedset(n->right, o);
  292. return;
  293. }
  294. complex(n);
  295. switch(n->op) {
  296. case OADDR: /* volatile */
  297. gopcode(OTST, types[TINT], D_TREE, n, D_NONE, Z);
  298. p->as = ANOP;
  299. break;
  300. case ONAME:
  301. if(o == OSET)
  302. gopcode(OTST, types[TINT], D_NONE, Z, D_TREE, n);
  303. else
  304. gopcode(OTST, types[TINT], D_TREE, n, D_NONE, Z);
  305. p->as = ANOP;
  306. break;
  307. }
  308. }
  309. void
  310. noretval(int n)
  311. {
  312. if(n & 1) {
  313. gopcode(OTST, types[TINT], D_NONE, Z, regret(types[TLONG]), Z);
  314. p->as = ANOP;
  315. }
  316. if(n & 2) {
  317. gopcode(OTST, types[TINT], D_NONE, Z, regret(types[TDOUBLE]), Z);
  318. p->as = ANOP;
  319. }
  320. }
  321. /*
  322. * calculate addressability as follows
  323. * REGISTER ==> 12 register
  324. * NAME ==> 11 name+value(SB/SP)
  325. * note that 10 is no longer generated
  326. * CONST ==> 20 $value
  327. * *(20) ==> 21 value
  328. * &(10) ==> 12 $name+value(SB)
  329. * &(11) ==> 1 $name+value(SP)
  330. * (12) + (20) ==> 12 fold constants
  331. * (1) + (20) ==> 1 fold constants
  332. * *(12) ==> 10 back to name
  333. * *(1) ==> 11 back to name
  334. *
  335. * (2,10,11) + (20) ==> 2 indirect w offset
  336. * (2) ==> &13
  337. * *(10,11) ==> 13 indirect, no index
  338. *
  339. * (20) * (X) ==> 7 multiplier in indexing
  340. * (X,7) + (12,1) ==> 8 adder in indexing (addresses)
  341. * (X,7) + (10,11,2) ==> 8 adder in indexing (names)
  342. * (8) ==> &9 index, almost addressable
  343. *
  344. * (X)++ ==> X fake addressability
  345. *
  346. * calculate complexity (number of registers)
  347. */
  348. void
  349. xcom(Node *n)
  350. {
  351. Node *l, *r;
  352. int g;
  353. if(n == Z)
  354. return;
  355. l = n->left;
  356. r = n->right;
  357. n->complex = 0;
  358. n->addable = 0;
  359. switch(n->op) {
  360. case OCONST:
  361. n->addable = 20;
  362. break;
  363. case ONAME:
  364. n->addable = 11; /* difference to make relocatable */
  365. break;
  366. case OREGISTER:
  367. n->addable = 12;
  368. break;
  369. case OADDR:
  370. xcom(l);
  371. if(l->addable == 10)
  372. n->addable = 12;
  373. else
  374. if(l->addable == 11)
  375. n->addable = 1;
  376. break;
  377. case OADD:
  378. xcom(l);
  379. xcom(r);
  380. if(n->type->etype != TIND)
  381. break;
  382. if(l->addable == 20)
  383. switch(r->addable) {
  384. case 12:
  385. case 1:
  386. n->addable = r->addable;
  387. goto brk;
  388. }
  389. if(r->addable == 20)
  390. switch(l->addable) {
  391. case 12:
  392. case 1:
  393. n->addable = l->addable;
  394. goto brk;
  395. }
  396. break;
  397. case OIND:
  398. xcom(l);
  399. if(l->op == OADDR) {
  400. l = l->left;
  401. l->type = n->type;
  402. *n = *l;
  403. return;
  404. }
  405. switch(l->addable) {
  406. case 20:
  407. n->addable = 21;
  408. break;
  409. case 1:
  410. n->addable = 11;
  411. break;
  412. case 12:
  413. n->addable = 10;
  414. break;
  415. }
  416. break;
  417. case OASHL:
  418. xcom(l);
  419. xcom(r);
  420. if(typev[n->type->etype])
  421. break;
  422. g = vconst(r);
  423. if(g >= 0 && g < 4)
  424. n->addable = 7;
  425. break;
  426. case OMUL:
  427. case OLMUL:
  428. xcom(l);
  429. xcom(r);
  430. if(typev[n->type->etype])
  431. break;
  432. g = vlog(r);
  433. if(g >= 0) {
  434. n->op = OASHL;
  435. r->vconst = g;
  436. if(g < 4)
  437. n->addable = 7;
  438. break;
  439. }
  440. g = vlog(l);
  441. if(g >= 0) {
  442. n->left = r;
  443. n->right = l;
  444. l = r;
  445. r = n->right;
  446. n->op = OASHL;
  447. r->vconst = g;
  448. if(g < 4)
  449. n->addable = 7;
  450. break;
  451. }
  452. break;
  453. case ODIV:
  454. case OLDIV:
  455. xcom(l);
  456. xcom(r);
  457. if(typev[n->type->etype])
  458. break;
  459. g = vlog(r);
  460. if(g >= 0) {
  461. if(n->op == ODIV)
  462. n->op = OASHR;
  463. else
  464. n->op = OLSHR;
  465. r->vconst = g;
  466. }
  467. break;
  468. case OSUB:
  469. xcom(l);
  470. xcom(r);
  471. if(typev[n->type->etype])
  472. break;
  473. if(vconst(l) == 0) {
  474. n->op = ONEG;
  475. n->left = r;
  476. n->right = Z;
  477. }
  478. break;
  479. case OXOR:
  480. xcom(l);
  481. xcom(r);
  482. if(typev[n->type->etype])
  483. break;
  484. if(vconst(l) == -1) {
  485. n->op = OCOM;
  486. n->left = r;
  487. n->right = Z;
  488. }
  489. break;
  490. case OASMUL:
  491. case OASLMUL:
  492. xcom(l);
  493. xcom(r);
  494. if(typev[n->type->etype])
  495. break;
  496. g = vlog(r);
  497. if(g >= 0) {
  498. n->op = OASASHL;
  499. r->vconst = g;
  500. }
  501. goto aseae;
  502. case OASDIV:
  503. case OASLDIV:
  504. xcom(l);
  505. xcom(r);
  506. if(typev[n->type->etype])
  507. break;
  508. g = vlog(r);
  509. if(g >= 0) {
  510. if(n->op == OASDIV)
  511. n->op = OASASHR;
  512. else
  513. n->op = OASLSHR;
  514. r->vconst = g;
  515. }
  516. goto aseae;
  517. case OASLMOD:
  518. case OASMOD:
  519. xcom(l);
  520. xcom(r);
  521. if(typev[n->type->etype])
  522. break;
  523. aseae: /* hack that there are no byte/short mul/div operators */
  524. if(n->type->etype == TCHAR || n->type->etype == TSHORT) {
  525. n->right = new1(OCAST, n->right, Z);
  526. n->right->type = types[TLONG];
  527. n->type = types[TLONG];
  528. }
  529. if(n->type->etype == TUCHAR || n->type->etype == TUSHORT) {
  530. n->right = new1(OCAST, n->right, Z);
  531. n->right->type = types[TULONG];
  532. n->type = types[TULONG];
  533. }
  534. goto asop;
  535. case OASXOR:
  536. case OASOR:
  537. case OASADD:
  538. case OASSUB:
  539. case OASLSHR:
  540. case OASASHR:
  541. case OASASHL:
  542. case OASAND:
  543. case OAS:
  544. xcom(l);
  545. xcom(r);
  546. if(typev[n->type->etype])
  547. break;
  548. asop:
  549. if(l->addable > INDEXED &&
  550. l->complex < FNX &&
  551. r && r->complex < FNX)
  552. n->addable = l->addable;
  553. break;
  554. case OPOSTINC:
  555. case OPREINC:
  556. case OPOSTDEC:
  557. case OPREDEC:
  558. xcom(l);
  559. if(typev[n->type->etype])
  560. break;
  561. if(l->addable > INDEXED &&
  562. l->complex < FNX)
  563. n->addable = l->addable;
  564. break;
  565. default:
  566. if(l != Z)
  567. xcom(l);
  568. if(r != Z)
  569. xcom(r);
  570. break;
  571. }
  572. brk:
  573. n->complex = 0;
  574. if(n->addable >= 10)
  575. return;
  576. if(l != Z)
  577. n->complex = l->complex;
  578. if(r != Z) {
  579. if(r->complex == n->complex)
  580. n->complex = r->complex+1;
  581. else
  582. if(r->complex > n->complex)
  583. n->complex = r->complex;
  584. }
  585. if(n->complex == 0)
  586. n->complex++;
  587. if(com64(n))
  588. return;
  589. switch(n->op) {
  590. case OFUNC:
  591. n->complex = FNX;
  592. break;
  593. case OADD:
  594. case OMUL:
  595. case OLMUL:
  596. case OXOR:
  597. case OAND:
  598. case OOR:
  599. /*
  600. * symmetric operators, make right side simple
  601. * if same, put constant on left to get movq
  602. */
  603. if(r->complex > l->complex ||
  604. (r->complex == l->complex && r->addable == 20)) {
  605. n->left = r;
  606. n->right = l;
  607. }
  608. break;
  609. case OLE:
  610. case OLT:
  611. case OGE:
  612. case OGT:
  613. case OEQ:
  614. case ONE:
  615. /*
  616. * relational operators, make right side simple
  617. * if same, put constant on left to get movq
  618. */
  619. if(r->complex > l->complex || r->addable == 20) {
  620. n->left = r;
  621. n->right = l;
  622. n->op = invrel[relindex(n->op)];
  623. }
  624. break;
  625. }
  626. }
  627. void
  628. bcomplex(Node *n)
  629. {
  630. complex(n);
  631. if(n->type != T)
  632. if(tcompat(n, T, n->type, tnot))
  633. n->type = T;
  634. if(n->type != T) {
  635. bool64(n);
  636. doinc(n, PRE);
  637. boolgen(n, 1, D_NONE, Z, n);
  638. } else
  639. gbranch(OGOTO);
  640. }
  641. Node*
  642. nodconst(long v)
  643. {
  644. return (Node*)v;
  645. }