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);
1001 * convert from types l->n->nn
1003 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
1004 /* both null, gen l->nn */
1008 if(typev[l->type->etype]) {
1012 regalloc(&nod, l, nn);
1014 regalloc(&nod1, n, &nod);
1022 sugen(l, nodrat, l->type->width);
1025 warn(n, "non-interruptable temporary");
1027 if(!r || r->op != OCONST) {
1028 diag(n, "DOT and no offset");
1031 nod.xoffset += (long)r->vconst;
1050 if(l->type->etype == TIND)
1051 v = l->type->link->width;
1060 reglcgen(&nod, l, Z);
1064 if(typefd[n->type->etype])
1067 gopcode(OADD, n->type, nodconst(v), &nod);
1075 if(l->type->etype == TIND)
1076 v = l->type->link->width;
1084 reglcgen(&nod, l, Z);
1087 if(typefd[n->type->etype])
1089 gopcode(OADD, n->type, nodconst(v), &nod);
1097 gmove(&nod, &fregnode0);
1098 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC))
1099 gins(AFMOVD, &fregnode0, &fregnode0);
1102 fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0);
1104 fgopcode(OADD, &fregnode0, &fregnode1, 1, 0);
1105 if(nn != Z && (o == OPREINC || o == OPREDEC))
1106 gins(AFMOVD, &fregnode0, &fregnode0);
1107 gmove(&fregnode0, &nod);
1113 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
1114 bitload(l, &nod, &nod1, &nod2, Z);
1116 gopcode(OADD, tfield, nodconst(v), &nod);
1117 bitstore(l, &nod, &nod1, &nod2, Z);
1120 bitload(l, &nod, &nod1, &nod2, nn);
1121 gopcode(OADD, tfield, nodconst(v), &nod);
1122 bitstore(l, &nod, &nod1, &nod2, nn);
1130 reglcgen(Node *t, Node *n, Node *nn)
1135 regialloc(t, n, nn);
1138 while(r->op == OADD)
1155 lcgen(Node *n, Node *nn)
1161 prtree(nn, "lcgen lhs");
1164 if(n == Z || n->type == T)
1168 regalloc(&nod, n, Z);
1172 if(n->addable < INDEXED) {
1173 diag(n, "unknown op in lcgen: %O", n->op);
1176 gopcode(OADDR, n->type, n, nn);
1180 cgen(n->left, n->left);
1181 lcgen(n->right, nn);
1191 lcgen(n->right->left, nn);
1195 lcgen(n->right->right, nn);
1202 bcgen(Node *n, int true)
1208 boolgen(n, true, Z);
1212 boolgen(Node *n, int true, Node *nn)
1216 Node *l, *r, nod, nod1;
1220 prtree(nn, "boolgen lhs");
1221 prtree(n, "boolgen");
1229 if(typev[n->type->etype]) {
1236 if(typefd[n->type->etype]) {
1237 if(n->addable < INDEXED) {
1238 cgen(n, &fregnode0);
1240 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1243 fgopcode(o, n, &fregnode0, 0, 1);
1247 /* bad, 13 is address of external that becomes constant */
1248 if(n->addable >= INDEXED && n->addable != 13) {
1249 gopcode(o, n->type, n, nodconst(0));
1252 regalloc(&nod, n, nn);
1254 gopcode(o, n->type, &nod, nodconst(0));
1272 boolgen(r, true, nn);
1276 boolgen(l, !true, nn);
1282 bcgen(r->left, true);
1287 bcgen(r->right, !true);
1334 if(typev[l->type->etype]) {
1336 n->op = comrel[relindex(o)];
1341 o = comrel[relindex(o)];
1342 if(l->complex >= FNX && r->complex >= FNX) {
1345 regsalloc(&nod1, r);
1350 boolgen(&nod, true, nn);
1353 if(typefd[l->type->etype]) {
1354 if(l->complex >= r->complex) {
1355 cgen(l, &fregnode0);
1356 if(r->addable < INDEXED) {
1357 cgen(r, &fregnode0);
1358 o = invrel[relindex(o)];
1359 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1361 fgopcode(o, r, &fregnode0, 0, 1);
1363 o = invrel[relindex(o)];
1364 cgen(r, &fregnode0);
1365 if(l->addable < INDEXED) {
1366 cgen(l, &fregnode0);
1367 o = invrel[relindex(o)];
1368 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1370 fgopcode(o, l, &fregnode0, 0, 1);
1374 if(l->op == OCONST) {
1375 o = invrel[relindex(o)];
1376 /* bad, 13 is address of external that becomes constant */
1377 if(r->addable < INDEXED || r->addable == 13) {
1378 regalloc(&nod, r, nn);
1380 gopcode(o, l->type, &nod, l);
1383 gopcode(o, l->type, r, l);
1386 if(l->complex >= r->complex) {
1387 regalloc(&nod, l, nn);
1389 if(r->addable < INDEXED) {
1390 regalloc(&nod1, r, Z);
1392 gopcode(o, l->type, &nod, &nod1);
1395 gopcode(o, l->type, &nod, r);
1399 regalloc(&nod, r, nn);
1401 if(l->addable < INDEXED || l->addable == 13) {
1402 regalloc(&nod1, l, Z);
1404 if(typechlp[l->type->etype])
1405 gopcode(o, types[TINT], &nod1, &nod);
1407 gopcode(o, l->type, &nod1, &nod);
1410 gopcode(o, l->type, l, &nod);
1416 gmove(nodconst(1L), nn);
1420 gmove(nodconst(0L), nn);
1429 sugen(Node *n, Node *nn, long w)
1432 Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r;
1436 if(n == Z || n->type == T)
1439 prtree(nn, "sugen lhs");
1448 nullwarn(n->left, Z);
1456 if(n->type && typev[n->type->etype]) {
1458 nullwarn(n->left, Z);
1462 if(nn->op == OREGPAIR) {
1466 else if(!vaddr(nn, 0)) {
1468 nn->type = types[TLONG];
1469 reglcgen(&nod1, nn, Z);
1472 gmove(lo64(n), &nod1);
1473 nod1.xoffset += SZ_LONG;
1474 gmove(hi64(n), &nod1);
1478 gins(AMOVL, lo64(n), nn);
1479 nn->xoffset += SZ_LONG;
1480 gins(AMOVL, hi64(n), nn);
1481 nn->xoffset -= SZ_LONG;
1490 sugen(l, nodrat, l->type->width);
1493 warn(n, "non-interruptable temporary");
1496 if(!r || r->op != OCONST) {
1497 diag(n, "DOT and no offset");
1500 nod1.xoffset += (long)r->vconst;
1501 nod1.type = n->type;
1502 sugen(&nod1, nn, w);
1507 * rewrite so lhs has no fn call
1509 if(nn != Z && side(nn)) {
1511 nod1.type = typ(TIND, n->type);
1512 regret(&nod2, &nod1);
1514 regsalloc(&nod0, &nod1);
1529 for(t = n->type->link; t != T; t = t->down) {
1531 if(r->op == OLIST) {
1540 * hand craft *(&nn + o) = l
1555 nod2.type = typ(TIND, t);
1561 nod3.type = nod2.type;
1566 nod4.type = nod2.type;
1567 nod4.vconst = t->offset;
1575 /* prtree(&nod0, "hand craft"); /* */
1582 if(n->addable < INDEXED)
1583 sugen(n->right, n->left, w);
1587 sugen(n->right, nodrat, w);
1588 warn(n, "non-interruptable temporary");
1589 sugen(nodrat, n->left, w);
1590 sugen(nodrat, nn, w);
1595 sugen(n, nodrat, w);
1599 if(nn->op == OREGPAIR) {
1600 regsalloc(&nod1, nn);
1603 if(nn->op != OIND) {
1604 nn = new1(OADDR, nn, Z);
1605 nn->type = types[TIND];
1609 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1611 n->type = types[TVOID];
1612 n->left->type = types[TVOID];
1614 if(h->op == OREGPAIR)
1615 loadpair(nn->left, h);
1621 sugen(n->right->left, nn, w);
1625 sugen(n->right->right, nn, w);
1631 sugen(n->right, nn, w);
1664 if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1666 nn->type = types[TLONG];
1667 regialloc(&nod1, nn, Z);
1669 regsalloc(&nod2, &nod1);
1672 gins(AMOVL, &nod1, &nod2);
1675 nod2.type = typ(TIND, t);
1692 if(n->left != Z && n->left->complex >= FNX
1693 && n->right != Z && n->right->complex >= FNX) {
1694 regsalloc(&nod1, n->right);
1695 cgen(n->right, &nod1);
1711 if(n->complex > nn->complex){
1713 n->type = types[TLONG];
1714 regalloc(&nod0, n, Z);
1716 reglcgen(&nod1, n, Z);
1724 nn->type = types[TLONG];
1726 reglcgen(&nod2, nn, Z);
1734 nn->type = types[TLONG];
1735 regalloc(&nod0, nn, Z);
1737 reglcgen(&nod2, nn, Z);
1745 n->type = types[TLONG];
1747 reglcgen(&nod1, n, Z);
1754 gins(AMOVL, n, &nod0);
1756 gins(ANOTL, Z, &nod0);
1757 gins(AMOVL, &nod0, nn);
1758 n->xoffset += SZ_LONG;
1759 nn->xoffset += SZ_LONG;
1760 gins(AMOVL, n, &nod0);
1762 gins(ANOTL, Z, &nod0);
1763 gins(AMOVL, &nod0, nn);
1764 n->xoffset -= SZ_LONG;
1765 nn->xoffset -= SZ_LONG;
1775 if(t != types[TIND]){
1776 n->type = types[TIND];
1782 if(t != types[TIND]){
1783 nn->type = types[TIND];
1789 if(nodreg(&nod1, n, D_SI)) {
1790 regsalloc(&nod4, &nod1);
1791 gmove(&nod1, &nod4);
1796 gmove(&nod4, &nod1);
1800 if(nodreg(&nod2, nn, D_DI)) {
1801 regsalloc(&nod4, &nod2);
1802 gmove(&nod2, &nod4);
1807 gmove(&nod4, &nod2);
1811 if(nodreg(&nod3, Z, D_CX)) {
1812 regsalloc(&nod4, &nod3);
1813 gmove(&nod3, &nod4);
1818 gmove(&nod4, &nod3);
1823 if(n->complex > nn->complex){
1838 gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
1842 if(w & (SZ_LONG-1)) {
1843 /* odd length of packed structure */
1844 gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);