cgen.c 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  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 && l->complex < FNX) {
  69. if(nn != Z || r->addable < INDEXED) {
  70. if(r->complex >= FNX && nn == Z)
  71. regret(&nod, r);
  72. else
  73. regalloc(&nod, r, nn);
  74. cgen(r, &nod);
  75. gmove(&nod, l);
  76. if(nn != Z)
  77. gmove(&nod, nn);
  78. regfree(&nod);
  79. } else
  80. gmove(r, l);
  81. break;
  82. }
  83. if(l->complex >= r->complex) {
  84. reglcgen(&nod1, l, Z);
  85. if(r->addable >= INDEXED) {
  86. gmove(r, &nod1);
  87. if(nn != Z)
  88. gmove(r, nn);
  89. regfree(&nod1);
  90. break;
  91. }
  92. regalloc(&nod, r, nn);
  93. cgen(r, &nod);
  94. } else {
  95. regalloc(&nod, r, nn);
  96. cgen(r, &nod);
  97. reglcgen(&nod1, l, Z);
  98. }
  99. gmove(&nod, &nod1);
  100. regfree(&nod);
  101. regfree(&nod1);
  102. break;
  103. bitas:
  104. n = l->left;
  105. regalloc(&nod, r, nn);
  106. if(l->complex >= r->complex) {
  107. reglcgen(&nod1, n, Z);
  108. cgen(r, &nod);
  109. } else {
  110. cgen(r, &nod);
  111. reglcgen(&nod1, n, Z);
  112. }
  113. regalloc(&nod2, n, Z);
  114. gopcode(OAS, &nod1, Z, &nod2);
  115. bitstore(l, &nod, &nod1, &nod2, nn);
  116. break;
  117. case OBIT:
  118. if(nn == Z) {
  119. nullwarn(l, Z);
  120. break;
  121. }
  122. bitload(n, &nod, Z, Z, nn);
  123. gopcode(OAS, &nod, Z, nn);
  124. regfree(&nod);
  125. break;
  126. case OADD:
  127. case OSUB:
  128. case OAND:
  129. case OOR:
  130. case OXOR:
  131. case OLSHR:
  132. case OASHL:
  133. case OASHR:
  134. /*
  135. * immediate operands
  136. */
  137. if(nn != Z)
  138. if(r->op == OCONST)
  139. if(!typefd[n->type->etype]) {
  140. cgen(l, nn);
  141. if(r->vconst == 0)
  142. if(o != OAND)
  143. break;
  144. if(nn != Z)
  145. gopcode(o, r, Z, nn);
  146. break;
  147. }
  148. case OLMUL:
  149. case OLDIV:
  150. case OLMOD:
  151. case OMUL:
  152. case ODIV:
  153. case OMOD:
  154. if(nn == Z) {
  155. nullwarn(l, r);
  156. break;
  157. }
  158. if(o == OMUL || o == OLMUL) {
  159. if(mulcon(n, nn))
  160. break;
  161. }
  162. if(l->complex >= r->complex) {
  163. regalloc(&nod, l, nn);
  164. cgen(l, &nod);
  165. regalloc(&nod1, r, Z);
  166. cgen(r, &nod1);
  167. gopcode(o, &nod1, Z, &nod);
  168. } else {
  169. regalloc(&nod, r, nn);
  170. cgen(r, &nod);
  171. regalloc(&nod1, l, Z);
  172. cgen(l, &nod1);
  173. gopcode(o, &nod, &nod1, &nod);
  174. }
  175. gopcode(OAS, &nod, Z, nn);
  176. regfree(&nod);
  177. regfree(&nod1);
  178. break;
  179. case OASLSHR:
  180. case OASASHL:
  181. case OASASHR:
  182. case OASAND:
  183. case OASADD:
  184. case OASSUB:
  185. case OASXOR:
  186. case OASOR:
  187. if(l->op == OBIT)
  188. goto asbitop;
  189. if(r->op == OCONST)
  190. if(!typefd[r->type->etype])
  191. if(!typefd[n->type->etype]) {
  192. if(l->addable < INDEXED)
  193. reglcgen(&nod2, l, Z);
  194. else
  195. nod2 = *l;
  196. regalloc(&nod, r, nn);
  197. gopcode(OAS, &nod2, Z, &nod);
  198. gopcode(o, r, Z, &nod);
  199. gopcode(OAS, &nod, Z, &nod2);
  200. regfree(&nod);
  201. if(l->addable < INDEXED)
  202. regfree(&nod2);
  203. break;
  204. }
  205. case OASLMUL:
  206. case OASLDIV:
  207. case OASLMOD:
  208. case OASMUL:
  209. case OASDIV:
  210. case OASMOD:
  211. if(l->op == OBIT)
  212. goto asbitop;
  213. if(l->complex >= r->complex) {
  214. if(l->addable < INDEXED)
  215. reglcgen(&nod2, l, Z);
  216. else
  217. nod2 = *l;
  218. regalloc(&nod1, r, Z);
  219. cgen(r, &nod1);
  220. } else {
  221. regalloc(&nod1, r, Z);
  222. cgen(r, &nod1);
  223. if(l->addable < INDEXED)
  224. reglcgen(&nod2, l, Z);
  225. else
  226. nod2 = *l;
  227. }
  228. regalloc(&nod, n, nn);
  229. gmove(&nod2, &nod);
  230. gopcode(o, &nod1, Z, &nod);
  231. gmove(&nod, &nod2);
  232. if(nn != Z)
  233. gopcode(OAS, &nod, Z, nn);
  234. regfree(&nod);
  235. regfree(&nod1);
  236. if(l->addable < INDEXED)
  237. regfree(&nod2);
  238. break;
  239. asbitop:
  240. regalloc(&nod4, n, nn);
  241. if(l->complex >= r->complex) {
  242. bitload(l, &nod, &nod1, &nod2, &nod4);
  243. regalloc(&nod3, r, Z);
  244. cgen(r, &nod3);
  245. } else {
  246. regalloc(&nod3, r, Z);
  247. cgen(r, &nod3);
  248. bitload(l, &nod, &nod1, &nod2, &nod4);
  249. }
  250. gmove(&nod, &nod4);
  251. gopcode(o, &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. nullwarn(l, Z);
  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)) {
  361. if(nocast(n->type, nn->type)) {
  362. cgen(l, nn);
  363. break;
  364. }
  365. }
  366. regalloc(&nod, l, nn);
  367. cgen(l, &nod);
  368. regalloc(&nod1, n, &nod);
  369. gopcode(OAS, &nod, Z, &nod1);
  370. gopcode(OAS, &nod1, Z, nn);
  371. regfree(&nod1);
  372. regfree(&nod);
  373. break;
  374. case ODOT:
  375. sugen(l, nodrat, l->type->width);
  376. if(nn != Z) {
  377. warn(n, "non-interruptable temporary");
  378. nod = *nodrat;
  379. if(!r || r->op != OCONST) {
  380. diag(n, "DOT and no offset");
  381. break;
  382. }
  383. nod.xoffset += (long)r->vconst;
  384. nod.type = n->type;
  385. cgen(&nod, nn);
  386. }
  387. break;
  388. case OCOND:
  389. bcgen(l, 1);
  390. p1 = p;
  391. cgen(r->left, nn);
  392. gbranch(OGOTO);
  393. patch(p1, pc);
  394. p1 = p;
  395. cgen(r->right, nn);
  396. patch(p1, pc);
  397. break;
  398. case OPOSTINC:
  399. case OPOSTDEC:
  400. v = 1;
  401. if(l->type->etype == TIND)
  402. v = l->type->link->width;
  403. if(o == OPOSTDEC)
  404. v = -v;
  405. if(l->op == OBIT)
  406. goto bitinc;
  407. if(nn == Z)
  408. goto pre;
  409. if(l->addable < INDEXED)
  410. reglcgen(&nod2, l, Z);
  411. else
  412. nod2 = *l;
  413. regalloc(&nod, l, nn);
  414. gopcode(OAS, &nod2, Z, &nod);
  415. regalloc(&nod1, l, Z);
  416. if(typefd[l->type->etype]) {
  417. regalloc(&nod3, l, Z);
  418. if(v < 0) {
  419. gopcode(OAS, nodfconst(-v), Z, &nod3);
  420. gopcode(OSUB, &nod3, &nod, &nod1);
  421. } else {
  422. gopcode(OAS, nodfconst(v), Z, &nod3);
  423. gopcode(OADD, &nod3, &nod, &nod1);
  424. }
  425. regfree(&nod3);
  426. } else
  427. gopcode(OADD, nodconst(v), &nod, &nod1);
  428. gopcode(OAS, &nod1, Z, &nod2);
  429. regfree(&nod);
  430. regfree(&nod1);
  431. if(l->addable < INDEXED)
  432. regfree(&nod2);
  433. break;
  434. case OPREINC:
  435. case OPREDEC:
  436. v = 1;
  437. if(l->type->etype == TIND)
  438. v = l->type->link->width;
  439. if(o == OPREDEC)
  440. v = -v;
  441. if(l->op == OBIT)
  442. goto bitinc;
  443. pre:
  444. if(l->addable < INDEXED)
  445. reglcgen(&nod2, l, Z);
  446. else
  447. nod2 = *l;
  448. regalloc(&nod, l, nn);
  449. gopcode(OAS, &nod2, Z, &nod);
  450. if(typefd[l->type->etype]) {
  451. regalloc(&nod3, l, Z);
  452. if(v < 0) {
  453. gopcode(OAS, nodfconst(-v), Z, &nod3);
  454. gopcode(OSUB, &nod3, Z, &nod);
  455. } else {
  456. gopcode(OAS, nodfconst(v), Z, &nod3);
  457. gopcode(OADD, &nod3, Z, &nod);
  458. }
  459. regfree(&nod3);
  460. } else
  461. gopcode(OADD, nodconst(v), Z, &nod);
  462. gopcode(OAS, &nod, Z, &nod2);
  463. if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
  464. gins(ANOP, l, Z);
  465. regfree(&nod);
  466. if(l->addable < INDEXED)
  467. regfree(&nod2);
  468. break;
  469. bitinc:
  470. if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
  471. bitload(l, &nod, &nod1, &nod2, Z);
  472. gopcode(OAS, &nod, Z, nn);
  473. gopcode(OADD, nodconst(v), Z, &nod);
  474. bitstore(l, &nod, &nod1, &nod2, Z);
  475. break;
  476. }
  477. bitload(l, &nod, &nod1, &nod2, nn);
  478. gopcode(OADD, nodconst(v), Z, &nod);
  479. bitstore(l, &nod, &nod1, &nod2, nn);
  480. break;
  481. }
  482. cursafe = curs;
  483. }
  484. void
  485. reglcgen(Node *t, Node *n, Node *nn)
  486. {
  487. Node *r;
  488. long v;
  489. regialloc(t, n, nn);
  490. if(n->op == OIND) {
  491. r = n->left;
  492. while(r->op == OADD)
  493. r = r->right;
  494. if(sconst(r)) {
  495. v = r->vconst;
  496. r->vconst = 0;
  497. lcgen(n, t);
  498. t->xoffset += v;
  499. r->vconst = v;
  500. regind(t, n);
  501. return;
  502. }
  503. }
  504. lcgen(n, t);
  505. regind(t, n);
  506. }
  507. void
  508. lcgen(Node *n, Node *nn)
  509. {
  510. Prog *p1;
  511. Node nod;
  512. if(debug['g']) {
  513. prtree(nn, "lcgen lhs");
  514. prtree(n, "lcgen");
  515. }
  516. if(n == Z || n->type == T)
  517. return;
  518. if(nn == Z) {
  519. nn = &nod;
  520. regalloc(&nod, n, Z);
  521. }
  522. switch(n->op) {
  523. default:
  524. if(n->addable < INDEXED) {
  525. diag(n, "unknown op in lcgen: %O", n->op);
  526. break;
  527. }
  528. nod = *n;
  529. nod.op = OADDR;
  530. nod.left = n;
  531. nod.right = Z;
  532. nod.type = types[TIND];
  533. gopcode(OAS, &nod, Z, nn);
  534. break;
  535. case OCOMMA:
  536. cgen(n->left, n->left);
  537. lcgen(n->right, nn);
  538. break;
  539. case OIND:
  540. cgen(n->left, nn);
  541. break;
  542. case OCOND:
  543. bcgen(n->left, 1);
  544. p1 = p;
  545. lcgen(n->right->left, nn);
  546. gbranch(OGOTO);
  547. patch(p1, pc);
  548. p1 = p;
  549. lcgen(n->right->right, nn);
  550. patch(p1, pc);
  551. break;
  552. }
  553. }
  554. void
  555. bcgen(Node *n, int true)
  556. {
  557. if(n->type == T)
  558. gbranch(OGOTO);
  559. else
  560. boolgen(n, true, Z);
  561. }
  562. void
  563. boolgen(Node *n, int true, Node *nn)
  564. {
  565. int o;
  566. Prog *p1, *p2;
  567. Node *l, *r, nod, nod1;
  568. long curs;
  569. if(debug['g']) {
  570. prtree(nn, "boolgen lhs");
  571. prtree(n, "boolgen");
  572. }
  573. curs = cursafe;
  574. l = n->left;
  575. r = n->right;
  576. switch(n->op) {
  577. default:
  578. regalloc(&nod, n, nn);
  579. cgen(n, &nod);
  580. if(nn == Z || typefd[n->type->etype]) {
  581. o = ONE;
  582. if(true)
  583. o = comrel[relindex(o)];
  584. if(typefd[n->type->etype]) {
  585. nodreg(&nod1, n, NREG+FREGZERO);
  586. gopcode(o, &nod, &nod1, Z);
  587. } else
  588. gopcode(o, &nod, Z, Z);
  589. regfree(&nod);
  590. goto com;
  591. }
  592. if(true)
  593. gopcode(OCOND, &nod, nodconst(0), &nod);
  594. else
  595. gopcode(OCOND, nodconst(1), &nod, &nod);
  596. gopcode(OAS, &nod, Z, nn);
  597. regfree(&nod);
  598. break;
  599. case OCONST:
  600. o = vconst(n);
  601. if(!true)
  602. o = !o;
  603. gbranch(OGOTO);
  604. if(o) {
  605. p1 = p;
  606. gbranch(OGOTO);
  607. patch(p1, pc);
  608. }
  609. goto com;
  610. case OCOMMA:
  611. cgen(l, Z);
  612. boolgen(r, true, nn);
  613. break;
  614. case ONOT:
  615. boolgen(l, !true, nn);
  616. break;
  617. case OCOND:
  618. bcgen(l, 1);
  619. p1 = p;
  620. bcgen(r->left, true);
  621. p2 = p;
  622. gbranch(OGOTO);
  623. patch(p1, pc);
  624. p1 = p;
  625. bcgen(r->right, !true);
  626. patch(p2, pc);
  627. p2 = p;
  628. gbranch(OGOTO);
  629. patch(p1, pc);
  630. patch(p2, pc);
  631. goto com;
  632. case OANDAND:
  633. if(!true)
  634. goto caseor;
  635. caseand:
  636. bcgen(l, true);
  637. p1 = p;
  638. bcgen(r, !true);
  639. p2 = p;
  640. patch(p1, pc);
  641. gbranch(OGOTO);
  642. patch(p2, pc);
  643. goto com;
  644. case OOROR:
  645. if(!true)
  646. goto caseand;
  647. caseor:
  648. bcgen(l, !true);
  649. p1 = p;
  650. bcgen(r, !true);
  651. p2 = p;
  652. gbranch(OGOTO);
  653. patch(p1, pc);
  654. patch(p2, pc);
  655. goto com;
  656. case OEQ:
  657. case ONE:
  658. case OLE:
  659. case OLT:
  660. case OGE:
  661. case OGT:
  662. case OHI:
  663. case OHS:
  664. case OLO:
  665. case OLS:
  666. o = n->op;
  667. if(true)
  668. o = comrel[relindex(o)];
  669. if(l->complex >= FNX && r->complex >= FNX) {
  670. regret(&nod, r);
  671. cgen(r, &nod);
  672. regsalloc(&nod1, r);
  673. gopcode(OAS, &nod, Z, &nod1);
  674. regfree(&nod);
  675. nod = *n;
  676. nod.right = &nod1;
  677. boolgen(&nod, true, nn);
  678. break;
  679. }
  680. if(nn != Z && !typefd[l->type->etype]) {
  681. if(l->complex >= r->complex) {
  682. regalloc(&nod1, l, nn);
  683. cgen(l, &nod1);
  684. regalloc(&nod, r, Z);
  685. cgen(r, &nod);
  686. } else {
  687. regalloc(&nod, r, nn);
  688. cgen(r, &nod);
  689. regalloc(&nod1, l, Z);
  690. cgen(l, &nod1);
  691. }
  692. switch(o) {
  693. case OEQ:
  694. gopcode(OSUB, &nod1, &nod, &nod);
  695. gopcode(OCOND, &nod, nodconst(0), &nod);
  696. break;
  697. case ONE:
  698. gopcode(OSUB, &nod1, &nod, &nod);
  699. gopcode(OCOND, nodconst(1), &nod, &nod);
  700. break;
  701. case OLE:
  702. gopcode(OCOMMA, &nod1, &nod, &nod);
  703. break;
  704. case OGT:
  705. gopcode(OCOMMA, &nod1, &nod, &nod);
  706. gopcode(OXOR, nodconst(1), &nod, &nod);
  707. break;
  708. case OLT:
  709. gopcode(OCOMMA, &nod, &nod1, &nod);
  710. gopcode(OXOR, nodconst(1), &nod, &nod);
  711. break;
  712. case OGE:
  713. gopcode(OCOMMA, &nod, &nod1, &nod);
  714. break;
  715. case OLS:
  716. gopcode(OCOND, &nod1, &nod, &nod);
  717. break;
  718. case OHI:
  719. gopcode(OCOND, &nod1, &nod, &nod);
  720. gopcode(OXOR, nodconst(1), &nod, &nod);
  721. break;
  722. case OLO:
  723. gopcode(OCOND, &nod, &nod1, &nod);
  724. gopcode(OXOR, nodconst(1), &nod, &nod);
  725. break;
  726. case OHS:
  727. gopcode(OCOND, &nod, &nod1, &nod);
  728. break;
  729. }
  730. gopcode(OAS, &nod, Z, nn);
  731. regfree(&nod);
  732. regfree(&nod1);
  733. break;
  734. }
  735. if(sconst(l)) {
  736. switch(o) {
  737. default:
  738. if(l->vconst != 0)
  739. break;
  740. case OGT:
  741. case OHI:
  742. case OLE:
  743. case OLS:
  744. regalloc(&nod, r, nn);
  745. cgen(r, &nod);
  746. gopcode(o, l, &nod, Z);
  747. regfree(&nod);
  748. goto com;
  749. }
  750. }
  751. if(sconst(r)) {
  752. switch(o) {
  753. default:
  754. if(r->vconst != 0)
  755. break;
  756. case OGE:
  757. case OHS:
  758. case OLT:
  759. case OLO:
  760. regalloc(&nod, l, nn);
  761. cgen(l, &nod);
  762. gopcode(o, &nod, r, Z);
  763. regfree(&nod);
  764. goto com;
  765. }
  766. }
  767. if(l->complex >= r->complex) {
  768. regalloc(&nod1, l, nn);
  769. cgen(l, &nod1);
  770. regalloc(&nod, r, Z);
  771. cgen(r, &nod);
  772. } else {
  773. regalloc(&nod, r, nn);
  774. cgen(r, &nod);
  775. regalloc(&nod1, l, Z);
  776. cgen(l, &nod1);
  777. }
  778. gopcode(o, &nod1, &nod, Z);
  779. regfree(&nod);
  780. regfree(&nod1);
  781. com:
  782. if(nn != Z) {
  783. p1 = p;
  784. gopcode(OAS, nodconst(1), Z, nn);
  785. gbranch(OGOTO);
  786. p2 = p;
  787. patch(p1, pc);
  788. gopcode(OAS, nodconst(0), Z, nn);
  789. patch(p2, pc);
  790. }
  791. break;
  792. }
  793. cursafe = curs;
  794. }
  795. void
  796. sugen(Node *n, Node *nn, long w)
  797. {
  798. Prog *p1;
  799. Node nod0, nod1, nod2, nod3, nod4, *l, *r;
  800. Type *t;
  801. long pc1;
  802. int i, m, c;
  803. if(n == Z || n->type == T)
  804. return;
  805. if(debug['g']) {
  806. prtree(nn, "sugen lhs");
  807. prtree(n, "sugen");
  808. }
  809. if(nn == nodrat)
  810. if(w > nrathole)
  811. nrathole = w;
  812. switch(n->op) {
  813. case OIND:
  814. if(nn == Z) {
  815. nullwarn(n->left, Z);
  816. break;
  817. }
  818. default:
  819. goto copy;
  820. case OCONST:
  821. if(n->type && typev[n->type->etype]) {
  822. if(nn == Z) {
  823. nullwarn(n->left, Z);
  824. break;
  825. }
  826. t = nn->type;
  827. nn->type = types[TLONG];
  828. reglcgen(&nod1, nn, Z);
  829. nn->type = t;
  830. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  831. gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
  832. else
  833. gopcode(OAS, nod32const(n->vconst), Z, &nod1);
  834. nod1.xoffset += SZ_LONG;
  835. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  836. gopcode(OAS, nod32const(n->vconst), Z, &nod1);
  837. else
  838. gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
  839. regfree(&nod1);
  840. break;
  841. }
  842. goto copy;
  843. case ODOT:
  844. l = n->left;
  845. sugen(l, nodrat, l->type->width);
  846. if(nn != Z) {
  847. warn(n, "non-interruptable temporary");
  848. nod1 = *nodrat;
  849. r = n->right;
  850. if(!r || r->op != OCONST) {
  851. diag(n, "DOT and no offset");
  852. break;
  853. }
  854. nod1.xoffset += (long)r->vconst;
  855. nod1.type = n->type;
  856. sugen(&nod1, nn, w);
  857. }
  858. break;
  859. case OSTRUCT:
  860. /*
  861. * rewrite so lhs has no fn call
  862. */
  863. if(nn != Z && nn->complex >= FNX) {
  864. nod1 = *n;
  865. nod1.type = typ(TIND, n->type);
  866. regret(&nod2, &nod1);
  867. lcgen(nn, &nod2);
  868. regsalloc(&nod0, &nod1);
  869. gopcode(OAS, &nod2, Z, &nod0);
  870. regfree(&nod2);
  871. nod1 = *n;
  872. nod1.op = OIND;
  873. nod1.left = &nod0;
  874. nod1.right = Z;
  875. nod1.complex = 1;
  876. sugen(n, &nod1, w);
  877. return;
  878. }
  879. r = n->left;
  880. for(t = n->type->link; t != T; t = t->down) {
  881. l = r;
  882. if(r->op == OLIST) {
  883. l = r->left;
  884. r = r->right;
  885. }
  886. if(nn == Z) {
  887. cgen(l, nn);
  888. continue;
  889. }
  890. /*
  891. * hand craft *(&nn + o) = l
  892. */
  893. nod0 = znode;
  894. nod0.op = OAS;
  895. nod0.type = t;
  896. nod0.left = &nod1;
  897. nod0.right = l;
  898. nod1 = znode;
  899. nod1.op = OIND;
  900. nod1.type = t;
  901. nod1.left = &nod2;
  902. nod2 = znode;
  903. nod2.op = OADD;
  904. nod2.type = typ(TIND, t);
  905. nod2.left = &nod3;
  906. nod2.right = &nod4;
  907. nod3 = znode;
  908. nod3.op = OADDR;
  909. nod3.type = nod2.type;
  910. nod3.left = nn;
  911. nod4 = znode;
  912. nod4.op = OCONST;
  913. nod4.type = nod2.type;
  914. nod4.vconst = t->offset;
  915. ccom(&nod0);
  916. acom(&nod0);
  917. xcom(&nod0);
  918. nod0.addable = 0;
  919. cgen(&nod0, Z);
  920. }
  921. break;
  922. case OAS:
  923. if(nn == Z) {
  924. if(n->addable < INDEXED)
  925. sugen(n->right, n->left, w);
  926. break;
  927. }
  928. sugen(n->right, nodrat, w);
  929. warn(n, "non-interruptable temporary");
  930. sugen(nodrat, n->left, w);
  931. sugen(nodrat, nn, w);
  932. break;
  933. case OFUNC:
  934. if(nn == Z) {
  935. sugen(n, nodrat, w);
  936. break;
  937. }
  938. if(nn->op != OIND) {
  939. nn = new1(OADDR, nn, Z);
  940. nn->type = types[TIND];
  941. nn->addable = 0;
  942. } else
  943. nn = nn->left;
  944. n = new(OFUNC, n->left, new(OLIST, nn, n->right));
  945. n->type = types[TVOID];
  946. n->left->type = types[TVOID];
  947. cgen(n, Z);
  948. break;
  949. case OCOND:
  950. bcgen(n->left, 1);
  951. p1 = p;
  952. sugen(n->right->left, nn, w);
  953. gbranch(OGOTO);
  954. patch(p1, pc);
  955. p1 = p;
  956. sugen(n->right->right, nn, w);
  957. patch(p1, pc);
  958. break;
  959. case OCOMMA:
  960. cgen(n->left, Z);
  961. sugen(n->right, nn, w);
  962. break;
  963. }
  964. return;
  965. copy:
  966. if(nn == Z)
  967. return;
  968. if(n->complex >= FNX && nn->complex >= FNX) {
  969. t = nn->type;
  970. nn->type = types[TLONG];
  971. regialloc(&nod1, nn, Z);
  972. lcgen(nn, &nod1);
  973. regsalloc(&nod2, nn);
  974. nn->type = t;
  975. gopcode(OAS, &nod1, Z, &nod2);
  976. regfree(&nod1);
  977. nod2.type = typ(TIND, t);
  978. nod1 = nod2;
  979. nod1.op = OIND;
  980. nod1.left = &nod2;
  981. nod1.right = Z;
  982. nod1.complex = 1;
  983. nod1.type = t;
  984. sugen(n, &nod1, w);
  985. return;
  986. }
  987. if(n->complex > nn->complex) {
  988. t = n->type;
  989. n->type = types[TLONG];
  990. reglcgen(&nod1, n, Z);
  991. n->type = t;
  992. t = nn->type;
  993. nn->type = types[TLONG];
  994. reglcgen(&nod2, nn, Z);
  995. nn->type = t;
  996. } else {
  997. t = nn->type;
  998. nn->type = types[TLONG];
  999. reglcgen(&nod2, nn, Z);
  1000. nn->type = t;
  1001. t = n->type;
  1002. n->type = types[TLONG];
  1003. reglcgen(&nod1, n, Z);
  1004. n->type = t;
  1005. }
  1006. w /= SZ_LONG;
  1007. if(w <= 5) {
  1008. layout(&nod1, &nod2, w, 0, Z);
  1009. goto out;
  1010. }
  1011. /*
  1012. * minimize space for unrolling loop
  1013. * 3,4,5 times. (6 or more is never minimum)
  1014. * if small structure, try 2 also.
  1015. */
  1016. c = 0; /* set */
  1017. m = 100;
  1018. i = 3;
  1019. if(w <= 15)
  1020. i = 2;
  1021. for(; i<=5; i++)
  1022. if(i + w%i <= m) {
  1023. c = i;
  1024. m = c + w%c;
  1025. }
  1026. regalloc(&nod3, &regnode, Z);
  1027. layout(&nod1, &nod2, w%c, w/c, &nod3);
  1028. pc1 = pc;
  1029. layout(&nod1, &nod2, c, 0, Z);
  1030. gopcode(OSUB, nodconst(1), Z, &nod3);
  1031. nod1.op = OREGISTER;
  1032. gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
  1033. nod2.op = OREGISTER;
  1034. gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
  1035. gopcode(OEQ, &nod3, Z, Z);
  1036. p->as = ABGTZ;
  1037. patch(p, pc1);
  1038. regfree(&nod3);
  1039. out:
  1040. regfree(&nod1);
  1041. regfree(&nod2);
  1042. }
  1043. void
  1044. layout(Node *f, Node *t, int c, int cv, Node *cn)
  1045. {
  1046. Node t1, t2;
  1047. while(c > 3) {
  1048. layout(f, t, 2, 0, Z);
  1049. c -= 2;
  1050. }
  1051. regalloc(&t1, &regnode, Z);
  1052. regalloc(&t2, &regnode, Z);
  1053. t1.type = types[TLONG];
  1054. t2.type = types[TLONG];
  1055. if(c > 0) {
  1056. gopcode(OAS, f, Z, &t1);
  1057. f->xoffset += SZ_LONG;
  1058. }
  1059. if(cn != Z)
  1060. gopcode(OAS, nodconst(cv), Z, cn);
  1061. if(c > 1) {
  1062. gopcode(OAS, f, Z, &t2);
  1063. f->xoffset += SZ_LONG;
  1064. }
  1065. if(c > 0) {
  1066. gopcode(OAS, &t1, Z, t);
  1067. t->xoffset += SZ_LONG;
  1068. }
  1069. if(c > 2) {
  1070. gopcode(OAS, f, Z, &t1);
  1071. f->xoffset += SZ_LONG;
  1072. }
  1073. if(c > 1) {
  1074. gopcode(OAS, &t2, Z, t);
  1075. t->xoffset += SZ_LONG;
  1076. }
  1077. if(c > 2) {
  1078. gopcode(OAS, &t1, Z, t);
  1079. t->xoffset += SZ_LONG;
  1080. }
  1081. regfree(&t1);
  1082. regfree(&t2);
  1083. }