sgen.c 8.9 KB

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