sgen.c 8.5 KB

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