cgen.c 18 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. #include "gc.h"
  2. void
  3. cgen(Node *n, Node *nn)
  4. {
  5. Node *l, *r;
  6. Prog *p1;
  7. Node nod, nod1, nod2, nod3, nod4;
  8. int o;
  9. long v, curs;
  10. if(debug['g']) {
  11. prtree(nn, "cgen lhs");
  12. prtree(n, "cgen");
  13. }
  14. if(n == Z || n->type == T)
  15. return;
  16. if(typesuv[n->type->etype]) {
  17. sugen(n, nn, n->type->width);
  18. return;
  19. }
  20. l = n->left;
  21. r = n->right;
  22. o = n->op;
  23. if(n->addable >= INDEXED) {
  24. if(nn == Z) {
  25. switch(o) {
  26. default:
  27. nullwarn(Z, Z);
  28. break;
  29. case OINDEX:
  30. nullwarn(l, r);
  31. break;
  32. }
  33. return;
  34. }
  35. gmove(n, nn);
  36. return;
  37. }
  38. curs = cursafe;
  39. if(n->complex >= FNX)
  40. if(l->complex >= FNX)
  41. if(r != Z && r->complex >= FNX)
  42. switch(o) {
  43. default:
  44. regret(&nod, r);
  45. cgen(r, &nod);
  46. regsalloc(&nod1, r);
  47. gopcode(OAS, &nod, Z, &nod1);
  48. regfree(&nod);
  49. nod = *n;
  50. nod.right = &nod1;
  51. cgen(&nod, nn);
  52. return;
  53. case OFUNC:
  54. case OCOMMA:
  55. case OANDAND:
  56. case OOROR:
  57. case OCOND:
  58. case ODOT:
  59. break;
  60. }
  61. switch(o) {
  62. default:
  63. diag(n, "unknown op in cgen: %O", o);
  64. break;
  65. case OAS:
  66. if(l->op == OBIT)
  67. goto bitas;
  68. if(l->addable >= INDEXED) {
  69. if(nn != Z || r->addable < INDEXED) {
  70. regalloc(&nod, r, nn);
  71. cgen(r, &nod);
  72. gmove(&nod, l);
  73. regfree(&nod);
  74. } else
  75. gmove(r, l);
  76. break;
  77. }
  78. if(l->complex >= r->complex) {
  79. reglcgen(&nod1, l, Z);
  80. if(r->addable >= INDEXED) {
  81. gmove(r, &nod1);
  82. if(nn != Z)
  83. gmove(r, nn);
  84. regfree(&nod1);
  85. break;
  86. }
  87. regalloc(&nod, r, nn);
  88. cgen(r, &nod);
  89. } else {
  90. regalloc(&nod, r, nn);
  91. cgen(r, &nod);
  92. reglcgen(&nod1, l, Z);
  93. }
  94. gmove(&nod, &nod1);
  95. regfree(&nod);
  96. regfree(&nod1);
  97. break;
  98. bitas:
  99. n = l->left;
  100. regalloc(&nod, r, nn);
  101. if(l->complex >= r->complex) {
  102. reglcgen(&nod1, n, Z);
  103. cgen(r, &nod);
  104. } else {
  105. cgen(r, &nod);
  106. reglcgen(&nod1, n, Z);
  107. }
  108. regalloc(&nod2, n, Z);
  109. gopcode(OAS, &nod1, Z, &nod2);
  110. bitstore(l, &nod, &nod1, &nod2, nn);
  111. break;
  112. case OBIT:
  113. if(nn == Z) {
  114. nullwarn(l, Z);
  115. break;
  116. }
  117. bitload(n, &nod, Z, Z, nn);
  118. gopcode(OAS, &nod, Z, nn);
  119. regfree(&nod);
  120. break;
  121. case OXOR:
  122. if(nn != Z)
  123. if(r->op == OCONST && r->vconst == -1){
  124. cgen(l, nn);
  125. gopcode(OCOM, nn, Z, nn);
  126. break;
  127. }
  128. case OADD:
  129. case OSUB:
  130. case OAND:
  131. case OOR:
  132. case OLSHR:
  133. case OASHL:
  134. case OASHR:
  135. /*
  136. * immediate operands
  137. */
  138. if(nn != Z)
  139. if(r->op == OCONST)
  140. if(!typefd[n->type->etype]) {
  141. cgen(l, nn);
  142. if(r->vconst == 0)
  143. if(o != OAND)
  144. break;
  145. if(nn != Z)
  146. gopcode(o, r, Z, nn);
  147. break;
  148. }
  149. case OMUL:
  150. case OLMUL:
  151. case OLDIV:
  152. case OLMOD:
  153. case ODIV:
  154. case OMOD:
  155. if(nn == Z) {
  156. nullwarn(l, r);
  157. break;
  158. }
  159. if(o == OMUL || o == OLMUL) {
  160. if(mulcon(n, nn))
  161. break;
  162. if(debug['M'])
  163. print("%L multiply\n", n->lineno);
  164. }
  165. if(l->complex >= r->complex) {
  166. regalloc(&nod, l, nn);
  167. cgen(l, &nod);
  168. regalloc(&nod1, r, Z);
  169. cgen(r, &nod1);
  170. gopcode(o, &nod1, Z, &nod);
  171. } else {
  172. regalloc(&nod, r, nn);
  173. cgen(r, &nod);
  174. regalloc(&nod1, l, Z);
  175. cgen(l, &nod1);
  176. gopcode(o, &nod, &nod1, &nod);
  177. }
  178. gopcode(OAS, &nod, Z, nn);
  179. regfree(&nod);
  180. regfree(&nod1);
  181. break;
  182. case OASLSHR:
  183. case OASASHL:
  184. case OASASHR:
  185. case OASAND:
  186. case OASADD:
  187. case OASSUB:
  188. case OASXOR:
  189. case OASOR:
  190. if(l->op == OBIT)
  191. goto asbitop;
  192. if(r->op == OCONST)
  193. if(!typefd[r->type->etype])
  194. if(!typefd[n->type->etype]) {
  195. if(l->addable < INDEXED)
  196. reglcgen(&nod2, l, Z);
  197. else
  198. nod2 = *l;
  199. regalloc(&nod, r, nn);
  200. gopcode(OAS, &nod2, Z, &nod);
  201. gopcode(o, r, Z, &nod);
  202. gopcode(OAS, &nod, Z, &nod2);
  203. regfree(&nod);
  204. if(l->addable < INDEXED)
  205. regfree(&nod2);
  206. break;
  207. }
  208. case OASLMUL:
  209. case OASLDIV:
  210. case OASLMOD:
  211. case OASMUL:
  212. case OASDIV:
  213. case OASMOD:
  214. if(l->op == OBIT)
  215. goto asbitop;
  216. if(l->complex >= r->complex) {
  217. if(l->addable < INDEXED)
  218. reglcgen(&nod2, l, Z);
  219. else
  220. nod2 = *l;
  221. regalloc(&nod, n, nn);
  222. cgen(r, &nod);
  223. } else {
  224. regalloc(&nod, n, nn);
  225. cgen(r, &nod);
  226. if(l->addable < INDEXED)
  227. reglcgen(&nod2, l, Z);
  228. else
  229. nod2 = *l;
  230. }
  231. regalloc(&nod1, n, Z);
  232. gopcode(OAS, &nod2, Z, &nod1);
  233. gopcode(o, &nod, &nod1, &nod);
  234. gopcode(OAS, &nod, Z, &nod2);
  235. regfree(&nod);
  236. regfree(&nod1);
  237. if(l->addable < INDEXED)
  238. regfree(&nod2);
  239. break;
  240. asbitop:
  241. regalloc(&nod4, n, nn);
  242. regalloc(&nod3, r, Z);
  243. if(l->complex >= r->complex) {
  244. bitload(l, &nod, &nod1, &nod2, &nod4);
  245. cgen(r, &nod3);
  246. } else {
  247. cgen(r, &nod3);
  248. bitload(l, &nod, &nod1, &nod2, &nod4);
  249. }
  250. gmove(&nod, &nod4);
  251. gopcode(n->op, &nod3, Z, &nod4);
  252. regfree(&nod3);
  253. gmove(&nod4, &nod);
  254. regfree(&nod4);
  255. bitstore(l, &nod, &nod1, &nod2, nn);
  256. break;
  257. case OADDR:
  258. if(nn == Z) {
  259. nullwarn(l, Z);
  260. break;
  261. }
  262. lcgen(l, nn);
  263. break;
  264. case OFUNC:
  265. if(l->complex >= FNX) {
  266. if(l->op != OIND)
  267. diag(n, "bad function call");
  268. regret(&nod, l->left);
  269. cgen(l->left, &nod);
  270. regsalloc(&nod1, l->left);
  271. gopcode(OAS, &nod, Z, &nod1);
  272. regfree(&nod);
  273. nod = *n;
  274. nod.left = &nod2;
  275. nod2 = *l;
  276. nod2.left = &nod1;
  277. nod2.complex = 1;
  278. cgen(&nod, nn);
  279. return;
  280. }
  281. o = reg[REGARG];
  282. gargs(r, &nod, &nod1);
  283. if(l->addable < INDEXED) {
  284. reglcgen(&nod, l, Z);
  285. gopcode(OFUNC, Z, Z, &nod);
  286. regfree(&nod);
  287. } else
  288. gopcode(OFUNC, Z, Z, l);
  289. if(REGARG)
  290. if(o != reg[REGARG])
  291. reg[REGARG]--;
  292. if(nn != Z) {
  293. regret(&nod, n);
  294. gopcode(OAS, &nod, Z, nn);
  295. regfree(&nod);
  296. }
  297. break;
  298. case OIND:
  299. if(nn == Z) {
  300. cgen(l, nn);
  301. break;
  302. }
  303. regialloc(&nod, n, nn);
  304. r = l;
  305. while(r->op == OADD)
  306. r = r->right;
  307. if(sconst(r)) {
  308. v = r->vconst;
  309. r->vconst = 0;
  310. cgen(l, &nod);
  311. nod.xoffset += v;
  312. r->vconst = v;
  313. } else
  314. cgen(l, &nod);
  315. regind(&nod, n);
  316. gopcode(OAS, &nod, Z, nn);
  317. regfree(&nod);
  318. break;
  319. case OEQ:
  320. case ONE:
  321. case OLE:
  322. case OLT:
  323. case OGE:
  324. case OGT:
  325. case OLO:
  326. case OLS:
  327. case OHI:
  328. case OHS:
  329. if(nn == Z) {
  330. nullwarn(l, r);
  331. break;
  332. }
  333. boolgen(n, 1, nn);
  334. break;
  335. case OANDAND:
  336. case OOROR:
  337. boolgen(n, 1, nn);
  338. if(nn == Z)
  339. patch(p, pc);
  340. break;
  341. case ONOT:
  342. if(nn == Z) {
  343. nullwarn(l, Z);
  344. break;
  345. }
  346. boolgen(n, 1, nn);
  347. break;
  348. case OCOMMA:
  349. cgen(l, Z);
  350. cgen(r, nn);
  351. break;
  352. case OCAST:
  353. if(nn == Z) {
  354. nullwarn(l, Z);
  355. break;
  356. }
  357. /*
  358. * convert from types l->n->nn
  359. */
  360. if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
  361. /* both null, gen l->nn */
  362. cgen(l, nn);
  363. break;
  364. }
  365. regalloc(&nod, l, nn);
  366. cgen(l, &nod);
  367. regalloc(&nod1, n, &nod);
  368. gopcode(OAS, &nod, Z, &nod1);
  369. gopcode(OAS, &nod1, Z, nn);
  370. regfree(&nod1);
  371. regfree(&nod);
  372. break;
  373. case ODOT:
  374. sugen(l, nodrat, l->type->width);
  375. if(nn != Z) {
  376. warn(n, "non-interruptable temporary");
  377. nod = *nodrat;
  378. if(!r || r->op != OCONST) {
  379. diag(n, "DOT and no offset");
  380. break;
  381. }
  382. nod.xoffset += (long)r->vconst;
  383. nod.type = n->type;
  384. cgen(&nod, nn);
  385. }
  386. break;
  387. case OCOND:
  388. bcgen(l, 1);
  389. p1 = p;
  390. cgen(r->left, nn);
  391. gbranch(OGOTO);
  392. patch(p1, pc);
  393. p1 = p;
  394. cgen(r->right, nn);
  395. patch(p1, pc);
  396. break;
  397. case OPOSTINC:
  398. case OPOSTDEC:
  399. v = 1;
  400. if(l->type->etype == TIND)
  401. v = l->type->link->width;
  402. if(o == OPOSTDEC)
  403. v = -v;
  404. if(l->op == OBIT)
  405. goto bitinc;
  406. if(nn == Z)
  407. goto pre;
  408. if(l->addable < INDEXED)
  409. reglcgen(&nod2, l, Z);
  410. else
  411. nod2 = *l;
  412. regalloc(&nod, l, nn);
  413. gopcode(OAS, &nod2, Z, &nod);
  414. regalloc(&nod1, l, Z);
  415. if(typefd[l->type->etype]) {
  416. regalloc(&nod3, l, Z);
  417. if(v < 0) {
  418. gopcode(OAS, nodfconst(-v), Z, &nod3);
  419. gopcode(OSUB, &nod3, &nod, &nod1);
  420. } else {
  421. gopcode(OAS, nodfconst(v), Z, &nod3);
  422. gopcode(OADD, &nod3, &nod, &nod1);
  423. }
  424. regfree(&nod3);
  425. } else
  426. gopcode(OADD, nodconst(v), &nod, &nod1);
  427. gopcode(OAS, &nod1, Z, &nod2);
  428. regfree(&nod);
  429. regfree(&nod1);
  430. if(l->addable < INDEXED)
  431. regfree(&nod2);
  432. break;
  433. case OPREINC:
  434. case OPREDEC:
  435. v = 1;
  436. if(l->type->etype == TIND)
  437. v = l->type->link->width;
  438. if(o == OPREDEC)
  439. v = -v;
  440. if(l->op == OBIT)
  441. goto bitinc;
  442. pre:
  443. if(l->addable < INDEXED)
  444. reglcgen(&nod2, l, Z);
  445. else
  446. nod2 = *l;
  447. regalloc(&nod, l, nn);
  448. gopcode(OAS, &nod2, Z, &nod);
  449. if(typefd[l->type->etype]) {
  450. regalloc(&nod3, l, Z);
  451. if(v < 0) {
  452. gopcode(OAS, nodfconst(-v), Z, &nod3);
  453. gopcode(OSUB, &nod3, Z, &nod);
  454. } else {
  455. gopcode(OAS, nodfconst(v), Z, &nod3);
  456. gopcode(OADD, &nod3, Z, &nod);
  457. }
  458. regfree(&nod3);
  459. } else
  460. gopcode(OADD, nodconst(v), Z, &nod);
  461. gopcode(OAS, &nod, Z, &nod2);
  462. if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
  463. gins(ANOP, l, Z);
  464. regfree(&nod);
  465. if(l->addable < INDEXED)
  466. regfree(&nod2);
  467. break;
  468. bitinc:
  469. if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
  470. bitload(l, &nod, &nod1, &nod2, Z);
  471. gopcode(OAS, &nod, Z, nn);
  472. gopcode(OADD, nodconst(v), Z, &nod);
  473. bitstore(l, &nod, &nod1, &nod2, Z);
  474. break;
  475. }
  476. bitload(l, &nod, &nod1, &nod2, nn);
  477. gopcode(OADD, nodconst(v), Z, &nod);
  478. bitstore(l, &nod, &nod1, &nod2, nn);
  479. break;
  480. }
  481. cursafe = curs;
  482. }
  483. void
  484. reglcgen(Node *t, Node *n, Node *nn)
  485. {
  486. Node *r;
  487. long v;
  488. regialloc(t, n, nn);
  489. if(n->op == OIND) {
  490. r = n->left;
  491. while(r->op == OADD)
  492. r = r->right;
  493. if(sconst(r)) {
  494. v = r->vconst;
  495. r->vconst = 0;
  496. lcgen(n, t);
  497. t->xoffset += v;
  498. r->vconst = v;
  499. regind(t, n);
  500. return;
  501. }
  502. }
  503. lcgen(n, t);
  504. regind(t, n);
  505. }
  506. void
  507. lcgen(Node *n, Node *nn)
  508. {
  509. Prog *p1;
  510. Node nod;
  511. if(debug['g']) {
  512. prtree(nn, "lcgen lhs");
  513. prtree(n, "lcgen");
  514. }
  515. if(n == Z || n->type == T)
  516. return;
  517. if(nn == Z) {
  518. nn = &nod;
  519. regalloc(&nod, n, Z);
  520. }
  521. switch(n->op) {
  522. default:
  523. if(n->addable < INDEXED) {
  524. diag(n, "unknown op in lcgen: %O", n->op);
  525. break;
  526. }
  527. nod = *n;
  528. nod.op = OADDR;
  529. nod.left = n;
  530. nod.right = Z;
  531. nod.type = types[TIND];
  532. gopcode(OAS, &nod, Z, nn);
  533. break;
  534. case OCOMMA:
  535. cgen(n->left, n->left);
  536. lcgen(n->right, nn);
  537. break;
  538. case OIND:
  539. cgen(n->left, nn);
  540. break;
  541. case OCOND:
  542. bcgen(n->left, 1);
  543. p1 = p;
  544. lcgen(n->right->left, nn);
  545. gbranch(OGOTO);
  546. patch(p1, pc);
  547. p1 = p;
  548. lcgen(n->right->right, nn);
  549. patch(p1, pc);
  550. break;
  551. }
  552. }
  553. void
  554. bcgen(Node *n, int true)
  555. {
  556. if(n->type == T)
  557. gbranch(OGOTO);
  558. else
  559. boolgen(n, true, Z);
  560. }
  561. void
  562. boolgen(Node *n, int true, Node *nn)
  563. {
  564. int o;
  565. Prog *p1, *p2;
  566. Node *l, *r, nod, nod1;
  567. long curs;
  568. if(debug['g']) {
  569. prtree(nn, "boolgen lhs");
  570. prtree(n, "boolgen");
  571. }
  572. curs = cursafe;
  573. l = n->left;
  574. r = n->right;
  575. switch(n->op) {
  576. default:
  577. if(n->op == OCONST) {
  578. o = vconst(n);
  579. if(!true)
  580. o = !o;
  581. gbranch(OGOTO);
  582. if(o) {
  583. p1 = p;
  584. gbranch(OGOTO);
  585. patch(p1, pc);
  586. }
  587. goto com;
  588. }
  589. regalloc(&nod, n, nn);
  590. cgen(n, &nod);
  591. o = ONE;
  592. if(true)
  593. o = comrel[relindex(o)];
  594. if(typefd[n->type->etype]) {
  595. nodreg(&nod1, n, NREG+FREGZERO);
  596. gopcode(o, &nod, Z, &nod1);
  597. } else
  598. gopcode(o, &nod, Z, nodconst(0));
  599. regfree(&nod);
  600. goto com;
  601. case OCOMMA:
  602. cgen(l, Z);
  603. boolgen(r, true, nn);
  604. break;
  605. case ONOT:
  606. boolgen(l, !true, nn);
  607. break;
  608. case OCOND:
  609. bcgen(l, 1);
  610. p1 = p;
  611. bcgen(r->left, true);
  612. p2 = p;
  613. gbranch(OGOTO);
  614. patch(p1, pc);
  615. p1 = p;
  616. bcgen(r->right, !true);
  617. patch(p2, pc);
  618. p2 = p;
  619. gbranch(OGOTO);
  620. patch(p1, pc);
  621. patch(p2, pc);
  622. goto com;
  623. case OANDAND:
  624. if(!true)
  625. goto caseor;
  626. caseand:
  627. bcgen(l, true);
  628. p1 = p;
  629. bcgen(r, !true);
  630. p2 = p;
  631. patch(p1, pc);
  632. gbranch(OGOTO);
  633. patch(p2, pc);
  634. goto com;
  635. case OOROR:
  636. if(!true)
  637. goto caseand;
  638. caseor:
  639. bcgen(l, !true);
  640. p1 = p;
  641. bcgen(r, !true);
  642. p2 = p;
  643. gbranch(OGOTO);
  644. patch(p1, pc);
  645. patch(p2, pc);
  646. goto com;
  647. case OEQ:
  648. case ONE:
  649. case OLE:
  650. case OLT:
  651. case OGE:
  652. case OGT:
  653. case OHI:
  654. case OHS:
  655. case OLO:
  656. case OLS:
  657. o = n->op;
  658. if(true)
  659. o = comrel[relindex(o)];
  660. if(l->complex >= FNX && r->complex >= FNX) {
  661. regret(&nod, r);
  662. cgen(r, &nod);
  663. regsalloc(&nod1, r);
  664. gopcode(OAS, &nod, Z, &nod1);
  665. regfree(&nod);
  666. nod = *n;
  667. nod.right = &nod1;
  668. boolgen(&nod, true, nn);
  669. break;
  670. }
  671. if(sconst(r)) {
  672. regalloc(&nod, l, nn);
  673. cgen(l, &nod);
  674. gopcode(o, &nod, Z, r);
  675. regfree(&nod);
  676. goto com;
  677. }
  678. if(l->complex >= r->complex) {
  679. regalloc(&nod1, l, nn);
  680. cgen(l, &nod1);
  681. regalloc(&nod, r, Z);
  682. cgen(r, &nod);
  683. } else {
  684. regalloc(&nod, r, nn);
  685. cgen(r, &nod);
  686. regalloc(&nod1, l, Z);
  687. cgen(l, &nod1);
  688. }
  689. gopcode(o, &nod1, Z, &nod);
  690. regfree(&nod);
  691. regfree(&nod1);
  692. com:
  693. if(nn != Z) {
  694. p1 = p;
  695. gopcode(OAS, nodconst(1L), Z, nn);
  696. gbranch(OGOTO);
  697. p2 = p;
  698. patch(p1, pc);
  699. gopcode(OAS, nodconst(0L), Z, nn);
  700. patch(p2, pc);
  701. }
  702. break;
  703. }
  704. cursafe = curs;
  705. }
  706. void
  707. sugen(Node *n, Node *nn, long w)
  708. {
  709. Prog *p1;
  710. Node nod0, nod1, nod2, nod3, nod4, *l, *r;
  711. Type *t;
  712. long pc1;
  713. int i, m, c;
  714. if(n == Z || n->type == T)
  715. return;
  716. if(debug['g']) {
  717. prtree(nn, "sugen lhs");
  718. prtree(n, "sugen");
  719. }
  720. if(nn == nodrat)
  721. if(w > nrathole)
  722. nrathole = w;
  723. switch(n->op) {
  724. case OIND:
  725. if(nn == Z) {
  726. nullwarn(n->left, Z);
  727. break;
  728. }
  729. default:
  730. goto copy;
  731. case OCONST:
  732. if(n->type && typev[n->type->etype]) {
  733. if(nn == Z) {
  734. nullwarn(n->left, Z);
  735. break;
  736. }
  737. t = nn->type;
  738. nn->type = types[TLONG];
  739. reglcgen(&nod1, nn, Z);
  740. nn->type = t;
  741. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  742. gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
  743. else
  744. gopcode(OAS, nod32const(n->vconst), Z, &nod1);
  745. nod1.xoffset += SZ_LONG;
  746. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  747. gopcode(OAS, nod32const(n->vconst), Z, &nod1);
  748. else
  749. gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
  750. regfree(&nod1);
  751. break;
  752. }
  753. goto copy;
  754. case ODOT:
  755. l = n->left;
  756. sugen(l, nodrat, l->type->width);
  757. if(nn != Z) {
  758. warn(n, "non-interruptable temporary");
  759. nod1 = *nodrat;
  760. r = n->right;
  761. if(!r || r->op != OCONST) {
  762. diag(n, "DOT and no offset");
  763. break;
  764. }
  765. nod1.xoffset += (long)r->vconst;
  766. nod1.type = n->type;
  767. sugen(&nod1, nn, w);
  768. }
  769. break;
  770. case OSTRUCT:
  771. /*
  772. * rewrite so lhs has no side effects
  773. */
  774. if(nn != Z && side(nn)) {
  775. nod1 = *n;
  776. nod1.type = typ(TIND, n->type);
  777. regalloc(&nod2, &nod1, Z);
  778. lcgen(nn, &nod2);
  779. regsalloc(&nod0, &nod1);
  780. gopcode(OAS, &nod2, Z, &nod0);
  781. regfree(&nod2);
  782. nod1 = *n;
  783. nod1.op = OIND;
  784. nod1.left = &nod0;
  785. nod1.right = Z;
  786. nod1.complex = 1;
  787. sugen(n, &nod1, w);
  788. return;
  789. }
  790. r = n->left;
  791. for(t = n->type->link; t != T; t = t->down) {
  792. l = r;
  793. if(r->op == OLIST) {
  794. l = r->left;
  795. r = r->right;
  796. }
  797. if(nn == Z) {
  798. cgen(l, nn);
  799. continue;
  800. }
  801. /*
  802. * hand craft *(&nn + o) = l
  803. */
  804. nod0 = znode;
  805. nod0.op = OAS;
  806. nod0.type = t;
  807. nod0.left = &nod1;
  808. nod0.right = l;
  809. nod1 = znode;
  810. nod1.op = OIND;
  811. nod1.type = t;
  812. nod1.left = &nod2;
  813. nod2 = znode;
  814. nod2.op = OADD;
  815. nod2.type = typ(TIND, t);
  816. nod2.left = &nod3;
  817. nod2.right = &nod4;
  818. nod3 = znode;
  819. nod3.op = OADDR;
  820. nod3.type = nod2.type;
  821. nod3.left = nn;
  822. nod4 = znode;
  823. nod4.op = OCONST;
  824. nod4.type = nod2.type;
  825. nod4.vconst = t->offset;
  826. ccom(&nod0);
  827. acom(&nod0);
  828. xcom(&nod0);
  829. nod0.addable = 0;
  830. /* prtree(&nod0, "hand craft"); /* */
  831. cgen(&nod0, Z);
  832. }
  833. break;
  834. case OAS:
  835. if(nn == Z) {
  836. if(n->addable < INDEXED)
  837. sugen(n->right, n->left, w);
  838. break;
  839. }
  840. /* BOTCH -- functions can clobber rathole */
  841. sugen(n->right, nodrat, w);
  842. warn(n, "non-interruptable temporary");
  843. sugen(nodrat, n->left, w);
  844. sugen(nodrat, nn, w);
  845. break;
  846. case OFUNC:
  847. if(nn == Z) {
  848. sugen(n, nodrat, w);
  849. break;
  850. }
  851. if(nn->op != OIND) {
  852. nn = new1(OADDR, nn, Z);
  853. nn->type = types[TIND];
  854. nn->addable = 0;
  855. } else
  856. nn = nn->left;
  857. n = new(OFUNC, n->left, new(OLIST, nn, n->right));
  858. n->type = types[TVOID];
  859. n->left->type = types[TVOID];
  860. cgen(n, Z);
  861. break;
  862. case OCOND:
  863. bcgen(n->left, 1);
  864. p1 = p;
  865. sugen(n->right->left, nn, w);
  866. gbranch(OGOTO);
  867. patch(p1, pc);
  868. p1 = p;
  869. sugen(n->right->right, nn, w);
  870. patch(p1, pc);
  871. break;
  872. case OCOMMA:
  873. cgen(n->left, Z);
  874. sugen(n->right, nn, w);
  875. break;
  876. }
  877. return;
  878. copy:
  879. if(nn == Z)
  880. return;
  881. if(n->complex >= FNX && nn->complex >= FNX) {
  882. t = nn->type;
  883. nn->type = types[TLONG];
  884. regialloc(&nod1, nn, Z);
  885. lcgen(nn, &nod1);
  886. regsalloc(&nod2, nn);
  887. nn->type = t;
  888. gopcode(OAS, &nod1, Z, &nod2);
  889. regfree(&nod1);
  890. nod2.type = typ(TIND, t);
  891. nod1 = nod2;
  892. nod1.op = OIND;
  893. nod1.left = &nod2;
  894. nod1.right = Z;
  895. nod1.complex = 1;
  896. nod1.type = t;
  897. sugen(n, &nod1, w);
  898. return;
  899. }
  900. if(n->complex > nn->complex) {
  901. t = n->type;
  902. n->type = types[TLONG];
  903. reglcgen(&nod1, n, Z);
  904. n->type = t;
  905. t = nn->type;
  906. nn->type = types[TLONG];
  907. reglcgen(&nod2, nn, Z);
  908. nn->type = t;
  909. } else {
  910. t = nn->type;
  911. nn->type = types[TLONG];
  912. reglcgen(&nod2, nn, Z);
  913. nn->type = t;
  914. t = n->type;
  915. n->type = types[TLONG];
  916. reglcgen(&nod1, n, Z);
  917. n->type = t;
  918. }
  919. w /= SZ_LONG;
  920. if(w <= 5) {
  921. layout(&nod1, &nod2, w, 0, Z);
  922. goto out;
  923. }
  924. /*
  925. * minimize space for unrolling loop
  926. * 3,4,5 times. (6 or more is never minimum)
  927. * if small structure, try 2 also.
  928. */
  929. c = 0; /* set */
  930. m = 100;
  931. i = 3;
  932. if(w <= 15)
  933. i = 2;
  934. for(; i<=5; i++)
  935. if(i + w%i <= m) {
  936. c = i;
  937. m = c + w%c;
  938. }
  939. regalloc(&nod3, &regnode, Z);
  940. layout(&nod1, &nod2, w%c, w/c, &nod3);
  941. pc1 = pc;
  942. layout(&nod1, &nod2, c, 0, Z);
  943. gopcode(OSUB, nodconst(1L), Z, &nod3);
  944. nod1.op = OREGISTER;
  945. gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
  946. nod2.op = OREGISTER;
  947. gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
  948. gopcode(OGT, &nod3, Z, nodconst(0));
  949. patch(p, pc1);
  950. regfree(&nod3);
  951. out:
  952. regfree(&nod1);
  953. regfree(&nod2);
  954. }
  955. void
  956. layout(Node *f, Node *t, int c, int cv, Node *cn)
  957. {
  958. Node t1, t2;
  959. while(c > 3) {
  960. layout(f, t, 2, 0, Z);
  961. c -= 2;
  962. }
  963. regalloc(&t1, &regnode, Z);
  964. regalloc(&t2, &regnode, Z);
  965. if(c > 0) {
  966. gopcode(OAS, f, Z, &t1);
  967. f->xoffset += SZ_LONG;
  968. }
  969. if(cn != Z)
  970. gopcode(OAS, nodconst(cv), Z, cn);
  971. if(c > 1) {
  972. gopcode(OAS, f, Z, &t2);
  973. f->xoffset += SZ_LONG;
  974. }
  975. if(c > 0) {
  976. gopcode(OAS, &t1, Z, t);
  977. t->xoffset += SZ_LONG;
  978. }
  979. if(c > 2) {
  980. gopcode(OAS, f, Z, &t1);
  981. f->xoffset += SZ_LONG;
  982. }
  983. if(c > 1) {
  984. gopcode(OAS, &t2, Z, t);
  985. t->xoffset += SZ_LONG;
  986. }
  987. if(c > 2) {
  988. gopcode(OAS, &t1, Z, t);
  989. t->xoffset += SZ_LONG;
  990. }
  991. regfree(&t1);
  992. regfree(&t2);
  993. }