cgen.c 18 KB

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