cgen.c 18 KB

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