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 if(n->addable >= INDEXED) {
46 if(r != Z && r->complex >= FNX)
49 if(cond(o) && typesuv[l->type->etype])
74 hardleft = l->addable < INDEXED || l->complex >= FNX;
77 diag(n, "unknown op in cgen: %O", o);
86 regalloc(&nod, l, nn);
88 gopcode(o, n->type, Z, &nod);
94 if(typefd[n->type->etype]) {
97 gins(AFMOVD, &fregnode0, &fregnode0);
98 if(l->addable < INDEXED) {
100 gmove(&fregnode0, &nod);
103 gmove(&fregnode0, l);
105 gmove(&fregnode0, nn);
111 if(nn != Z || r->addable < INDEXED) {
112 if(r->complex >= FNX && nn == Z)
115 regalloc(&nod, r, nn);
125 if(l->complex >= r->complex) {
126 if(l->op == OINDEX && r->op == OCONST) {
130 reglcgen(&nod1, l, Z);
131 if(r->addable >= INDEXED) {
138 regalloc(&nod, r, nn);
141 regalloc(&nod, r, nn);
143 reglcgen(&nod1, l, Z);
152 regalloc(&nod, r, nn);
153 if(l->complex >= r->complex) {
154 reglcgen(&nod1, n, Z);
158 reglcgen(&nod1, n, Z);
160 regalloc(&nod2, n, Z);
162 bitstore(l, &nod, &nod1, &nod2, nn);
170 bitload(n, &nod, Z, Z, nn);
182 if(r->op == OCONST) {
187 regalloc(&nod, l, nn);
189 if(o == OASHL && r->vconst == 1)
190 gopcode(OADD, n->type, &nod, &nod);
192 gopcode(o, n->type, r, &nod);
201 if(nodreg(&nod, nn, D_CX)) {
204 cgen(n, &nod); /* probably a bug */
210 if(nn->op == OREGISTER && nn->reg == D_CX)
211 regalloc(&nod1, l, Z);
213 regalloc(&nod1, l, nn);
214 if(r->complex >= l->complex) {
221 gopcode(o, n->type, &nod, &nod1);
236 if(typefd[n->type->etype])
238 if(r->op == OCONST) {
239 if(r->vconst == 0 && o != OAND) {
244 if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
245 && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
246 c = l->right->vconst;
247 if(c > 0 && c <= 3) {
248 if(l->left->complex >= r->complex) {
249 regalloc(&nod, l->left, nn);
251 if(r->addable < INDEXED) {
252 regalloc(&nod1, r, Z);
254 genmuladd(&nod, &nod, 1 << c, &nod1);
258 genmuladd(&nod, &nod, 1 << c, r);
261 regalloc(&nod, r, nn);
263 regalloc(&nod1, l->left, Z);
264 cgen(l->left, &nod1);
265 genmuladd(&nod, &nod1, 1 << c, &nod);
273 if(r->addable >= INDEXED) {
274 regalloc(&nod, l, nn);
276 gopcode(o, n->type, r, &nod);
281 if(l->complex >= r->complex) {
282 regalloc(&nod, l, nn);
284 regalloc(&nod1, r, Z);
286 gopcode(o, n->type, &nod1, &nod);
288 regalloc(&nod1, r, nn);
290 regalloc(&nod, l, Z);
292 gopcode(o, n->type, &nod1, &nod);
309 if(typefd[n->type->etype])
311 if(r->op == OCONST) {
325 regalloc(&nod, l, nn);
330 mulgen(n->type, r, &nod);
333 sdiv2(r->vconst, v, l, &nod);
336 smod2(r->vconst, v, l, &nod);
344 if((c & 0x80000000) == 0)
346 regalloc(&nod1, l, Z);
348 regalloc(&nod, l, nn);
350 gins(ACMPL, &nod1, nodconst(c));
351 gins(ASBBL, nodconst(-1), &nod);
360 if(l->addable >= INDEXED) {
366 else if(r->addable >= INDEXED) {
368 /* should favour AX */
369 regalloc(&nod, l, nn);
371 gopcode(OMUL, n->type, r, &nod);
374 /* should favour AX */
375 regalloc(&nod, l, nn);
377 regalloc(&nod1, r, Z);
379 gopcode(OMUL, n->type, &nod1, &nod);
389 * get nod1 to be D_DX
391 if(nodreg(&nod, nn, D_AX)) {
413 if(nodreg(&nod1, nn, D_DX)) {
437 if(r->op == OCONST) {
441 if(l->addable < INDEXED) {
442 regalloc(&nod2, l, Z);
446 sdivgen(l, r, &nod, &nod1);
453 if(l->addable < INDEXED) {
454 regalloc(&nod2, l, Z);
458 udivgen(l, r, &nod, &nod1);
466 if(l->complex >= r->complex) {
469 if(o == ODIV || o == OMOD)
471 if(o == OLDIV || o == OLMOD)
473 if(r->addable < INDEXED || r->op == OCONST) {
476 gopcode(o, n->type, &nod3, Z);
478 gopcode(o, n->type, r, Z);
484 if(o == ODIV || o == OMOD)
486 if(o == OLDIV || o == OLMOD)
488 gopcode(o, n->type, &nod3, Z);
490 if(o == OMOD || o == OLMOD)
506 if(typefd[n->type->etype])
512 if(nodreg(&nod, nn, D_CX)) {
523 if(r->complex >= l->complex) {
526 reglcgen(&nod1, l, Z);
531 reglcgen(&nod1, l, Z);
537 gopcode(o, l->type, &nod, &nod1);
553 if(typefd[n->type->etype]||typefd[r->type->etype])
555 if(l->complex >= r->complex) {
557 reglcgen(&nod, l, Z);
560 if(r->op != OCONST) {
561 regalloc(&nod1, r, nn);
563 gopcode(o, l->type, &nod1, &nod);
566 gopcode(o, l->type, r, &nod);
568 regalloc(&nod1, r, nn);
571 reglcgen(&nod, l, Z);
574 gopcode(o, l->type, &nod1, &nod);
591 if(typefd[n->type->etype]||typefd[r->type->etype])
593 if(r->op == OCONST) {
608 reglcgen(&nod2, l, Z);
611 regalloc(&nod, l, nn);
616 mulgen(n->type, r, &nod);
619 sdiv2(r->vconst, v, l, &nod);
622 smod2(r->vconst, v, l, &nod);
635 if((c & 0x80000000) == 0)
638 reglcgen(&nod2, l, Z);
641 regalloc(&nod1, l, nn);
643 regalloc(&nod, l, nn);
645 gins(ACMPL, &nod1, nodconst(c));
646 gins(ASBBL, nodconst(-1), &nod);
653 /* should favour AX */
654 regalloc(&nod, l, nn);
655 if(r->complex >= FNX) {
656 regalloc(&nod1, r, Z);
661 reglcgen(&nod2, l, Z);
665 if(r->addable < INDEXED) {
666 if(r->complex < FNX) {
667 regalloc(&nod1, r, Z);
670 gopcode(OASMUL, n->type, &nod1, &nod);
674 gopcode(OASMUL, n->type, r, &nod);
688 * get nod1 to be D_DX
690 if(nodreg(&nod, nn, D_AX)) {
712 if(nodreg(&nod1, nn, D_DX)) {
737 if(l->complex >= r->complex) {
739 reglcgen(&nod2, l, Z);
743 if(r->op == OCONST) {
746 sdivgen(&nod2, r, &nod, &nod1);
749 udivgen(&nod2, r, &nod, &nod1);
757 if(o == OASDIV || o == OASMOD)
759 if(o == OASLDIV || o == OASLMOD)
761 if(r->addable < INDEXED || r->op == OCONST ||
762 !typeil[r->type->etype]) {
763 regalloc(&nod3, r, Z);
765 gopcode(o, l->type, &nod3, Z);
768 gopcode(o, n->type, r, Z);
770 regalloc(&nod3, r, Z);
773 reglcgen(&nod2, l, Z);
777 if(o == OASDIV || o == OASMOD)
779 if(o == OASLDIV || o == OASLMOD)
781 gopcode(o, l->type, &nod3, Z);
784 if(o == OASMOD || o == OASLMOD) {
801 if(l->complex >= r->complex) {
803 if(r->addable < INDEXED) {
805 fgopcode(o, &fregnode0, &fregnode1, 1, 0);
807 fgopcode(o, r, &fregnode0, 0, 0);
810 if(l->addable < INDEXED) {
812 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
814 fgopcode(o, l, &fregnode0, 0, 1);
816 gmove(&fregnode0, nn);
820 if(l->complex >= r->complex) {
822 reglcgen(&nod, l, Z);
829 reglcgen(&nod, l, Z);
833 if(!typefd[l->type->etype]) {
834 gmove(&nod, &fregnode0);
835 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
837 fgopcode(o, &nod, &fregnode0, 0, 1);
839 gins(AFMOVD, &fregnode0, &fregnode0);
840 gmove(&fregnode0, &nod);
842 gmove(&fregnode0, nn);
848 regalloc(&nod4, n, nn);
849 if(l->complex >= r->complex) {
850 bitload(l, &nod, &nod1, &nod2, &nod4);
851 regalloc(&nod3, r, Z);
854 regalloc(&nod3, r, Z);
856 bitload(l, &nod, &nod1, &nod2, &nod4);
860 if(typefd[nod3.type->etype])
861 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
865 /* incredible grot ... */
878 bitstore(l, &nod, &nod1, &nod2, nn);
890 if(l->complex >= FNX) {
892 diag(n, "bad function call");
894 regret(&nod, l->left);
896 regsalloc(&nod1, l->left);
909 gargs(r, &nod, &nod1);
910 if(l->addable < INDEXED) {
911 reglcgen(&nod, l, nn);
913 gopcode(OFUNC, n->type, Z, &nod);
916 gopcode(OFUNC, n->type, Z, l);
917 if(REGARG>=0 && reg[REGARG])
924 if(typefd[n->type->etype])
925 gins(AFMOVDP, &fregnode0, &fregnode0);
933 regialloc(&nod, n, nn);
993 * convert from types l->n->nn
995 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
996 /* both null, gen l->nn */
1000 if(typev[l->type->etype]) {
1004 regalloc(&nod, l, nn);
1006 regalloc(&nod1, n, &nod);
1014 sugen(l, nodrat, l->type->width);
1017 warn(n, "non-interruptable temporary");
1019 if(!r || r->op != OCONST) {
1020 diag(n, "DOT and no offset");
1023 nod.xoffset += (long)r->vconst;
1042 if(l->type->etype == TIND)
1043 v = l->type->link->width;
1052 reglcgen(&nod, l, Z);
1056 if(typefd[n->type->etype])
1059 gopcode(OADD, n->type, nodconst(v), &nod);
1067 if(l->type->etype == TIND)
1068 v = l->type->link->width;
1076 reglcgen(&nod, l, Z);
1079 if(typefd[n->type->etype])
1081 gopcode(OADD, n->type, nodconst(v), &nod);
1089 gmove(&nod, &fregnode0);
1090 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC))
1091 gins(AFMOVD, &fregnode0, &fregnode0);
1094 fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0);
1096 fgopcode(OADD, &fregnode0, &fregnode1, 1, 0);
1097 if(nn != Z && (o == OPREINC || o == OPREDEC))
1098 gins(AFMOVD, &fregnode0, &fregnode0);
1099 gmove(&fregnode0, &nod);
1105 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
1106 bitload(l, &nod, &nod1, &nod2, Z);
1108 gopcode(OADD, tfield, nodconst(v), &nod);
1109 bitstore(l, &nod, &nod1, &nod2, Z);
1112 bitload(l, &nod, &nod1, &nod2, nn);
1113 gopcode(OADD, tfield, nodconst(v), &nod);
1114 bitstore(l, &nod, &nod1, &nod2, nn);
1122 reglcgen(Node *t, Node *n, Node *nn)
1127 regialloc(t, n, nn);
1130 while(r->op == OADD)
1147 lcgen(Node *n, Node *nn)
1153 prtree(nn, "lcgen lhs");
1156 if(n == Z || n->type == T)
1160 regalloc(&nod, n, Z);
1164 if(n->addable < INDEXED) {
1165 diag(n, "unknown op in lcgen: %O", n->op);
1168 gopcode(OADDR, n->type, n, nn);
1172 cgen(n->left, n->left);
1173 lcgen(n->right, nn);
1183 lcgen(n->right->left, nn);
1187 lcgen(n->right->right, nn);
1194 bcgen(Node *n, int true)
1200 boolgen(n, true, Z);
1204 boolgen(Node *n, int true, Node *nn)
1208 Node *l, *r, nod, nod1;
1212 prtree(nn, "boolgen lhs");
1213 prtree(n, "boolgen");
1221 if(typev[n->type->etype]) {
1228 if(typefd[n->type->etype]) {
1229 if(n->addable < INDEXED) {
1230 cgen(n, &fregnode0);
1232 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1235 fgopcode(o, n, &fregnode0, 0, 1);
1239 /* bad, 13 is address of external that becomes constant */
1240 if(n->addable >= INDEXED && n->addable != 13) {
1241 gopcode(o, n->type, n, nodconst(0));
1244 regalloc(&nod, n, nn);
1246 gopcode(o, n->type, &nod, nodconst(0));
1264 boolgen(r, true, nn);
1268 boolgen(l, !true, nn);
1274 bcgen(r->left, true);
1279 bcgen(r->right, !true);
1326 if(typev[l->type->etype]) {
1328 n->op = comrel[relindex(o)];
1333 o = comrel[relindex(o)];
1334 if(l->complex >= FNX && r->complex >= FNX) {
1337 regsalloc(&nod1, r);
1342 boolgen(&nod, true, nn);
1345 if(typefd[l->type->etype]) {
1346 if(l->complex >= r->complex) {
1347 cgen(l, &fregnode0);
1348 if(r->addable < INDEXED) {
1349 cgen(r, &fregnode0);
1350 o = invrel[relindex(o)];
1351 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1353 fgopcode(o, r, &fregnode0, 0, 1);
1355 o = invrel[relindex(o)];
1356 cgen(r, &fregnode0);
1357 if(l->addable < INDEXED) {
1358 cgen(l, &fregnode0);
1359 o = invrel[relindex(o)];
1360 fgopcode(o, &fregnode0, &fregnode1, 1, 1);
1362 fgopcode(o, l, &fregnode0, 0, 1);
1366 if(l->op == OCONST) {
1367 o = invrel[relindex(o)];
1368 /* bad, 13 is address of external that becomes constant */
1369 if(r->addable < INDEXED || r->addable == 13) {
1370 regalloc(&nod, r, nn);
1372 gopcode(o, l->type, &nod, l);
1375 gopcode(o, l->type, r, l);
1378 if(l->complex >= r->complex) {
1379 regalloc(&nod, l, nn);
1381 if(r->addable < INDEXED) {
1382 regalloc(&nod1, r, Z);
1384 gopcode(o, l->type, &nod, &nod1);
1387 gopcode(o, l->type, &nod, r);
1391 regalloc(&nod, r, nn);
1393 if(l->addable < INDEXED || l->addable == 13) {
1394 regalloc(&nod1, l, Z);
1396 if(typechlp[l->type->etype])
1397 gopcode(o, types[TINT], &nod1, &nod);
1399 gopcode(o, l->type, &nod1, &nod);
1402 gopcode(o, l->type, l, &nod);
1408 gmove(nodconst(1L), nn);
1412 gmove(nodconst(0L), nn);
1421 sugen(Node *n, Node *nn, long w)
1424 Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r;
1428 if(n == Z || n->type == T)
1431 prtree(nn, "sugen lhs");
1440 nullwarn(n->left, Z);
1448 if(n->type && typev[n->type->etype]) {
1450 nullwarn(n->left, Z);
1454 if(nn->op == OREGPAIR) {
1458 else if(!vaddr(nn, 0)) {
1460 nn->type = types[TLONG];
1461 reglcgen(&nod1, nn, Z);
1464 gmove(lo64(n), &nod1);
1465 nod1.xoffset += SZ_LONG;
1466 gmove(hi64(n), &nod1);
1470 gins(AMOVL, lo64(n), nn);
1471 nn->xoffset += SZ_LONG;
1472 gins(AMOVL, hi64(n), nn);
1473 nn->xoffset -= SZ_LONG;
1482 sugen(l, nodrat, l->type->width);
1485 warn(n, "non-interruptable temporary");
1488 if(!r || r->op != OCONST) {
1489 diag(n, "DOT and no offset");
1492 nod1.xoffset += (long)r->vconst;
1493 nod1.type = n->type;
1494 sugen(&nod1, nn, w);
1499 * rewrite so lhs has no fn call
1501 if(nn != Z && side(nn)) {
1503 nod1.type = typ(TIND, n->type);
1504 regret(&nod2, &nod1);
1506 regsalloc(&nod0, &nod1);
1521 for(t = n->type->link; t != T; t = t->down) {
1523 if(r->op == OLIST) {
1532 * hand craft *(&nn + o) = l
1547 nod2.type = typ(TIND, t);
1553 nod3.type = nod2.type;
1558 nod4.type = nod2.type;
1559 nod4.vconst = t->offset;
1567 /* prtree(&nod0, "hand craft"); /* */
1574 if(n->addable < INDEXED)
1575 sugen(n->right, n->left, w);
1579 sugen(n->right, nodrat, w);
1580 warn(n, "non-interruptable temporary");
1581 sugen(nodrat, n->left, w);
1582 sugen(nodrat, nn, w);
1587 sugen(n, nodrat, w);
1591 if(nn->op == OREGPAIR) {
1592 regsalloc(&nod1, nn);
1595 if(nn->op != OIND) {
1596 nn = new1(OADDR, nn, Z);
1597 nn->type = types[TIND];
1601 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1602 n->type = types[TVOID];
1603 n->left->type = types[TVOID];
1605 if(h->op == OREGPAIR)
1606 loadpair(nn->left, h);
1612 sugen(n->right->left, nn, w);
1616 sugen(n->right->right, nn, w);
1622 sugen(n->right, nn, w);
1655 if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1657 nn->type = types[TLONG];
1658 regialloc(&nod1, nn, Z);
1660 regsalloc(&nod2, nn);
1663 gins(AMOVL, &nod1, &nod2);
1666 nod2.type = typ(TIND, t);
1683 if(n->left != Z && n->left->complex >= FNX
1684 && n->right != Z && n->right->complex >= FNX) {
1685 // warn(n, "toughie");
1686 regsalloc(&nod1, n->right);
1687 cgen(n->right, &nod1);
1704 /* botch, need to save in .safe */
1706 if(n->complex > nn->complex) {
1708 n->type = types[TLONG];
1710 regalloc(&nod0, n, Z);
1712 reglcgen(&nod1, n, Z);
1720 nodreg(&nod1, n, D_SI);
1722 gins(APUSHL, &nod1, Z);
1731 nn->type = types[TLONG];
1734 reglcgen(&nod2, nn, Z);
1742 nodreg(&nod2, nn, D_DI);
1744 gins(APUSHL, &nod2, Z);
1753 nn->type = types[TLONG];
1755 regalloc(&nod0, nn, Z);
1757 reglcgen(&nod2, nn, Z);
1765 nodreg(&nod2, nn, D_DI);
1767 gins(APUSHL, &nod2, Z);
1776 n->type = types[TLONG];
1779 reglcgen(&nod1, n, Z);
1787 nodreg(&nod1, n, D_SI);
1789 gins(APUSHL, &nod1, Z);
1798 gins(AMOVL, n, &nod0);
1800 gins(ANOTL, Z, &nod0);
1801 gins(AMOVL, &nod0, nn);
1802 n->xoffset += SZ_LONG;
1803 nn->xoffset += SZ_LONG;
1804 gins(AMOVL, n, &nod0);
1806 gins(ANOTL, Z, &nod0);
1807 gins(AMOVL, &nod0, nn);
1808 n->xoffset -= SZ_LONG;
1809 nn->xoffset -= SZ_LONG;
1817 nodreg(&nod3, n, D_CX);
1819 gins(APUSHL, &nod3, Z);
1823 gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
1828 gins(APOPL, Z, &nod3);
1832 gins(APOPL, Z, &nod2);
1836 gins(APOPL, Z, &nod1);