cgen.c 19 KB

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