3 /* ,x/^(print|prtree)\(/i/\/\/ */
6 cgen(Node *n, Node *nn)
10 Node nod, nod1, nod2, nod3, nod4;
16 prtree(nn, "cgen lhs");
19 if(n == Z || n->type == T)
21 if(typesuv[n->type->etype]) {
22 sugen(n, nn, n->type->width);
28 // Go's version does the following, but it's the wrong place: doesn't allow assignment
29 // if(o == OEXREG || nn != Z && nn->op == OEXREG) {
34 if(n->addable >= INDEXED) {
52 if(r != Z && r->complex >= FNX)
55 if(cond(o) && typesuv[l->type->etype])
80 hardleft = l->addable < INDEXED || l->complex >= FNX;
83 diag(n, "unknown op in cgen: %O", o);
92 regalloc(&nod, l, nn);
94 gopcode(o, n->type, Z, &nod);
100 if(typefd[n->type->etype]) {
103 gins(AFMOVD, &fregnode0, &fregnode0);
104 if(l->addable < INDEXED) {
105 reglcgen(&nod, l, Z);
106 gmove(&fregnode0, &nod);
109 gmove(&fregnode0, l);
111 gmove(&fregnode0, nn);
117 if(nn != Z || r->addable < INDEXED) {
118 if(r->complex >= FNX && nn == Z)
121 regalloc(&nod, r, nn);
131 if(l->complex >= r->complex) {
132 if(l->op == OINDEX && r->op == OCONST) {
136 reglcgen(&nod1, l, Z);
137 if(r->addable >= INDEXED) {
144 regalloc(&nod, r, nn);
147 regalloc(&nod, r, nn);
149 reglcgen(&nod1, l, Z);
158 regalloc(&nod, r, nn);
159 if(l->complex >= r->complex) {
160 reglcgen(&nod1, n, Z);
164 reglcgen(&nod1, n, Z);
166 regalloc(&nod2, n, Z);
168 bitstore(l, &nod, &nod1, &nod2, nn);
176 bitload(n, &nod, Z, Z, nn);
189 if(r->op == OCONST) {
194 regalloc(&nod, l, nn);
196 if(o == OASHL && r->vconst == 1)
197 gopcode(OADD, n->type, &nod, &nod);
199 gopcode(o, n->type, r, &nod);
208 if(nodreg(&nod, nn, D_CX)) {
211 cgen(n, &nod); /* probably a bug */
217 if(nn->op == OREGISTER && nn->reg == D_CX)
218 regalloc(&nod1, l, Z);
220 regalloc(&nod1, l, nn);
221 if(r->complex >= l->complex) {
228 gopcode(o, n->type, &nod, &nod1);
243 if(typefd[n->type->etype])
245 if(r->op == OCONST) {
246 if(r->vconst == 0 && o != OAND) {
251 if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
252 && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
253 c = l->right->vconst;
254 if(c > 0 && c <= 3 && nareg(1) >= 4) {
255 if(l->left->complex >= r->complex) {
256 regalloc(&nod, l->left, nn);
258 if(r->addable < INDEXED) {
259 regalloc(&nod1, r, Z);
261 genmuladd(&nod, &nod, 1 << c, &nod1);
265 genmuladd(&nod, &nod, 1 << c, r);
268 regalloc(&nod, r, nn);
270 regalloc(&nod1, l->left, Z);
271 cgen(l->left, &nod1);
272 genmuladd(&nod, &nod1, 1 << c, &nod);
280 if(r->addable >= INDEXED) {
281 regalloc(&nod, l, nn);
283 gopcode(o, n->type, r, &nod);
288 if(l->complex >= r->complex) {
289 regalloc(&nod, l, nn);
291 regalloc(&nod1, r, Z);
293 gopcode(o, n->type, &nod1, &nod);
295 regalloc(&nod1, r, nn);
297 regalloc(&nod, l, Z);
299 gopcode(o, n->type, &nod1, &nod);
316 if(typefd[n->type->etype])
318 if(r->op == OCONST) {
332 regalloc(&nod, l, nn);
337 mulgen(n->type, r, &nod);
340 sdiv2(r->vconst, v, l, &nod);
343 smod2(r->vconst, v, l, &nod);
351 if((c & 0x80000000) == 0)
353 regalloc(&nod1, l, Z);
355 regalloc(&nod, l, nn);
357 gins(ACMPL, &nod1, nodconst(c));
358 gins(ASBBL, nodconst(-1), &nod);
367 if(l->addable >= INDEXED) {
373 else if(r->addable >= INDEXED) {
375 /* should favour AX */
376 regalloc(&nod, l, nn);
378 gopcode(OMUL, n->type, r, &nod);
381 /* should favour AX */
382 regalloc(&nod, l, nn);
384 regalloc(&nod1, r, Z);
386 gopcode(OMUL, n->type, &nod1, &nod);
396 * get nod1 to be D_DX
398 if(nodreg(&nod, nn, D_AX)) {
420 if(nodreg(&nod1, nn, D_DX)) {
444 if(r->op == OCONST) {
448 if(l->addable < INDEXED) {
449 regalloc(&nod2, l, Z);
453 sdivgen(l, r, &nod, &nod1);
460 if(l->addable < INDEXED) {
461 regalloc(&nod2, l, Z);
465 udivgen(l, r, &nod, &nod1);
473 if(l->complex >= r->complex) {
476 if(o == ODIV || o == OMOD)
478 if(o == OLDIV || o == OLMOD)
480 if(r->addable < INDEXED || r->op == OCONST) {
483 gopcode(o, n->type, &nod3, Z);
485 gopcode(o, n->type, r, Z);
491 if(o == ODIV || o == OMOD)
493 if(o == OLDIV || o == OLMOD)
495 gopcode(o, n->type, &nod3, Z);
497 if(o == OMOD || o == OLMOD)
513 if(typefd[n->type->etype])
519 if(nodreg(&nod, nn, D_CX)) {
530 if(r->complex >= l->complex) {
533 reglcgen(&nod1, l, Z);
538 reglcgen(&nod1, l, Z);
544 gopcode(o, l->type, &nod, &nod1);
560 if(typefd[n->type->etype]||typefd[r->type->etype])
562 if(l->complex >= r->complex) {
564 reglcgen(&nod, l, Z);
567 if(r->op != OCONST) {
568 regalloc(&nod1, r, nn);
570 gopcode(o, l->type, &nod1, &nod);
573 gopcode(o, l->type, r, &nod);
575 regalloc(&nod1, r, nn);
578 reglcgen(&nod, l, Z);
581 gopcode(o, l->type, &nod1, &nod);
598 if(typefd[n->type->etype]||typefd[r->type->etype])
600 if(r->op == OCONST) {
615 reglcgen(&nod2, l, Z);
618 regalloc(&nod, l, nn);
623 mulgen(n->type, r, &nod);
626 sdiv2(r->vconst, v, l, &nod);
629 smod2(r->vconst, v, l, &nod);
642 if((c & 0x80000000) == 0)
645 reglcgen(&nod2, l, Z);
648 regalloc(&nod1, l, nn);
650 regalloc(&nod, l, nn);
652 gins(ACMPL, &nod1, nodconst(c));
653 gins(ASBBL, nodconst(-1), &nod);
660 /* should favour AX */
661 regalloc(&nod, l, nn);
662 if(r->complex >= FNX) {
663 regalloc(&nod1, r, Z);
668 reglcgen(&nod2, l, Z);
672 if(r->addable < INDEXED) {
673 if(r->complex < FNX) {
674 regalloc(&nod1, r, Z);
677 gopcode(OASMUL, n->type, &nod1, &nod);
681 gopcode(OASMUL, n->type, r, &nod);
695 * get nod1 to be D_DX
697 if(nodreg(&nod, nn, D_AX)) {
719 if(nodreg(&nod1, nn, D_DX)) {
744 if(l->complex >= r->complex) {
746 reglcgen(&nod2, l, Z);
750 if(r->op == OCONST) {
753 sdivgen(&nod2, r, &nod, &nod1);
756 udivgen(&nod2, r, &nod, &nod1);
764 if(o == OASDIV || o == OASMOD)
766 if(o == OASLDIV || o == OASLMOD)
768 if(r->addable < INDEXED || r->op == OCONST ||
769 !typeil[r->type->etype]) {
770 regalloc(&nod3, r, Z);
772 gopcode(o, l->type, &nod3, Z);
775 gopcode(o, n->type, r, Z);
777 regalloc(&nod3, r, Z);
780 reglcgen(&nod2, l, Z);
784 if(o == OASDIV || o == OASMOD)
786 if(o == OASLDIV || o == OASLMOD)
788 gopcode(o, l->type, &nod3, Z);
791 if(o == OASMOD || o == OASLMOD) {
808 if(l->complex >= r->complex) {
810 if(r->addable < INDEXED) {
812 fgopcode(o, &fregnode0, &fregnode1, 1, 0);
814 fgopcode(o, r, &fregnode0, 0, 0);
817 if(l->addable < INDEXED) {
819 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
821 fgopcode(o, l, &fregnode0, 0, 1);
823 gmove(&fregnode0, nn);
827 if(l->complex >= r->complex) {
829 reglcgen(&nod, l, Z);
836 reglcgen(&nod, l, Z);
840 if(!typefd[l->type->etype]) {
841 gmove(&nod, &fregnode0);
842 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
844 fgopcode(o, &nod, &fregnode0, 0, 1);
846 gins(AFMOVD, &fregnode0, &fregnode0);
847 gmove(&fregnode0, &nod);
849 gmove(&fregnode0, nn);
855 regalloc(&nod4, n, nn);
856 if(l->complex >= r->complex) {
857 bitload(l, &nod, &nod1, &nod2, &nod4);
858 regalloc(&nod3, r, Z);
861 regalloc(&nod3, r, Z);
863 bitload(l, &nod, &nod1, &nod2, &nod4);
867 if(typefd[nod3.type->etype])
868 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
872 /* incredible grot ... */
885 bitstore(l, &nod, &nod1, &nod2, nn);
898 if(l->complex >= FNX) {
900 diag(n, "bad function call");
902 regret(&nod, l->left);
904 regsalloc(&nod1, l->left);
917 gargs(r, &nod, &nod1);
918 if(l->addable < INDEXED) {
919 reglcgen(&nod, l, nn);
921 gopcode(OFUNC, n->type, Z, &nod);
924 gopcode(OFUNC, n->type, Z, l);
925 if(REGARG>=0 && reg[REGARG])
932 if(typefd[n->type->etype])
933 gins(AFMOVDP, &fregnode0, &fregnode0);
941 regialloc(&nod, n, nn);
997 if(n->type != types[TVOID])
1004 * convert from types l->n->nn
1006 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
1007 /* both null, gen l->nn */
1011 if(typev[l->type->etype]) {
1015 regalloc(&nod, l, nn);
1017 regalloc(&nod1, n, &nod);
1025 sugen(l, nodrat, l->type->width);
1028 warn(n, "non-interruptable temporary");
1030 if(!r || r->op != OCONST) {
1031 diag(n, "DOT and no offset");
1034 nod.xoffset += (long)r->vconst;
1053 if(l->type->etype == TIND)
1054 v = l->type->link->width;
1063 reglcgen(&nod, l, Z);
1067 if(typefd[n->type->etype])
1070 gopcode(OADD, n->type, nodconst(v), &nod);
1078 if(l->type->etype == TIND)
1079 v = l->type->link->width;
1087 reglcgen(&nod, l, Z);
1090 if(typefd[n->type->etype])
1092 gopcode(OADD, n->type, nodconst(v), &nod);
1100 gmove(&nod, &fregnode0);
1101 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC))
1102 gins(AFMOVD, &fregnode0, &fregnode0);
1105 fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0);
1107 fgopcode(OADD, &fregnode0, &fregnode1, 1, 0);
1108 if(nn != Z && (o == OPREINC || o == OPREDEC))
1109 gins(AFMOVD, &fregnode0, &fregnode0);
1110 gmove(&fregnode0, &nod);
1116 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
1117 bitload(l, &nod, &nod1, &nod2, Z);
1119 gopcode(OADD, tfield, nodconst(v), &nod);
1120 bitstore(l, &nod, &nod1, &nod2, Z);
1123 bitload(l, &nod, &nod1, &nod2, nn);
1124 gopcode(OADD, tfield, nodconst(v), &nod);
1125 bitstore(l, &nod, &nod1, &nod2, nn);
1133 reglcgen(Node *t, Node *n, Node *nn)
1138 regialloc(t, n, nn);
1141 while(r->op == OADD)
1158 lcgen(Node *n, Node *nn)
1164 prtree(nn, "lcgen lhs");
1167 if(n == Z || n->type == T)
1171 regalloc(&nod, n, Z);
1175 if(n->addable < INDEXED) {
1176 diag(n, "unknown op in lcgen: %O", n->op);
1179 gopcode(OADDR, n->type, n, nn);
1183 cgen(n->left, n->left);
1184 lcgen(n->right, nn);
1194 lcgen(n->right->left, nn);
1198 lcgen(n->right->right, nn);
1205 bcgen(Node *n, int true)
1211 boolgen(n, true, Z);
1215 boolgen(Node *n, int true, Node *nn)
1219 Node *l, *r, nod, nod1;
1223 prtree(nn, "boolgen lhs");
1224 prtree(n, "boolgen");
1232 if(typev[n->type->etype]) {
1239 if(typefd[n->type->etype]) {
1240 if(n->addable < INDEXED) {
1241 cgen(n, &fregnode0);
1243 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1246 fgopcode(o, n, &fregnode0, 0, 1);
1250 /* bad, 13 is address of external that becomes constant */
1251 if(n->addable >= INDEXED && n->addable != 13) {
1252 gopcode(o, n->type, n, nodconst(0));
1255 regalloc(&nod, n, nn);
1257 gopcode(o, n->type, &nod, nodconst(0));
1275 boolgen(r, true, nn);
1279 boolgen(l, !true, nn);
1285 bcgen(r->left, true);
1290 bcgen(r->right, !true);
1337 if(typev[l->type->etype]) {
1339 n->op = comrel[relindex(o)];
1344 o = comrel[relindex(o)];
1345 if(l->complex >= FNX && r->complex >= FNX) {
1348 regsalloc(&nod1, r);
1353 boolgen(&nod, true, nn);
1356 if(typefd[l->type->etype]) {
1357 if(l->complex >= r->complex) {
1358 cgen(l, &fregnode0);
1359 if(r->addable < INDEXED) {
1360 cgen(r, &fregnode0);
1361 o = invrel[relindex(o)];
1362 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1364 fgopcode(o, r, &fregnode0, 0, 1);
1366 o = invrel[relindex(o)];
1367 cgen(r, &fregnode0);
1368 if(l->addable < INDEXED) {
1369 cgen(l, &fregnode0);
1370 o = invrel[relindex(o)];
1371 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1373 fgopcode(o, l, &fregnode0, 0, 1);
1377 if(l->op == OCONST) {
1378 o = invrel[relindex(o)];
1379 /* bad, 13 is address of external that becomes constant */
1380 if(r->addable < INDEXED || r->addable == 13) {
1381 regalloc(&nod, r, nn);
1383 gopcode(o, l->type, &nod, l);
1386 gopcode(o, l->type, r, l);
1389 if(l->complex >= r->complex) {
1390 regalloc(&nod, l, nn);
1392 if(r->addable < INDEXED) {
1393 regalloc(&nod1, r, Z);
1395 gopcode(o, l->type, &nod, &nod1);
1398 gopcode(o, l->type, &nod, r);
1402 regalloc(&nod, r, nn);
1404 if(l->addable < INDEXED || l->addable == 13) {
1405 regalloc(&nod1, l, Z);
1407 if(typechlp[l->type->etype])
1408 gopcode(o, types[TINT], &nod1, &nod);
1410 gopcode(o, l->type, &nod1, &nod);
1413 gopcode(o, l->type, l, &nod);
1419 gmove(nodconst(1L), nn);
1423 gmove(nodconst(0L), nn);
1432 sugen(Node *n, Node *nn, long w)
1435 Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r;
1439 if(n == Z || n->type == T)
1442 prtree(nn, "sugen lhs");
1451 nullwarn(n->left, Z);
1459 if(n->type && typev[n->type->etype]) {
1461 nullwarn(n->left, Z);
1465 if(nn->op == OREGPAIR) {
1469 else if(!vaddr(nn, 0)) {
1471 nn->type = types[TLONG];
1472 reglcgen(&nod1, nn, Z);
1475 gmove(lo64(n), &nod1);
1476 nod1.xoffset += SZ_LONG;
1477 gmove(hi64(n), &nod1);
1481 gins(AMOVL, lo64(n), nn);
1482 nn->xoffset += SZ_LONG;
1483 gins(AMOVL, hi64(n), nn);
1484 nn->xoffset -= SZ_LONG;
1493 sugen(l, nodrat, l->type->width);
1496 warn(n, "non-interruptable temporary");
1499 if(!r || r->op != OCONST) {
1500 diag(n, "DOT and no offset");
1503 nod1.xoffset += (long)r->vconst;
1504 nod1.type = n->type;
1505 sugen(&nod1, nn, w);
1510 * rewrite so lhs has no fn call
1512 if(nn != Z && side(nn)) {
1514 nod1.type = typ(TIND, n->type);
1515 regret(&nod2, &nod1);
1517 regsalloc(&nod0, &nod1);
1532 for(t = n->type->link; t != T; t = t->down) {
1534 if(r->op == OLIST) {
1543 * hand craft *(&nn + o) = l
1558 nod2.type = typ(TIND, t);
1564 nod3.type = nod2.type;
1569 nod4.type = nod2.type;
1570 nod4.vconst = t->offset;
1578 /* prtree(&nod0, "hand craft"); /* */
1585 if(n->addable < INDEXED)
1586 sugen(n->right, n->left, w);
1590 sugen(n->right, nodrat, w);
1591 warn(n, "non-interruptable temporary");
1592 sugen(nodrat, n->left, w);
1593 sugen(nodrat, nn, w);
1598 sugen(n, nodrat, w);
1602 if(nn->op == OREGPAIR) {
1603 regsalloc(&nod1, nn);
1606 if(nn->op != OIND) {
1607 nn = new1(OADDR, nn, Z);
1608 nn->type = types[TIND];
1612 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1614 n->type = types[TVOID];
1615 n->left->type = types[TVOID];
1617 if(h->op == OREGPAIR)
1618 loadpair(nn->left, h);
1624 sugen(n->right->left, nn, w);
1628 sugen(n->right->right, nn, w);
1634 sugen(n->right, nn, w);
1667 if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1669 nn->type = types[TLONG];
1670 regialloc(&nod1, nn, Z);
1672 regsalloc(&nod2, nn);
1675 gins(AMOVL, &nod1, &nod2);
1678 nod2.type = typ(TIND, t);
1695 if(n->left != Z && n->left->complex >= FNX
1696 && n->right != Z && n->right->complex >= FNX) {
1697 regsalloc(&nod1, n->right);
1698 cgen(n->right, &nod1);
1714 if(n->complex > nn->complex){
1716 n->type = types[TLONG];
1717 regalloc(&nod0, n, Z);
1719 reglcgen(&nod1, n, Z);
1727 nn->type = types[TLONG];
1729 reglcgen(&nod2, nn, Z);
1737 nn->type = types[TLONG];
1738 regalloc(&nod0, nn, Z);
1740 reglcgen(&nod2, nn, Z);
1748 n->type = types[TLONG];
1750 reglcgen(&nod1, n, Z);
1757 gins(AMOVL, n, &nod0);
1759 gins(ANOTL, Z, &nod0);
1760 gins(AMOVL, &nod0, nn);
1761 n->xoffset += SZ_LONG;
1762 nn->xoffset += SZ_LONG;
1763 gins(AMOVL, n, &nod0);
1765 gins(ANOTL, Z, &nod0);
1766 gins(AMOVL, &nod0, nn);
1767 n->xoffset -= SZ_LONG;
1768 nn->xoffset -= SZ_LONG;
1778 if(t != types[TIND]){
1779 n->type = types[TIND];
1785 if(t != types[TIND]){
1786 nn->type = types[TIND];
1792 if(nodreg(&nod1, n, D_SI)) {
1793 regsalloc(&nod4, &nod1);
1794 gmove(&nod1, &nod4);
1799 gmove(&nod4, &nod1);
1803 if(nodreg(&nod2, nn, D_DI)) {
1804 regsalloc(&nod4, &nod2);
1805 gmove(&nod2, &nod4);
1810 gmove(&nod4, &nod2);
1814 if(nodreg(&nod3, Z, D_CX)) {
1815 regsalloc(&nod4, &nod3);
1816 gmove(&nod3, &nod4);
1821 gmove(&nod4, &nod3);
1826 if(n->complex > nn->complex){
1841 gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
1845 if(w & (SZ_LONG-1)) {
1846 /* odd length of packed structure */
1847 gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);