sgen.c 10.0 KB

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